双通道电压表案例程序设计说明
1 工程文件下载:
2 程序设计流程图

3 相关寄存器设置
1) P0(8位)和P2.3需要设置成推挽输出,以驱动电路正常发光。按键作为输入,不需推挽,涉及寄存器及配置值如下:
P0M1=0x00;
P0M0=0xff;
P2M1=0x00;
P2M0=0x08;
2) 采用定时器1,在定时器中断中进行AD的初始化,涉及寄存器(含可位寻址)及配置如下:
TMOD=0x10;
IE=0xa8;
TH1=(65535-40000)/256;
TL1=(65535-40000)%256;
TR1=1; //启动定时器
3) 对于P1_0通过AD采集,涉及寄存器及配置如下:
P1ASF=0xff;
ADC_RES=0;
ADC_RESL=0; //AD转换结果寄存器清0
ADC_CONTR=0X88; //10001000,后三位决定P1^3作为A/D输入
CLK_DIV=0X20;
4) 对于P1_1通过AD采集,涉及寄存器及配置如下:
P1ASF=0xff;
ADC_RES=0;
ADC_RESL=0; //AD转换结果寄存器清0
ADC_CONTR=0X89; //10001001,后三位决定P1^1作为A/D输入
CLK_DIV=0X20;
4 程序设计框架
4.1 void main()
调用U0_U1()。
4.2 void U0_U1()
(1)设置P0为推挽模式,设置P2^3为推挽模式,其它为准双向口模式
(2)选通数码管
(3)开定时器中断和AD中断
(4)设定时器1初值并开启定时器1中断
(5)无条件循环调用SEG_Display()。
4.3 void SEG_Display()
(1) 电压范围0~5V;
(2) 保留两位小数,因此有个位、十分位、百分位;
4.4 void Timer1_Routine() interrupt 3
定时器1中断处理程序:
(1) 判断当前flag标志,如果是1,则调用InitADC_U1()初始化P1_1相应寄存器;否则调用InitADC_U1()初始化P1_1相应寄存器。对flag标志取反。
(2) 开总中断,开AD中断,使能定时器1中断;启动定时器1工作。
4.5 void weixuan(char i)
将数码管i信息对应到位选引脚SEL0、SEL1、SEL2上。
4.6 void Delay(int n)
延时
4.7 void InitADC_U1()
初始化P1_1引脚AD转换结果寄存器及控制寄存器
4.8 void InitADC_U0()
初始化P1_0引脚AD转换结果寄存器及控制寄存器
4.9 void adc_isr() interrupt 5 using 1
AD中断处理程序:
(1) 每中断AD一次,计数器time加1;
(2) 屏蔽所有中断;
(3) 如果中断次数达到2000次,则如果flag为1,则求温度AD平均值,并从tempdata数组中获取相应AD值对应的摄氏温度值,AD中断重新计数,调用date_processtemp()方法完成数码管左边三个温度值显示。如果flag为-1,则求光AD平均值,AD中断重新计数,调用date_processlight()方法用数码管右侧三个显示光信息。
(4) 如果flag为1,则将存储了温度AD值的ADC_RES和ADC_RESL寄存器数值经过处理后累加,温度中断次数加1;如果flag为-1,则将存储了光AD值的ADC_RES和ADC_RESL寄存器数值累加,光中断次数加1。
(5) 标志本次数模转换结束,并重新开放AD中断和定时中断。
ADC_CONTR&=~0X10;//ADC_FLAG=0,数模转换结束标志被程序清为0
ADC_CONTR|=0X08; //ADC_START=1,模数转换启动,结束后自动为0
4.10 voiddate_processP1_0()
将十进制P1_0电压信息分别取出其个位、小数点后两位信息。
4.11 voiddate_processP1_1()
将十进制P1_1电压信息分别取出其个位、小数点后两位信息。
5 相关寄存器知识







