第49节:利用DS18B20做一个温控器
DS18B20是一款常用的温度传感器芯片,它只占用单片机一根IO口,使用起来也特别方便。需要特别注意的是,正因为它只用一根IO口跟单片机通讯,因此读取一次温度值的通讯时间比较长,而且时序要求严格,在通讯期间不允许被单片机其它的中断干扰,因此在实际项目中,系统一旦选用了这款传感器芯片,就千万不要选用动态扫描数码管的显示方式。否则在关闭中断读取温度的时候,数码管的显示会有略微的“闪烁”现象。
DS18B20的测温范围是-55度至125度。在-10度至85度的温度范围内误差是+-0.5度,能满足大部分常用的测温要求。
这一节要教会大家三个知识点:
第一个:大概了解一下DS18B20的驱动程序。
第二个:做温控设备的时候,为了避免继电器在临界温度附近频繁跳动切换,应该设置一个缓冲温差。本程序的缓冲温差是2度。
第三个:继续加深了解按键,显示,传感器它们三者是如何紧密关联起来的程序框架。
具体内容,请看源代码讲解。
(1) 硬件平台.
基于朱兆祺51单片机学习板。
(2)实现功能:
本程序只有1个窗口。这个窗口有2个局部显示。
第1个局部是第7,6,5位数码管,显示设定的温度。
第2个局部是第4,3,2,1位数码管,显示实际环境温度。其中第4位数码管显示正负符号位。
S1按键是加键,S5按键是减键。通过它们可以直接设置“设定温度”。
一个LED灯用来模拟工控的继电器。
当实际温度低于或者等于设定温度2度以下时,模拟继电器的LED灯亮。
当实际温度等于或者大于设定温度时,模拟继电器的LED灯灭。
当实际温度处于设定温度和设定温度减去2度的范围内,模拟继电器的LED维持现状,这个2度范围用来做缓冲温差,避免继电器在临界温度附近频繁跳动切换。
(3)源代码讲解如下:
- #include "REG52.H"
- #define const_voice_short40 //蜂鸣器短叫的持续时间
- #define const_key_time120 //按键去抖动延时的时间
- #define const_key_time220 //按键去抖动延时的时间
- #define const_ds18b20_sampling_time 180 //累计主循环次数的时间,每次刷新采样时钟芯片的时间
- void initial_myself(void);
- void initial_peripheral(void);
- void delay_short(unsigned int uiDelayShort);
- void delay_long(unsigned int uiDelaylong);
- //驱动数码管的74HC595
- void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01);
- void display_drive(void); //显示数码管字模的驱动函数
- void display_service(void); //显示的窗口菜单服务程序
- //驱动LED的74HC595
- void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01);
- void T0_time(void);//定时中断函数
- void key_service(void); //按键服务的应用程序
- void key_scan(void);//按键扫描函数 放在定时中断里
- void temper_control_service(void); //温控程序
- void ds18b20_sampling(void); //ds18b20采样程序
- void ds18b20_reset(); //复位ds18b20的时序
- unsigned char ds_read_byte(void ); //读一字节
- void ds_write_byte(unsigned char dat); //写一个字节
- unsigned int get_temper();//读取一次没有经过换算的温度数值
- sbit dq_dr_sr=P2^6; //ds18b20的数据驱动线
- sbit key_sr1=P0^0; //对应朱兆祺学习板的S1键
- sbit key_sr2=P0^1; //对应朱兆祺学习板的S5键
- sbit led_dr=P3^5;//LED灯,模拟工控中的继电器
- sbit key_gnd_dr=P0^4; //模拟独立按键的地GND,因此必须一直输出低电平
- sbit beep_dr=P2^7; //蜂鸣器的驱动IO口
- sbit dig_hc595_sh_dr=P2^0; //数码管的74HC595程序
- sbit dig_hc595_st_dr=P2^1;
- sbit dig_hc595_ds_dr=P2^2;
- sbit hc595_sh_dr=P2^3; //LED灯的74HC595程序
- sbit hc595_st_dr=P2^4;
- sbit hc595_ds_dr=P2^5;
- unsigned int uiSampingCnt=0; //采集Ds1302的计时器,每秒钟更新采集一次
- unsigned char ucSignFlag=0; //正负符号。0代表正数,1代表负数,表示零下多少度。
- unsigned long ulCurrentTemper=33; //实际温度
- unsigned long ulSetTemper=26; //设定温度
- unsigned int uiTemperTemp=0; //中间变量
- unsigned char ucKeySec=0; //被触发的按键编号
- unsigned intuiKeyTimeCnt1=0; //按键去抖动延时计数器
- unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
- unsigned intuiKeyTimeCnt2=0; //按键去抖动延时计数器
- unsigned char ucKeyLock2=0; //按键触发后自锁的变量标志
- unsigned intuiVoiceCnt=0;//蜂鸣器鸣叫的持续时间计数器
- unsigned charucVoiceLock=0;//蜂鸣器鸣叫的原子锁
- unsigned char ucDigShow8;//第8位数码管要显示的内容
- unsigned char ucDigShow7;//第7位数码管要显示的内容
- unsigned char ucDigShow6;//第6位数码管要显示的内容
- unsigned char ucDigShow5;//第5位数码管要显示的内容
- unsigned char ucDigShow4;//第4位数码管要显示的内容
- unsigned char ucDigShow3;//第3位数码管要显示的内容
- unsigned char ucDigShow2;//第2位数码管要显示的内容
- unsigned char ucDigShow1;//第1位数码管要显示的内容
- unsigned char ucDigDot8;//数码管8的小数点是否显示的标志
- unsigned char ucDigDot7;//数码管7的小数点是否显示的标志
- unsigned char ucDigDot6;//数码管6的小数点是否显示的标志
- unsigned char ucDigDot5;//数码管5的小数点是否显示的标志
- unsigned char ucDigDot4;//数码管4的小数点是否显示的标志
- unsigned char ucDigDot3;//数码管3的小数点是否显示的标志
- unsigned char ucDigDot2;//数码管2的小数点是否显示的标志
- unsigned char ucDigDot1;//数码管1的小数点是否显示的标志
- unsigned char ucDigShowTemp=0; //临时中间变量
- unsigned char ucDisplayDriveStep=1;//动态扫描数码管的步骤变量
- unsigned char ucWd=1;//因为本程序只有1个窗口,在实际项目中,此处的ucWd也可以省略不要
- unsigned char ucWd1Part1Update=1;//在窗口1中,局部1的更新显示标志
- unsigned char ucWd1Part2Update=1; //在窗口1中,局部2的更新显示标志
- unsigned char ucTemp1=0;//中间过渡变量
- unsigned char ucTemp2=0;//中间过渡变量
- unsigned char ucTemp3=0;//中间过渡变量
- unsigned char ucTemp4=0;//中间过渡变量
- unsigned char ucTemp5=0;//中间过渡变量
- unsigned char ucTemp6=0;//中间过渡变量
- unsigned char ucTemp7=0;//中间过渡变量
- unsigned char ucTemp8=0;//中间过渡变量
- //根据原理图得出的共阴数码管字模表
- code unsigned char dig_table[]=
- {
- 0x3f,//0 序号0
- 0x06,//1 序号1
- 0x5b,//2 序号2
- 0x4f,//3 序号3
- 0x66,//4 序号4
- 0x6d,//5 序号5
- 0x7d,//6 序号6
- 0x07,//7 序号7
- 0x7f,//8 序号8
- 0x6f,//9 序号9
- 0x00,//无 序号10
- 0x40,//- 序号11
- 0x73,//P 序号12
- };
- void main()
- {
- initial_myself();
- delay_long(100);
- initial_peripheral();
- while(1)
- {
- key_service(); //按键服务的应用程序
- ds18b20_sampling(); //ds18b20采样程序
- temper_control_service(); //温控程序
- display_service(); //显示的窗口菜单服务程序
- }
- }
- /* 注释一:
- * 做温控设备的时候,为了避免继电器在临界温度附近频繁跳动切换,应该设置一个
- * 缓冲温差。本程序的缓冲温差是2度。
- */
- void temper_control_service(void) //温控程序
- {
- if(ucSignFlag==0) //是正数的前提下
- {
- if(ulCurrentTemper>=ulSetTemper)//当实际温度大于等于设定温度时
- {
- led_dr=0; //模拟继电器的LED灯熄灭
- }
- else if(ulCurrentTemper<=(ulSetTemper-2))//当实际温度小于等于设定温度2读以下时,这里的2是缓冲温差2度
- {
- led_dr=1; //模拟继电器的LED灯点亮
- }
- }
- else//是负数,说明是零下多少度的情况下
- {
- led_dr=1; //模拟继电器的LED灯点亮
- }
- }
- void ds18b20_sampling(void) //ds18b20采样程序
- {
- ++uiSampingCnt;//累计主循环次数的时间
- if(uiSampingCnt>const_ds18b20_sampling_time)//每隔一段时间就更新采集一次Ds18b20数据
- {
- uiSampingCnt=0;
- ET0=0;//禁止定时中断
- uiTemperTemp=get_temper();//读取一次没有经过换算的温度数值
- ET0=1; //开启定时中断
- if((uiTemperTemp&0xf800)==0xf800) //是负号
- {
- ucSignFlag=1;
- uiTemperTemp=~uiTemperTemp;//求补码
- uiTemperTemp=uiTemperTemp+1;
- }
- else //是正号
- {
- ucSignFlag=0;
- }
- ulCurrentTemper=0; //把int数据类型赋给long类型之前要先清零
- ulCurrentTemper=uiTemperTemp;
- ulCurrentTemper=ulCurrentTemper*10; //为了先保留一位小数点,所以放大10倍,
- ulCurrentTemper=ulCurrentTemper>>4;//往右边移动4位,相当于乘以0.0625. 此时保留了1位小数点,
- ulCurrentTemper=ulCurrentTemper+5;//四舍五入
- ulCurrentTemper=ulCurrentTemper/10; //四舍五入后,去掉小数点
- ucWd1Part2Update=1; //局部2更新显示实时温度
- }
- }
- //ds18b20驱动程序
- unsigned int get_temper()//读取一次没有经过换算的温度数值
- {
- unsigned char temper_H;
- unsigned char temper_L;
- unsigned int ds18b20_data=0;
- ds18b20_reset(); //复位ds18b20的时序
- ds_write_byte(0xCC);
- ds_write_byte(0x44);
- ds18b20_reset(); //复位ds18b20的时序
- ds_write_byte(0xCC);
- ds_write_byte(0xBE);
- temper_L=ds_read_byte();
- temper_H=ds_read_byte();
- ds18b20_data=temper_H; //把两个字节合并成一个int数据类型
- ds18b20_data=ds18b20_data<<8;
- ds18b20_data=ds18b20_data|temper_L;
- return ds18b20_data;
- }
- void ds18b20_reset() //复位ds18b20的时序
- {
- unsigned char x;
- dq_dr_sr=1;
- delay_short(8);
- dq_dr_sr=0;
- delay_short(80);
- dq_dr_sr=1;
- delay_short(14);
- x=dq_dr_sr;
- delay_short(20);
- }
- void ds_write_byte(unsigned char date) //写一个字节
- {
- unsigned chari;
- for(i=0;i<8;i++)
- {
- dq_dr_sr=0;
- dq_dr_sr=date&0x01;
- delay_short(5);
- dq_dr_sr=1;
- date=date>>1;
- }
- }
- unsigned char ds_read_byte(void ) //读一字节
- {
- unsigned char i;
- unsigned char date=0;
- for(i=0;i<8;i++)
- {
- dq_dr_sr=0;
- date=date>>1;
- dq_dr_sr=1;
- if(dq_dr_sr)
- {
- date=date|0x80;
- }
- delay_short(5);
- }
- return (date);
- }
- void display_service(void) //显示的窗口菜单服务程序
- {
- switch(ucWd)//因为本程序只有1个窗口,在实际项目中,此处的ucWd也可以省略不要
- {
- case 1:
- if(ucWd1Part1Update==1)//局部设定温度更新显示
- {
- ucWd1Part1Update=0;
- ucTemp8=10; //显示空
- if(ulSetTemper>=100)
- {
- ucTemp7=ulSetTemper%1000/100; //显示设定温度的百位
- }
- else
- {
- ucTemp7=10; //显示空
- }
- if(ulSetTemper>=10)
- {
- ucTemp6=ulSetTemper%100/10; //显示设定温度的十位
- }
- else
- {
- ucTemp6=10; //显示空
- }
- ucTemp5=ulSetTemper%10; //显示设定温度的个位
- ucDigShow8=ucTemp8; //数码管显示实际内容
- ucDigShow7=ucTemp7;
- ucDigShow6=ucTemp6;
- ucDigShow5=ucTemp5;
- }
- if(ucWd1Part2Update==1)//局部实际温度更新显示
- {
- if(ucSignFlag==0)//正数
- {
- ucTemp4=10; //显示空
- }
- else//负数,说明是零下多少度的情况下
- {
- ucTemp4=11; //显示负号-
- }
- if(ulCurrentTemper>=100)
- {
- ucTemp3=ulCurrentTemper%100/100; //显示实际温度的百位
- }
- else
- {
- ucTemp3=10; //显示空
- }
- if(ulCurrentTemper>=10)
- {
- ucTemp2=ulCurrentTemper%100/10;//显示实际温度的十位
- }
- else
- {
- ucTemp2=10;//显示空
- }
- ucTemp1=ulCurrentTemper%10; //显示实际温度的个数位
- ucDigShow4=ucTemp4; //数码管显示实际内容
- ucDigShow3=ucTemp3;
- ucDigShow2=ucTemp2;
- ucDigShow1=ucTemp1;
- }
- break;
- }
- }
- void key_scan(void)//按键扫描函数 放在定时中断里
- {
- if(key_sr1==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
- {
- ucKeyLock1=0; //按键自锁标志清零
- uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
- }
- else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
- {
- uiKeyTimeCnt1++; //累加定时中断次数
- if(uiKeyTimeCnt1>const_key_time1)
- {
- uiKeyTimeCnt1=0;
- ucKeyLock1=1;//自锁按键置位,避免一直触发
- ucKeySec=1; //触发1号键
- }
- }
- if(key_sr2==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
- {
- ucKeyLock2=0; //按键自锁标志清零
- uiKeyTimeCnt2=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
- }
- else if(ucKeyLock2==0)//有按键按下,且是第一次被按下
- {
- uiKeyTimeCnt2++; //累加定时中断次数
- if(uiKeyTimeCnt2>const_key_time2)
- {
- uiKeyTimeCnt2=0;
- ucKeyLock2=1;//自锁按键置位,避免一直触发
- ucKeySec=2; //触发2号键
- }
- }
- }
- void key_service(void) //按键服务的应用程序
- {
- switch(ucKeySec) //按键服务状态切换
- {
- case 1:// 加按键 对应朱兆祺学习板的S1键
- switch(ucWd) //因为本程序只有1个窗口,在实际项目中,此处的ucWd也可以省略不要
- {
- case 1: //在窗口1下设置设定温度
- ulSetTemper++;
- if(ulSetTemper>125)
- {
- ulSetTemper=125;
- }
- ucWd1Part1Update=1; //更新显示设定温度
- break;
- }
- ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCnt
- uiVoiceCnt=const_voice_short; //按键声音触发,滴一声就停。
- ucVoiceLock=0;//原子锁解锁,保护主函数与中断函数的共享变量uiVoiceCnt
- ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发
- break;
- case 2:// 减按键 对应朱兆祺学习板的S5键
- switch(ucWd) //因为本程序只有1个窗口,在实际项目中,此处的ucWd也可以省略不要
- {
- case 1: //在窗口1下设置设定温度
- if(ulSetTemper>2)//由于缓冲温差是2度,所以我人为规定最小允许设定的温度不能低于2度
- {
- ulSetTemper--;
- }
- ucWd1Part1Update=1; //更新显示设定温度
- break;
- }
- ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCnt
- uiVoiceCnt=const_voice_short; //按键声音触发,滴一声就停。
- ucVoiceLock=0;//原子锁解锁,保护主函数与中断函数的共享变量uiVoiceCnt
- ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发
- break;
- }
- }
- void display_drive(void)
- {
- //以下程序,如果加一些数组和移位的元素,还可以压缩容量。但是鸿哥追求的不是容量,而是清晰的讲解思路
- switch(ucDisplayDriveStep)
- {
- case 1://显示第1位
- ucDigShowTemp=dig_table[ucDigShow1];
- if(ucDigDot1==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xfe);
- break;
- case 2://显示第2位
- ucDigShowTemp=dig_table[ucDigShow2];
- if(ucDigDot2==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xfd);
- break;
- case 3://显示第3位
- ucDigShowTemp=dig_table[ucDigShow3];
- if(ucDigDot3==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xfb);
- break;
- case 4://显示第4位
- ucDigShowTemp=dig_table[ucDigShow4];
- if(ucDigDot4==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xf7);
- break;
- case 5://显示第5位
- ucDigShowTemp=dig_table[ucDigShow5];
- if(ucDigDot5==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xef);
- break;
- case 6://显示第6位
- ucDigShowTemp=dig_table[ucDigShow6];
- if(ucDigDot6==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xdf);
- break;
- case 7://显示第7位
- ucDigShowTemp=dig_table[ucDigShow7];
- if(ucDigDot7==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0xbf);
- break;
- case 8://显示第8位
- ucDigShowTemp=dig_table[ucDigShow8];
- if(ucDigDot8==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,0x7f);
- break;
- }
- ucDisplayDriveStep++;
- if(ucDisplayDriveStep>8)//扫描完8个数码管后,重新从第一个开始扫描
- {
- ucDisplayDriveStep=1;
- }
- }
- //数码管的74HC595驱动函数
- void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01)
- {
- unsigned char i;
- unsigned char ucTempData;
- dig_hc595_sh_dr=0;
- dig_hc595_st_dr=0;
- ucTempData=ucDigStatusTemp16_09;//先送高8位
- for(i=0;i<8;i++)
- {
- if(ucTempData>=0x80)dig_hc595_ds_dr=1;
- else dig_hc595_ds_dr=0;
- dig_hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
- delay_short(1);
- dig_hc595_sh_dr=1;
- delay_short(1);
- ucTempData=ucTempData<<1;
- }
- ucTempData=ucDigStatusTemp08_01;//再先送低8位
- for(i=0;i<8;i++)
- {
- if(ucTempData>=0x80)dig_hc595_ds_dr=1;
- else dig_hc595_ds_dr=0;
- dig_hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
- delay_short(1);
- dig_hc595_sh_dr=1;
- delay_short(1);
- ucTempData=ucTempData<<1;
- }
- dig_hc595_st_dr=0;//ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来
- delay_short(1);
- dig_hc595_st_dr=1;
- delay_short(1);
- dig_hc595_sh_dr=0; //拉低,抗干扰就增强
- dig_hc595_st_dr=0;
- dig_hc595_ds_dr=0;
- }
- //LED灯的74HC595驱动函数
- void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01)
- {
- unsigned char i;
- unsigned char ucTempData;
- hc595_sh_dr=0;
- hc595_st_dr=0;
- ucTempData=ucLedStatusTemp16_09;//先送高8位
- for(i=0;i<8;i++)
- {
- if(ucTempData>=0x80)hc595_ds_dr=1;
- else hc595_ds_dr=0;
- hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
- delay_short(1);
- hc595_sh_dr=1;
- delay_short(1);
- ucTempData=ucTempData<<1;
- }
- ucTempData=ucLedStatusTemp08_01;//再先送低8位
- for(i=0;i<8;i++)
- {
- if(ucTempData>=0x80)hc595_ds_dr=1;
- else hc595_ds_dr=0;
- hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
- delay_short(1);
- hc595_sh_dr=1;
- delay_short(1);
- ucTempData=ucTempData<<1;
- }
- hc595_st_dr=0;//ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来
- delay_short(1);
- hc595_st_dr=1;
- delay_short(1);
- hc595_sh_dr=0; //拉低,抗干扰就增强
- hc595_st_dr=0;
- hc595_ds_dr=0;
- }
- void T0_time(void) interrupt 1 //定时中断
- {
- TF0=0;//清除中断标志
- TR0=0; //关中断
- if(ucVoiceLock==0) //原子锁判断
- {
- if(uiVoiceCnt!=0)
- {
- uiVoiceCnt--; //每次进入定时中断都自减1,直到等于零为止。才停止鸣叫
- beep_dr=0;//蜂鸣器是PNP三极管控制,低电平就开始鸣叫。
- }
- else
- {
- ; //此处多加一个空指令,想维持跟if括号语句的数量对称,都是两条指令。不加也可以。
- beep_dr=1;//蜂鸣器是PNP三极管控制,高电平就停止鸣叫。
- }
- }
- key_scan(); //按键扫描函数
- display_drive();//数码管字模的驱动函数
- TH0=0xfe; //重装初始值(65535-500)=65035=0xfe0b
- TL0=0x0b;
- TR0=1;//开中断
- }
- void delay_short(unsigned int uiDelayShort)
- {
- unsigned int i;
- for(i=0;i
- {
- ; //一个分号相当于执行一条空语句
- }
- }
- void delay_long(unsigned int uiDelayLong)
- {
- unsigned int i;
- unsigned int j;
- for(i=0;i
- {
- for(j=0;j<500;j++)//内嵌循环的空指令数量
- {
- ; //一个分号相当于执行一条空语句
- }
- }
- }
- void initial_myself(void)//第一区 初始化单片机
- {
- led_dr=0;//此处的LED灯模拟工控中的继电器
- key_gnd_dr=0; //模拟独立按键的地GND,因此必须一直输出低电平
- beep_dr=1; //用PNP三极管控制蜂鸣器,输出高电平时不叫。
- hc595_drive(0x00,0x00);//关闭所有经过另外两个74HC595驱动的LED灯
- TMOD=0x01;//设置定时器0为工作方式1
- TH0=0xfe; //重装初始值(65535-500)=65035=0xfe0b
- TL0=0x0b;
- }
- void initial_peripheral(void) //第二区 初始化外围
- {
- ucDigDot8=0; //小数点全部不显示
- ucDigDot7=0;
- ucDigDot6=0;
- ucDigDot5=0;
- ucDigDot4=0;
- ucDigDot3=0;
- ucDigDot2=0;
- ucDigDot1=0;
- EA=1; //开总中断
- ET0=1; //允许定时中断
- TR0=1; //启动定时中断
- }
总结陈词:
下一节开始讲单片机采集模拟信号的内容,欲知详情,请听下回分解-----利用ADC0832采集电压的模拟信号。
评论