|
各位大佬和努力中朋友,本人制作个数码管时钟,mcu是stc15w408as,之前用的是12T,单独测试时钟,温度都能显示,本来改1T也是轻轻松松的事,但结果耗费我多少个晚上和周末,现在时钟没问题,自动调光也没问题,但温度显示始终是有问题的,现在一直显示-06℃。我也大概知道可能时序问题,但参照很多例程,就是调不好,真是绝望的很。只能求助了。
单片机源程序如下:
ds18b20.c
- //===========================================================================
- // 包含头文件
- //===========================================================================
- #include "DS18B20.h"
- #include "Delay.h"
- //===========================================================================
- // 宏定义
- //===========================================================================
- //===========================================================================
- // 函数原型声明
- //===========================================================================
- //===========================================================================
- // 全局变量声明
- //===========================================================================
- u8 DisplayData[4];
- u8 const code smgduan[] = {0x3c}; // 'c'符号,1100 0110数码管0是亮
- u8 const code dis_code_z[] = { // 正装共阳数码管
- 0xC0, // '0'
- 0xF9, // '1'
- 0xA4, // '2'
- 0xB0, // '3'
- 0x99, // '4'
- 0x92, // '5'
- 0x82, // '6'
- 0xF8, // '7'
- 0x80, // '8'
- 0x90, // '9'
- 0xFF // off
- };
- u8 const code dis_code_d[] = { // 倒装共阳数码管
- 0xC0, // '0'
- 0xCF, // '1'
- 0xA4, // '2'
- 0x86, // '3'
- 0x8B, // '4'
- 0x92, // '5'
- 0x90, // '6'
- 0xC7, // '7'
- 0x80, // '8'
- 0x82, // '9'
- 0xFF // 'off'
- };
- //===========================================================================
- // 外部变量声明
- //===========================================================================
- /*""FUNC COMMENT""***********************************************************
- *----------------------------------------------------------------------------
- * 功 能 : 初始化
- *----------------------------------------------------------------------------
- * 引 数 : 无
- *----------------------------------------------------------------------------
- * 返 回 值 : 初始化成功返回1,失败返回0
- *----------------------------------------------------------------------------
- * 注意事项 : 无
- *----------------------------------------------------------------------------
- *""FUNC COMMENT END""*******************************************************/
- bit ds18b20_reset(void)
- {
- u8 F_init = 0;
-
- DQ = 1; // 首先将数据线置高
- delay_us(1); // 短暂延时 (大约2us)
- DQ = 0; // 送出低电平复位信号
- delay_250us(); // 延时在480~960US之间
- delay_250us();
- delay_250us();
- DQ = 1; // 拉高 释放数据线
- delay_70us(); // 延时等待要求大于60us
- F_init = DQ; // DS18B20产生“存在脉冲”
- // 检测DQ若低,则复位成功,DS18B20存在
- // 若高,则复位失败,DS18B20损坏或不存在
- delay_250us(); // 等待释放数据线,避免影响下一步操作
- delay_250us();
-
- return (F_init); // 返回复位结果
- }
- /*""FUNC COMMENT""***********************************************************
- *----------------------------------------------------------------------------
- * 功 能 : 向18B20写入一个字节
- *----------------------------------------------------------------------------
- * 引 数 : dat
- *----------------------------------------------------------------------------
- * 返 回 值 : 无
- *----------------------------------------------------------------------------
- * 注意事项 : 无
- *----------------------------------------------------------------------------
- *""FUNC COMMENT END""*******************************************************/
- void ds18b20_writeData(u8 byte)
- {
- u8 i;
-
- for (i = 0; i < 8; i++) // 重复直到发送完整个字节
- {
- DQ = 1;
- delay_us(1);
- DQ = 0; // 数据线首先拉低,开始写
- delay_us(1); // 低电平保持1us以上
- DQ = byte & 0x01; // 送出数据
- delay_70us(); // 写周期在60us-120us间,等待时间片结束
- DQ = 1; // 释放数据线
- byte >>= 1;
- delay_us(1); // 恢复延时
- }
- }
- /*""FUNC COMMENT""***********************************************************
- *----------------------------------------------------------------------------
- * 功 能 : 读取一个字节
- *----------------------------------------------------------------------------
- * 引 数 : 无
- *----------------------------------------------------------------------------
- * 返 回 值 : 读取的数据
- *----------------------------------------------------------------------------
- * 注意事项 : 无
- *----------------------------------------------------------------------------
- *""FUNC COMMENT END""*******************************************************/
- u8 ds18b20_readData(void)
- {
- u8 i;
- u8 byte = 0;
-
- for (i = 0; i < 8; i++) // 重复接收直到读完整个字节
- {
-
- DQ = 0; // 开始时间片,开始一个读过程
- delay_us(1); // 保持1us以上
- DQ = 1; // 准备接收,开始读取数据线状态
- delay_us(1); // 读时间片开始后15us内主机对数据线进行采集
- byte >>= 1;
- if(DQ)
- {
- byte |= 0x80; // 读取数据
- }
- delay_70us(); // 等待时间片结束,读周期60us-120us间
- }
- return (byte);
- }
- /* void ds1820_setResolution(u8 res)//设置分辨率 默认12wei
- {
- while (ds18b20_reset());
- ds18b20_writeByte(0x4E);
- ds18b20_writeByte(0xFF);
- ds18b20_writeByte(0xFF);
- ds18b20_writeByte(0x1F | (res << 5)); //设置分辨率(0 R1 R0 1 1111)
- } */
- /*""FUNC COMMENT""***********************************************************
- *----------------------------------------------------------------------------
- * 功 能 : 读温度
- *----------------------------------------------------------------------------
- * 引 数 : 无
- *----------------------------------------------------------------------------
- * 返 回 值 : 读取的温度数据
- *----------------------------------------------------------------------------
- * 注意事项 : 无
- *----------------------------------------------------------------------------
- *""FUNC COMMENT END""*******************************************************/
- u16 ds18b20_readTemperature(void)
- {
- u8 TPL, TPH;
- u16 temp;//@001
- ds18b20_reset();
- ds18b20_writeData(0xCC);
- ds18b20_writeData(0x44);
-
- while(!DQ);
-
- ds18b20_reset();
- ds18b20_writeData(0xCC);
- ds18b20_writeData(0xBE);
-
- TPL = ds18b20_readData();
- TPH = ds18b20_readData();
-
- temp = TPH;
- temp <<= 8;
- temp |= TPL;
-
- return (temp);
- }
- /*""FUNC COMMENT""***********************************************************
- *----------------------------------------------------------------------------
- * 功 能 : 获取温度数据并处理
- *----------------------------------------------------------------------------
- * 引 数 : temp
- *----------------------------------------------------------------------------
- * 返 回 值 : 无
- *----------------------------------------------------------------------------
- * 注意事项 : 无
- *----------------------------------------------------------------------------
- *""FUNC COMMENT END""*******************************************************/
- void ds18b20_dataProcess(u16 temp) //@@1
- {
- float tp;
- // if (temp < 0)
- if ((temp & 0xF800) != 0)
- {
- DisplayData[3] = 0xBF; // '-'
- //因为读取的温度是实际温度的补码,所以减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的就
- //算加上0.5,还是在小数点后面。
- DisplayData[2] = dis_code_z[temp / 10]; // 十位
- DisplayData[1] = dis_code_d[temp % 10]; // 个位
- DisplayData[0] = smgduan[0]; // 显示C符号
- }
- else
- {
- //DisplayData[0] = 0x00;
- tp = temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
- //如果温度是正的那么,那么正数的原码就是补码它本身
- temp = tp*0.0625*100 + 0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算加上0.5,还是在小数点后面。
- if (( temp / 100 ) == 0)
- {
- DisplayData[3] = 0xFF;
- }
- else
- {
- DisplayData[3] = dis_code_z[temp / 100]; // 千位
- DisplayData[2] = dis_code_z[temp % 100 / 10] & 0x7F;// 十位
- DisplayData[1] = dis_code_d[temp % 10]; // 个位
- DisplayData[0] = smgduan[0]; // 显示C符号
- }
- }
- }
复制代码 还有个很莫名的问题也废了很多时间就是定时中断,参照着datasheet改1T,但若不加/12就不是1ms中断。。后来发现后加上能输出1ms。
#define T1MS (65536 - FOSC/1000/12)
|
|