这个是单片机练习,大致需要实现的功能如下:
1.包括一个电源开关,一个设定按键,两个控制设定温度增减的按键
2.通过4位数码管分别显示设定温度和实际温度,量程为0到99度,开机后设定温度值初始化为26度(这个地方我用了两个2位数码管分别显示,设定温度值通过蓝色数码管显示)
3.用ds18b20对温度进行转换并通过数码管显示(通过红色数码管显示)
4.单片机要根据设定温度S和实测温度P控制继电器R的动作,精度为2度
(1)当P<=S-1时,继电器接通加热回路
(2)当P>S+1时,继电器断开加热回路
(3)当P>S-1且P<=S+1时,继电器保持原状态不变
目前原理图和程序都已经基本完成了,但是只实现了“通过ds18b20读取温度并通过数码管显示”,和“通过数码管显示设定温度,并通过按键增减数值”这两个模块的功能,按下设定按键后,无论设定温度和实测温度值之间关系如何,P3.0口始终保持高电平,继电器没有任何动作,目前找不到问题出在什么地方。
此外还很好奇为什么开始仿真时,显示实测温度的数码管会显示85大约1秒钟的时间,之后才恢复正常,如果可以解决的话又要如何解决呢?
希望各位大神能够指导一下。
下面是原理图:
原理图,应该也存在需要修改的地方
下面是我自己在参考了一些文章后编写的代码,参考的部分主要是控制ds18b20初始化和读写数据
- /*预计实现功能:DS18B20读取温度通过P3.7口送入单片机,P3.2和P3.3通过外部中断方式增大或减小设定温度值*/
- /*P3.1口是设定按键,P3.0口通过光耦连接继电器*/
- /*设定按键按下后,当DS18B20读取到的温度数值小于设定温度减1时,继电器会接通;*/
- /*当读取到的温度大于设定温度加1时,继电器断开;*/
- /*当读取到的温度大于设定温度-1且小于等于设定温度+1时,继电器不动作*/
- /*目前的问题是程序只能实现显示当前温度和设定温度两个功能*/
- /*而无论当前温度和设定温度数值大小关系如何,P3.0口始终保持高电平,无任何动作,目前找不到问题出在什么地方*/
- /*希望能够得到解答和帮助*/
- #include<reg51.h>//头文件
- /*测量部分温度显示相关变量定义*/
- sbit DQ=P3^7;//DE18B20总线
- sbit CurTempTP=P2^0;//当前温度十位,Curent Temperature's Ten Place
- sbit CurTempOP=P2^1;//当前温度个位,Curent Temperature's One Place
- char CurTemp;//量程限制为0到99摄氏度,故使用有符号字符型变量
- int CurTempTPNum;//当前温度十位数字
- int CurTempOPNum;//当前温度个位数字
- /*设定部分温度显示相关变量定义*/
- char SetTemp=26;//设定温度,初始值为26
- sbit SetTempTP=P2^2;//设定温度的十位,set temperature's one place
- sbit SetTempOP=P2^3;//设定温度的个位,set temperature's ten place
- int SetTempTPNum;//设定温度十位数字
- int SetTempOPNum;//设定温度个位数字
- /*其他设定*/
- sbit SetButton=P3^1;//温度设定按键
- sbit Heater=P3^0;//加热线圈继电器控制
- int a,b;
- unsigned char LED[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};//定义0~9共阳极数码管字符码
- void DelayMs(const int ms)//毫秒延时子程序,正常
- {
- int i;
- for(i=0;i<ms;i++)//单次循环约1毫秒,根据输入的ms值进行延时
- {
- int j;
- for(j=0;j<120;j++);
- }
- }
- void DelayUs(unsigned int k)//微秒延时子程序,正常
- {
- while(k--);//每次数值减1延时约6微秒,设定值为需要延时的时间除以6
- }
- void DS18B20Init()//ds18b20初始化子程序,正常
- {
- unsigned char Flag=0;//DS18B20初始化标志位
- DQ=1;//暂时拉高总线
- DelayUs(5);//稍作延时
- DQ=0;//主机(单片机)发送复位脉冲
- DelayUs(80);//保持480微秒以上
- DQ=1;//然后释放总线
- DelayUs(14);//若从机(DS18B20)初始化成功,会在15到60微秒后产生低电平信号,信号持续60到240微秒
- Flag=DQ;//若DQFlag=0则初始化成功,DQFlag=1则初始化失败
- DelayUs(20);
- }
- unsigned char DS18B20ReadData()//ds18b20读数据子程序,正常
- {
- unsigned char k=0;
- unsigned char dat=0;
- for(k=8;k>0;k--)
- {
- DQ=0;//拉低总线
- dat=dat>>1;//从最高位开始读取数据,每读取一位后向右移动一位
- DQ=1;//释放总线
- if(DQ)
- dat|=0x80;
- DelayUs(4);
- }
- return dat;
- }
- void DS18B20WriteData(unsigned char com)//ds18b20写数据子程序,com为command,正常
- {
- unsigned char l=0;
- for(l=8;l>0;l--)
- {
- DQ=0;//拉低总线
- DQ=com&0x01;//从最低位开始写入指令数据,
- DelayUs(5);//延时
- DQ=1;//释放总线
- com=com>>1;//写入一位后,指令数据右移一位等待下一位写入
- }
- }
- unsigned char DS18B20GetTemp()//温度获取
- {
- unsigned char TL=0;//温度低8位
- unsigned char TH=0;//温度高8位
- unsigned char Temp=0;
- DS18B20Init();//温度转换部分,初始化
- DS18B20WriteData(0xcc);//跳过读rom
- DS18B20WriteData(0x44);//转换温度
- DS18B20Init();//温度读取部分
- DS18B20WriteData(0xcc);
- DS18B20WriteData(0xbe);//读取温度
- TL=DS18B20ReadData();//读低8位
- TH=DS18B20ReadData();//读高8位
- Temp=TH<<4;//高8位左移4位后赋值
- Temp=Temp|TL>>4;//低8位左移4位舍弃小数部分后按位或赋值
- return Temp;//返回Temp
- }
- void ShowTemp()//测量温度数值与设定温度数值综合显示,两种数值显示区间均为0到99摄氏度,正常
- {
- //显示当前测量温度,数码管接P0口,数位由P2.0和P2.1口控制
- if(CurTemp>=0&&CurTemp<=99)//当测量值处于0到99摄氏度区间
- {
- CurTempTPNum=CurTemp/10;//取测量值十位
- CurTempOPNum=CurTemp%10;//取测量值个位
- //显示测量值十位,点亮1毫秒后熄灭
- CurTempTP=1;
- P0=LED[CurTempTPNum];
- DelayMs(10);
- CurTempTP=0;
- //显示测量值个位,点亮1毫秒后熄灭
- CurTempOP=1;
- P0=LED[CurTempOPNum];
- DelayMs(10);
- CurTempOP=0;
- }
- else if(CurTemp<0)//当测量值低于0摄氏度,则数码管显示0
- {
- CurTempTP=1;
- P0=LED[0];
- DelayMs(10);
- CurTempTP=0;
- CurTempOP=1;
- P0=LED[0];
- DelayMs(10);
- CurTempOP=0;
- }
- else if(CurTemp>99)//当测量值高于99摄氏度,则数码管显示9
- {
- CurTempTP=1;
- P0=LED[9];
- DelayMs(10);
- CurTempTP=0;
- CurTempOP=1;
- P0=LED[9];
- DelayMs(10);
- CurTempOP=0;
- }
- //显示当前设定温度,数码管连接P1口,数位由P2.2和P2.3控制
- SetTempTPNum=SetTemp/10;//取设定值十位
- SetTempOPNum=SetTemp%10;//取设定值个位
- //显示设定值十位,点亮1毫秒后熄灭
- SetTempOP=1;
- P1=LED[SetTempOPNum];
- DelayMs(10) ;
- SetTempOP=0;
- //显示设定值个位,点亮1毫秒后熄灭
- SetTempTP=1;
- P1=LED[SetTempTPNum];
- DelayMs(10);
- SetTempTP=0;
- }
- void Add() interrupt 0//P3.2口接按钮控制增加设定值,正常
- {
- if(SetTemp<99)//防止数值溢出
- {
- SetTemp++;//设定值加1
- }
- }
- void Sub() interrupt 2//P3.3口接按钮控制减小设定值,正常
- {
- if(SetTemp>0)//防止数值过小
- {
- SetTemp--;//设定值减1
- }
- }
- void main()//主函数,有问题
- {
- EA=1;//允许总中断
- EX0=1;//允许外部中断0
- EX1=1;//允许外部中断1
- IT0=1;//外部中断0跳沿触发
- IT1=1;//外部中断1跳沿触发
- Heater=0;
- while(1)
- {
- CurTemp=DS18B20GetTemp();//读取DS18B20转换的温度
- ShowTemp();
- a=SetTemp-1;
- b=SetTemp+1;
- if(SetButton==0)//原本按下按键后应该会对当前温度和设定温度进行比较然后确定继电器的动作,但是却没有任何反应,也不清楚是哪里出了问题
- {
- DelayMs(10);
- if(SetButton==0)
- {
- if(CurTemp>a&&CurTemp<=b)
- {
- ;
- }
- else if(CurTemp<=a)
- {
- Heater=0;
- }
- else if(CurTemp>b)
- {
- Heater=1;
- }
- }
- }
- }
- }
复制代码
基于DS18B20的水温控制器,但是程序有点小问题.zip
(98.88 KB, 下载次数: 161)
|