使用STC8H时,发现在ADC中断中只能使用一个通道,即使切换了通道,那么数据要不为0,要不就是原先通道的电压。查阅手册,内容并不多,没有发现专门提到的问题。只能去试试,最后发现在ADC中断中,切换通道时,必须先关闭ADC,否则就会失败。以下代码:
void IOInit()
{
P0M0 = 0x00;
P0M1 = 0x07; //P0.0、P0.1、P0.2为ADC
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P1PU |= 0x03; //使能P1.0、P1.1的内部4.1k上拉电阻
// P1NCS |= 0x03; //禁止施密特触发
// P1SR &= ~0x03; //电平转换速度快
// P1DR &= ~0x03; //增强电流
// P1IE |= 0x01; //数字输入
}
volatile u16 AdcChannel=0x48; //P0.0口AD转换
void AdcInit(void)
{
P_SW2 |= 0x80; //使能访问扩展RAM区特殊功能寄存器XFR
ADCTIM = 0xbf; //设置ADC内部时序,32个ADC工作时钟
ADCEXCFG = 0x07; //16次AD平均值,进入中断
P_SW2 &= 0x7f; //禁止访问
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16,ADC数据右对齐
ADC_CONTR = 0x80; //使能ADC模块
EADC = 1; //使能ADC中断
EA = 1;
ADC_CONTR |= AdcChannel; //启动P0.0口AD转换
}
// 交叉采集P00和P02的ADC数据,必须先关闭ADC!
u16 AdcValue=0,Adc8=0,Adc10=0;
u16 Ai=0,Aj=0,An=20; //An<300。如果An是u32,那么计算速度会很慢。
//只做了P0.0的ADC
void ADC_Isr() interrupt 5 //
{
ADC_CONTR=0; //选择不同的通道,需要先关闭ADC,不然转化会出错!!!
AdcValue = (ADC_RES<<8)+ADC_RESL; //读取ADC结果
if(AdcChannel==0x48){
Adc8=Adc8+AdcValue;
AdcChannel=0x4a;
}
else{
Adc10=Adc10+AdcValue;
AdcChannel=0x48;
}
Ai++;
if(Ai>An){
Ai=0;
Adc8=Adc8/An*2;
Adc10=Adc10/An*2;
// ShowU16(Adc8);
// ShowU16(Adc10);
// SendU8('\r');
// SendU8('\n');
if(Adc8>50){ //注意:该阈值可能随代码的增多而改变。
Stop1_2=5;//限制步进电机转动
STBY1=0;//步进电机1驱动失能;
STBY2=0;//步进电机2驱动失能;
}
// if(Adc10>270){ //电推杆检测效果不好,不建议使用
// Stop3_4=5;//限制推杆电机运动
// STBY3=0;//推杆电机驱动失能;
// }
Adc8=0;
Adc10=0;
}
ADC_CONTR=0x80;
ADC_CONTR |= AdcChannel; //继续AD转换
}