標(biāo)題:
藍(lán)橋杯ct107 51單片機的溫度控制器程序設(shè)計
[打印本頁]
作者:
NCUTER
時間:
2021-11-4 09:22
標(biāo)題:
藍(lán)橋杯ct107 51單片機的溫度控制器程序設(shè)計
基于51單片機的溫度控制器設(shè)計
功能較為完善
單片機源程序如下:
#include "reg52.h"
#include "ct107.h"
#include "iic.h"
#include "EEPROM.H"
#include "18b20.h"
#include "i2c.h"
bit flag_get,keyflag; //定義采集溫度標(biāo)志位和按鍵標(biāo)志位
sbit PWM=P3^4; //定義脈沖端口
sbit LED1=P0^0;
sbit LED2=P0^1;
sbit LED3=P0^2;
sbit LED4=P0^3;
sbit LED5=P0^4;
sbit LED6=P0^5;
sbit LED7=P0^6;
sbit LED8=P0^7;
unsigned char code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管段選“0~9”
unsigned char code smg_we[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //數(shù)碼管位選
unsigned char UpT,DoT,NowT; //上限溫度,下限溫度,目前溫度
unsigned int temp; //定義中間變量
unsigned char dat[8]; //定義顯示數(shù)組
unsigned int Ad_data;
void key(); //按鍵函數(shù)
void diswork(); //顯示處理函數(shù)
void Write_byte(unsigned char add,unsigned char dat); //向EEPROM寫一個字節(jié)
unsigned char read_byte(unsigned char add); //從EEPROM讀一個字節(jié)
unsigned int ReadTemperature(void); //讀當(dāng)前溫度
void deplay_50us(unsigned char t); //50us延時函數(shù)
void work(); //判斷采用何種措施函數(shù)
void Ad_read(void); //電壓讀取
main() //主函數(shù)
{
ct107_init(); //初始化板(關(guān)蜂鳴器,繼電器,LED等)
TMOD=0X12; //定義定時器1為16位,定時器0為8位重載定時器
TH1=(65536-2000)/256; //定時2ms
TL1=(65536-2000)%256;
TH0=256-100; //定時0.1ms
TL0=256-100;
TR1=1; //開定時器T1
ET1=1; //開定時器T1中斷
TR0=1; //開定時器T0
EA=1; //開總中斷
while(1)
{
key();
if(flag_get==1) //定時讀取當(dāng)前溫度
{
Ad_read();
temp=ReadTemperature();
NowT=temp>>4; //讀溫度整數(shù)部分
flag_get=0;
}
UpT=read_byte(0x00); //從EEPROM讀出上限溫度
DoT=read_byte(0x01); //從EEPROM讀出下限溫度
work();
diswork();
}
}
/*--------------------------------------------------------------------------
判斷采用何種措施函數(shù)
-------------------------------------------------------------------------*/
void work()
{
if(NowT>UpT) //當(dāng)目前溫度高于上限溫度是開T0中斷,產(chǎn)生1KHz占空比為30%的方波
{
ET0=1;
LED1=0;
LED2=1;
LED3=1;
LED4=1;
LED5=1;
LED6=1;
LED7=1;
LED8=1;
P2|=Y4C;
P2&=0x1f;
}
else
if(NowT>DoT) //溫度在上下限之間時,關(guān)中斷,P3^4口保持高電平
{
ET0=0;
PWM=1;
LED1=1;
LED2=0;
LED3=1;
LED4=1;
LED5=1;
LED6=1;
LED7=1;
LED8=1;
P2|=Y4C;
P2&=0x1f;
}
if(NowT<DoT) //溫度低于下限溫度時開繼電器,關(guān)蜂鳴器避免干擾
{
P2&=0x1f;
BUZZ=0;
RELAY=1;
P2|=Y5C;
P2&=0x1f;
LED1=1;
LED2=1;
LED3=0;
LED4=1;
LED5=1;
LED6=1;
LED7=1;
LED8=1;
P2|=Y4C;
P2&=0x1f;
}
else
{
P2&=0x1f;
BUZZ=0;
RELAY=0;
P2|=Y5C;
P2&=0x1f;
}
}
/*-------------------------------------------------------------------------------
按鍵掃描函數(shù)
-------------------------------------------------------------------------------*/
void key()
{
if((P3&0x0f)!=0x0f)
{
if(!keyflag)
{
deplay_50us(200);
if((P3&0x0f)!=0x0f)
{
keyflag=1;
switch(P3&0x0f)
{
case 0x07:if(UpT<99)UpT++;break;
case 0x0b:if(DoT<UpT-1)DoT++;break;
case 0x0d:if(UpT-1>DoT)UpT--;break;
case 0x0e:if(DoT>0)DoT--;break;
default:break;
}
if(UpT<=DoT|UpT>99|DoT<0) //保護(hù)程序,一旦存儲數(shù)據(jù)出錯可以使數(shù)據(jù)回到設(shè)定值,使系統(tǒng)穩(wěn)定
{
UpT=30;
DoT=0;
}
Write_byte(0x00,UpT); //將數(shù)據(jù)寫入EEPROM
deplay_50us(18);
Write_byte(0x01,DoT);
deplay_50us(18);
}
}
}
else
keyflag=0;
}
/*----------------------------------------------
顯示數(shù)據(jù)處理函數(shù)
----------------------------------------------*/
void diswork()
{
dat[0]=UpT/10;
dat[1]=UpT%10;
dat[2]=DoT/10;
dat[3]=DoT%10;
dat[4]=Ad_data/10;
dat[5]=Ad_data%10;
dat[6]=NowT/10;
dat[7]=NowT%10;
}
/*----------------------------------------
寫入內(nèi)存一個字節(jié)
-----------------------------------------*/
void Write_byte(unsigned char add,unsigned char dat)
{
ET1=0;
init_iic(); //可以不初始化,函數(shù)已有嚴(yán)格的時序控制
Start(); //起始信號
Send(AddWr); //器件地址
Ack(); //應(yīng)答
Send(add); //存放地址
Ack();
Send(dat); //存放數(shù)據(jù)
Ack();
Stop(); //停止信號
ET1=1;
}
/*-----------------------------------------
讀內(nèi)存一個字節(jié)
-----------------------------------------*/
unsigned char read_byte(unsigned char add)
{
unsigned char rdat;
ET1=0;
init_iic(); //可以不初始化,函數(shù)已有嚴(yán)格的時序控制
Start(); //起始信號
Send(AddWr); //發(fā)送寫器件地址
Ack();
Send(add);
Ack();
Start(); //起始信號
Send(AddRd); //讀器件地址
Ack();
rdat=Read(); //讀數(shù)據(jù)
NoAck(); //好像是告訴器件接收完畢
Stop(); //停止信號
ET1=1;
return rdat;
}
/*------------------------------------------------------
讀取溫度
-------------------------------------------------------*/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
delay(50);
Init_DS18B20();
EA=0;
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
EA=1;
return(t);
}
/*----------------------------------------------------------
定時器0中斷,產(chǎn)生1Khz占空比為30%的方波
----------------------------------------------------------*/
void tm0_isr() interrupt 1
{
static j;
if(j<3)
PWM=1;
else
PWM=0;
j++;
if(j==10)
{
j=0;
}
}
/*-----------------------------------------------------------
定時器中斷
------------------------------------------------------------*/
void tm1_isr() interrupt 3 //定時掃描數(shù)碼管和溫度
{
static i,k;
unsigned char com[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; //用于控制數(shù)碼管的亮滅
TH1=(65536-1800)/256;
TL1=(65536-1800)%256;
if(i==4)
{
P2&=0x1f;
P0=0xff;
P2=Y7C;
P2&=0x1f;
P0=smg_we[i]&com[i];
P2=Y6C;
P2&=0x1f;
P0=smg_du[dat[i]]+0x80;
P2=Y7C;
P2&=0x1f;
i++;
}
else
{
P2&=0x1f;
P0=0xff;
P2=Y7C;
P2&=0x1f;
P0=smg_we[i]&com[i];
P2=Y6C;
P2&=0x1f;
P0=smg_du[dat[i]];
P2=Y7C;
P2&=0x1f;
i++;
}
if(i==8)
{
i=0;
k++;
if(k==25)
{
k=0;
flag_get=1;//標(biāo)志位有效
}
}
}
/*-----------------------------------------------------------
大約50us的延時函數(shù)
-----------------------------------------------------------*/
void deplay_50us(unsigned char t)
{
unsigned char j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
void Ad_read(void)
{
Ad_data=adc_pcf8591(0);
Ad_data=Ad_data*50/256;
}
復(fù)制代碼
Keil代碼下載:
溫度.zip
(91.34 KB, 下載次數(shù): 13)
2021-11-4 09:22 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
天眷
時間:
2021-11-24 12:34
很棒的學(xué)習(xí)資料
作者:
1602283786
時間:
2021-12-1 10:00
你好樓主,我用你的代碼在Keil 5上運行仿真錯誤好多,
對了,板子是51的
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1