“温度和光照传感器测试”案例程序设计说明
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) 对于温度通过AD采集,涉及寄存器及配置如下:
P1ASF=0xff;
ADC_RES=0;
ADC_RESL=0; //AD转换结果寄存器清0
ADC_CONTR=0X8B; //10001011,后三位决定P1^3作为A/D输入来用;ADC_START(右4位)为1,开始转换;最高位ADC_Power=1,打开A/D转换器电源
CLK_DIV=0X20;
4) 对于光照通过AD采集,涉及寄存器及配置如下:
P1ASF=0xff;
ADC_RES=0;
ADC_RESL=0; //AD转换结果寄存器清0
ADC_CONTR=0X8C; //10001100,后三位决定P1^4作为A/D输入来用;ADC_START(右4位)为1,开始转换;最高位ADC_Power=1,打开A/D转换器电源。
CLK_DIV=0X20;
4 程序设计框架
4.1 void main()
调用T_L()。
4.2 void T_L()
(1)设置P0为推挽模式,设置P2^3为推挽模式,其它为准双向口模式
(2)选通数码管
sbit SEL3=P2^3; SEL3=0;
(3)开定时器中断和AD中断
(4)设定时器1初值并开启定时器1中断
(5)无条件循环调用SEG_Display()。
4.3 void SEG_Display()
(1) 如果摄氏温度值低于0,则将0号数码管用于显示“-”号;否则显示0;
(2) 1和2号数码管分别显示摄氏温度的十位和个位;
(3) 5、6、7号数码管分别用于显示光信息。
4.4 void Timer1_Routine() interrupt 3
定时器1中断处理程序:
(1) 判断当前flag标志,如果是1,则调用InitADC_light()方法初始化光感相应寄存器;否则调用InitADC_temp()方法初始化温度获取相应寄存器。对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_light()
初始化光照AD转换结果寄存器及控制寄存器
4.8 void InitADC_temp()
初始化温度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_processtemp()
将十进制温度信息分别取出其百位、十位与个位信息。
4.11 voiddate_processlight()
将十进制光信息分别取出其百位、十位与个位信息。
5 相关寄存器知识






6 interrupt 和using
interrupt 和using 都是 C51 的关键字。C51 中断过程通过使用interrupt 关键字和中断号(0 到 31)来实现。中断号指明编译器中断程序的入口地址中断序号对应着 8051中断使能寄存器IE 中的使能位,对应关系如下:
IE寄存器 C51中的 8051的使能位中断号中断源
--------------------------------
IE.0 0 外部中断0
IE.1 1 定时器0 溢出
IE.2 2 外部中断1
IE.3 3 定时器1 溢出
IE.4 4 串口中断
IE.5 5 定时器2 溢出
有了这一声明,编译器不需理会寄存器组参数的使用和对累加器A、状态寄存器、寄存器B、数据指针和默认的寄存器的保护。只要在中断程序中用到,编译器会把它们压栈,在中断程序结束时将他们出栈。C51 支持所有 5 个 8051标准中断从 0 到 4 和在 8051系列(增强型)中多达 27 个中断源。
using 关键字用来指定中断服务程序使用的寄存器组。用法是:using后跟一个0 到3 的数,对应着 4 组工作寄存器。一旦指定工作寄存器组,默认的工作寄存器组就不会被压栈,这将节省 32 个处理周期,因为入栈和出栈都需要 2 个处理周期。这一做法的缺点是所有调用中断的过程都必须使用指定的同一个寄存器组,否则参数传递会发生错误。因此对于using,在使用中需灵活取舍。

