动态数码管显示DS18B20测温显示,折腾好几天了,终于搞定了,开始要么不能正常显示温度,要么乱跳动。究其原因是DS18B20读写的时序太严格了,程序中动态数码管显示需要开定时中断扫描显示,折腾多天的问题就是这个定时中断打断了正常的读写时序。附上显示正常的程序,供初学者参考
单片机源程序如下:
- /*********
- 测试DS18B20测温数码管动态显示
- **********/
- #include<STC90C52.h>
- #include"ds18b20.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define LedDuan P0 /*定义数码管段码的控制脚*/
- #define LedWei P2 /*定义数码管位码的控制脚*/
- sbit Out0=P3^2;//增氧泵控制输出
- uchar code NumTab[]={//显示段码共阳码64231750
- 0x21,0xEB,0x85,0x83,0x4B,0x13,0x11,0xAB,0x01,0x03, //"9"
- 0x09,0x51,0x35,0xC1,0x15,0x1D,0x49,0x75,0x29,0x61,0x0D,0xD1,0xDF,0xFF,0x3D,0xD9};
- //A B C D E F H I N U P o - 熄灭 T n
- uchar code DisBit[]={/*0xfe,*/0xfd,0xfb,0xf7,0xef,0xdf,0xbf/*,0x7f*/};//LED位驱动
- uchar data DisBuf[6]={0xff,0xff,0xff,0xff,0xff,0xff}; /*显示段码缓冲值*/
- uchar data DisBitCnt=0;//显示第几位选择
- /*****************************************************************
- 函数名:毫秒级CPU延时函数
- 调 用:delay (?);
- 参 数:1~65535(参数不可为0)
- 返回值:无
- 结 果:占用CPU方式延时与参数数值相同的毫秒时间
- 备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
- /******************************************************************/
- void DelaymsN(uint t)
- {
- uint i; //定义变量
- for(;t>0;t--) //如果t大于0,t减1(外层循环)
- for(i=120;i>0;i--); //i等于124,如果i大于0,i减1
- }
- /******************************
- 初始化设置定时器0,2MS at 12Mhz
- ******************************/
- void timeinit() /*定义中断方式*/
- {
- TMOD=0x01; /*定时0,1工作在方式1*/
- TH0=0xf8;//(65535-1000)/256;//定时1MS*2_6Mhz=2Ms
- TL0=0x2f;//(65535-1000)%256;
- ET0=1; /*开定时器0中断*/
- // ClearEPROM();
- // ReadE2P();//读出设定的值
- EA=1; /*开总中断*/
- TR0=1;
- }
- /********
- 显示数据处理
- ************/
- /*******************************************************************************
- * 函 数 名 : LcdDisplay()
- * 函数功能 : LCD显示读取到的温度
- * 输 入 : v
- * 输 出 : 无
- *******************************************************************************/
- void DisplayTablex(int temp) //lcd显示
- {
- float tp;
- if(temp< 0) //当温度值为负数
- {
- DisBuf[0] = 0xdf; //显示-号
- //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
- temp=temp-1;
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算由?.5,还是在小数点后面。
-
- }
- else
- {
- DisBuf[0] = 0xff;
- tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
- //如果温度是正的那么,那么正数的原码就是补码它本身
- temp=tp*0.0625*100+0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算加上0.5,还是在小数点后面。
- }
- DisBuf[1]= NumTab[temp / 10000];
- DisBuf[2]= NumTab[temp % 10000 / 1000];
- DisBuf[3]= NumTab[temp % 1000 / 100] &0xfe;
- DisBuf[4]= NumTab[temp % 100 / 10];
- DisBuf[5]= NumTab[temp % 10];
- }
- /*****************
- 主函数
- ****************************/
- void main()
- {
- timeinit();//初始化
- while(1)
- {
- DisplayTablex(Ds18b20ReadTemp());
- DelaymsN(200);
- DelaymsN(200);
- }
- }
- /*****第一种显示方式数据处理****
- void Dis0()
- {
- DisBuf[0]=NumTab[0];//O
- DisBuf[1]=NumTab[15];//F
- DisBuf[2]=NumTab[15];//F
- DisBuf[3]=0xff;
- DisBuf[4]=0xff;
- DisBuf[5]=0xff;
- } */
- /*-----------------------------------------------
- 显示部分程序,采用定时器0产生中断,2MS更新一次
- 因为使用晶振为12Mhz
- ------------------------------------------------*/
- void Display() interrupt 1 //using 3
- {
- TR0=0;//关定时器0
- TH0=0xf8;//(65535-1000)/256;//定时1MS*2_6Mhz=2Ms
- TL0=0x2f;//(65535-1000)%256;
- LedWei=0xff; /*关闭显示*/
- TR0=1;//打开定时器0
- // Dis0();//第一种显示方式
- /********开始显示******************/
- LedDuan=DisBuf[DisBitCnt]; /*输出段码数据到数码管*/
- LedWei=DisBit[DisBitCnt]; /*输出位码数据到数码管*/
- DisBitCnt++;
- if(DisBitCnt>=6)
- DisBitCnt=0; /*6位数码管全动态输出*/
- }
复制代码
附上打包的程序
DS18B20.rar
(35.67 KB, 下载次数: 59)
|