各位大佬好,小弟在使用STC12C5A60S2的中断时遇到一点问题,我的想法是,在一个中断中用A/D轮流读取P1.0,P1.1,P1.2的值。但是我参考的例程有些问题,就是P1.1和P1.2的值都是P1.0的,应该是只读到了P1.0的值,或者没有清空P1.0。以下是我的代码,希望大佬们能帮忙看一下,谢谢!
#include "reg51.h"
#include "stdio.h"
#include "gsm.h"
#include "intrins.h"
/*Declare SFR associated with the ADC */
//STC12C5A60S2 特殊功能寄存器 关于AD部分的寄存器定义
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位数据寄存器(存AD转换的结果,共10位)
sfr ADC_LOW2 = 0xBE; //ADC低2位数据寄存器(存AD转换的结果,共10位)
sfr P1ASF = 0x9D; //P1第二功能选择寄存器
/*Define ADC operation const for ADC_CONTR*/
//ADC_CONTR寄存器的位变量定义
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x10 //ADC complete flag
#define ADC_START 0x08 //ADC start control bit
#define ADC_SPEEDLL 0x00 //420 clocks
#define ADC_SPEEDL 0x20 //280 clocks
#define ADC_SPEEDH 0x40 //140 clocks
#define ADC_SPEEDHH 0x60 //70 clocks
void Delay(unsigned int n); //延时函数申明
void InitADC(); //AD初始化函数申明
unsigned int ad_out0; //10位AD数据缓存
unsigned int ad_out1; //10位AD数据缓存
unsigned int ad_out2; //10位AD数据缓存
void main()
{
float ad_out_tur;
float ad_out_temp;
float ad_out_ph;
unsigned int delay;
Http_Init();
InitADC(); //AD初始化
IE = 0xa0; //允许AD中断
//Start A/D conversion
while (1)
{
EA = 0; //约间隔1秒打开AD中断,读取AD值
ad_out_tur = (ad_out0 * 5.00) / 1024; //浑浊度输出
ad_out_temp = (ad_out1 * 1.00) / 1024; //温度输出
ad_out_ph = (-5.65 * (ad_out2 * 5.00 / 1024) + 23.97); //PH输出
Http_Init();
Http_Send(ad_out_tur,ad_out_temp,ad_out_ph); //发送浑浊度、温度、PH
if(delay++ > 6000) //约1秒读取一次AD值
{
delay = 0;
EA = 1;
}
}
}
/*----------------------------
ADC interrupt service routine
----------------------------*/
void adc_isr() interrupt 5 using 1
{
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 000;
ad_out0 = (ADC_RES << 2) + ADC_LOW2; //高8位+低2位
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 001;
ad_out1 = (ADC_RES << 2) + ADC_LOW2; //高8位+低2位
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 010;
ad_out2 = (ADC_RES << 2) + ADC_LOW2; //高8位+低2位
}
/*----------------------------
Initial ADC sfr
----------------------------*/
void InitADC()
{
P1ASF = 0xff; //设置P1为A/D
ADC_RES = 0; //Clear previous result
ADC_LOW2 = 0;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 000;
Delay(2); //ADC power-on delay and Start A/D conversion
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 001;
Delay(2); //ADC power-on delay and Start A/D conversion
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 010;
Delay(2); //ADC power-on delay and Start A/D conversion
}
/*----------------------------
Software delay function
----------------------------*/
void Delay(unsigned int n)
{
unsigned int x;
while (n--)
{
x = 5000;
while (x--);
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
每次中断只转换一个通道,分三次转换,如此反复。
/*----------------------------
Initial ADC sfr
----------------------------*/
void InitADC()
{
P1ASF = 0x07; //设置P1.0~1.2口为AD口
ADC_RES = 0; //清除结果寄存器高8位
ADC_LOW2= 0; //清除结果寄存器低2位
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | 0x00;//启动转换
Delay(2); //ADC上电并延时
}
/*----------------------------
ADC interrupt service routine
----------------------------*/
void adc_isr() interrupt 5 using 1
{
static unsigned char CH=0;
switch(CH)
{
case 0:
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START |CH;
ad_out0 = (ADC_RES << 2) + ADC_LOW2; //高8位+低2位
CH++;
break;
case 1:
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START |CH;
ad_out1 = (ADC_RES << 2) + ADC_LOW2;//高8位+低2位
CH++;
break;
case 2:
ADC_CONTR &= !ADC_FLAG; //Clear ADC interrupt flag
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START |CH;
ad_out2 = (ADC_RES << 2) + ADC_LOW2;//高8位+低2位
CH=0;
break;
}
}
一周热门 更多>