历史上的今天
今天是:2024年12月26日(星期四)
2019年12月26日 | 基于DS18B20的数显温度计 数码管显示
2019-12-26 来源:51hei
主要亮点:
1.数码管使用74HC595作为段选驱动,为初学者提供了新的思路
次要亮点:
1.使用小巧的STC15F104W单片机
DS18B20的通信要点在于时序的严格对应,相比之下DHT11这一类的单总线通信时序要求更加宽松。
因为DS18B20算是极为常用的学习器件,故不做过多讲解,本次作品不涉及搜索BOM、精度调节等操作,只是单器件读取温度值,数据处理将可以显示的温度值设置为-20℃~80℃。 使用4位共阴极数码管,显示无符号位
(事实证明不同器件之间会有差异,读取的值也会不尽相同)
DS18B20数据处理参考普中科技相关例程![]()
#include
sbit DSPORT=P3^5;//DS18B20管脚定义
#include
#include"DS18B20.c"
sbit S1=P3^4;
sbit S2=P3^3;//数码管位选管脚定义
sbit SER=P3^0;
sbit RCLK=P3^1;
sbit SRCLK=P3^2;//74HC595管脚定义
//全局变量表
unsigned char code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//给74HC595的段选值
unsigned char Display_Temperature[4]={0x40,0x40,0x40,0x40};
int Data_temperature=0;
unsigned char t0_cnt=0;
/*##############################################################################################
设计名称:基于DS18B20的数显温度计
设计者:清河
平台:STC15F104W
硬件部分
数码管显示:位选使用74HC138改为2-4线译码、段选使用74HC595减少IO口使用
注意:由于STC15系列采用Y5内核,所以有关DS18B20精准延时部分在移植时应首先考虑更换
##############################################################################################*/
void delay(unsigned int cnt)//调用该函数进行一段时间的延时
{
while(cnt--);
}
void hc595send(unsigned char dat)//使用SPI向74HC595发送一个字节的数据
{
unsigned char a;
SRCLK=0;
RCLK=0;
for(a=0;a<8;a++)
{
SER=dat>>7;
dat<<=1;
SRCLK=1;
_nop_();
_nop_();
SRCLK=0;
}
RCLK=1;
_nop_();
_nop_();
RCLK=0;
}
void smgdisplay()//数码管显示函数,参数为需要显示的数组
{
unsigned char i;
for(i=0;i<4;i++)
{
switch(i)//位选,选择点亮的数码管
{
case(0):
S1=0;S2=1; break;
case(1):
S1=1;S2=0; break;
case(2):
S1=0;S2=0; break;
case(3):
S1=1;S2=1; break;
}
hc595send(Display_Temperature);
delay(10); //间隔一段时间扫描
hc595send(0x00);//消隐
}
}
void Data_processing()
{
float temperature=0.0;//【03c4】似乎只是一个用于更改值为float类型的中间变量,考虑删去
int temperature_middle;//为了不更改全局变量中读取出来的Data_temperature设置此中转值
if(Data_temperature>0xf000)//当温度值为负数
{
Display_Temperature[0]=0x40;//显示符号“-”的段码
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temperature_middle=Data_temperature-1;
temperature_middle=~temperature_middle;
temperature=temperature_middle;
temperature_middle=temperature*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
if(temperature_middle<2000)
{
if(temperature_middle>=1000)
{
Display_Temperature[1]=smgduan[temperature_middle%10000/1000];
Display_Temperature[2]=smgduan[temperature_middle%1000/100]|0x80;
Display_Temperature[3]=smgduan[temperature_middle%100/10];
}
else
{
Display_Temperature[1]=smgduan[temperature_middle%1000/100]|0x80;
Display_Temperature[2]=smgduan[temperature_middle%100/10];
Display_Temperature[3]=smgduan[temperature_middle%10];
}
}
else
{
unsigned char i;
for(i=0;i<4;i++)
{
Display_Temperature=0x40;
}
}
}
else
{
temperature=Data_temperature;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temperature_middle=(int)(temperature*0.0625*100+0.5);
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
if(temperature_middle<8000)
{
if(temperature_middle>=1000)
{
Display_Temperature[0]=smgduan[temperature_middle%10000/1000];
Display_Temperature[1]=smgduan[temperature_middle%1000/100]|0x80;
Display_Temperature[2]=smgduan[temperature_middle%100/10];
Display_Temperature[3]=smgduan[temperature_middle%10];
}
else
{
Display_Temperature[0]=0x00;
Display_Temperature[1]=smgduan[temperature_middle/100]|0x80;
Display_Temperature[2]=smgduan[temperature_middle%100/10];
Display_Temperature[3]=smgduan[temperature_middle%10];
}
}
else
{
unsigned char i;
for(i=0;i<4;i++)
{
Display_Temperature=0x40;
}
}
}
}
void sys_init()
{
TH0=0;
TL0=0;
ET0=1;
TR0=1;
EA=1;
}
void main()
{
sys_init();
while(1)
{
smgdisplay();
}
}
void Temperature_Refresh() interrupt 1
{
TL0 = 0x00;
TH0 = 0x28;//5ms初值
if(t0_cnt==10)
{
hc595send(0x00);
Data_temperature=DS18B20_GetTemperature();
Data_processing();
t0_cnt=0;
}
else
{
t0_cnt++;
}
}
由于中断时的数据读取和处理会占用一部分时间,导致数码管有轻微闪烁感,使用者可以考虑将转换精度调为最低并修改转换等待时间以减少数码管的闪烁感,同时别忘记调一下数据处理函数中对应的精度值。
上述程序仍然臃肿,但由于是普通器件的使用,没有难点,所以也没有进行优化,以完成功能为目的。
史海拾趣
|
按下16个矩阵键盘依次在数码管上显示1-16的平方。如按下第一个显示1,第二个显示4... 我写了第3行的检测,就是说:按键按下的话 ,会显示:16 25 36 49: 但是我在实验板上运行的时候,高位的数字只会闪一下 ...… 查看全部问答> |
|
Hp2490如何打开无线网卡,连接指定SSID,最好用C#完成,谢谢 Hp2490如何打开无线网卡,连接指定SSID,最好用C#完成,例如,我们办公室有N个无线网络,我想通过程序控制连接其中指定一个网络。… 查看全部问答> |
|
前一阵重新装机,从网上下了个IAR 3.41 然后有个小工具生成序列号,安装过程没问题,可是在程序编译时出现下面的提示: Fatal Error[Cp001]: Copy protection check, No valid license found for this product [20] 这是什么问题呀?… 查看全部问答> |
|
我尝试把ucos2移植到 cortex m0上,参考了 ucos over cortex m3 的代码。 有这样一个不明白的地方:从main函数开始,系统默认是使用 MSP 做堆栈使用的,也就是说 process模式和 中断模式都是用 MSP。 现在需要改成 proce ...… 查看全部问答> |
|
今天看了下点阵的教程,自己跑去搞了下 ,结果弄是弄出来,可就是每次图像移动前都会红一团 这是电路图还有代码,大大帮忙看看#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit dula=P2^6;sbit wela=P2^7;sbi ...… 查看全部问答> |
|
我在用CCS5中调用IQMATH函数时发现以下小问题: 下面是我的代码: _iq30 in2, out2 ; in2 =_IQ10(0.333*PI/(2*PI)); out2 =_IQ10sinPU(in2); temp = _IQ10toF(out2); in2 =_IQ30(0.333*PI/(2*PI)); out2 =_IQ30cosPU(in2); temp = _IQ30toF ...… 查看全部问答> |




