【藍橋杯單片機組第六屆模擬題】— “簡易溫度採集與控制裝置”設計任務書

1、試題

(1)功能簡述

   模擬“溫度採集與控制裝置” 用於實現溫度的實時監測與控制。單片機採集 DS18B20溫度傳感器的輸出信號, 並送到數碼管進行顯示; 通過傳感器得到的溫度數據將與用戶設定溫度上限、下限值做比較, 再由單片機啓動控制或報警電路。系統硬件部分主要由單片機最小系統、數碼管顯示、 DS18B20 溫度傳感器、矩陣鍵盤等模塊組成。 系統組成框圖如圖1所示:

(2)設計任務及要求

  1. 溫度檢測

   溫度檢測採用 DS18B20 溫度傳感器, 數據經過單片機處理後,與用戶設定的溫度上限(TMAX)和溫度下限(TMIN)比較,確定當前溫度所處的區間, 數碼管溫度顯示格式如圖 2 所示:

   關於溫度區間的說明:

    溫度區間 0: 當前溫度<TMIN
    溫度區間 1: TMIN≤當前溫度≤TMAX
    溫度區間 2: 當前溫度>TMAX
    可設定的最大溫度區間: 0℃~99℃

  2. 用戶輸入-3X4 矩陣鍵盤
   通過矩陣鍵盤設定系統的工作參數,各個按鍵的功能定義如圖 3 所示:

   “設置”按鍵按下後,進入工作參數設定界面,如圖 4 所示, 依次按下設定的數值,再次按下“設置” 按鍵, 保存當前輸入的數據,並退出工作參數設定界面。

   以設定 TMAX 爲 35 攝氏度, TMIN爲 25 攝氏度爲例說明參數設定過程:按下“設置”按鍵,然後依次按下數字按鍵“3” “5” “2” “5” 如圖 5 所示,再次按下“設置” 按鍵, 完成參數設定, 並退出參數設定界面。在輸入過程中,按下“清除” 按鍵, 將清除當前輸入數據, 若設定工作參數錯誤,如 TMAX<TMIN, L2 常亮,修正錯誤設定並保存參數後, L2 熄滅。

  3. 執行機構
  執行機構由指示燈 L1 和繼電器組成,用於報警和連接外部高低溫執行機構。
  3.1 實時溫度處在溫度區間 0, 繼電器關閉,指示燈 L1 以 0.8 秒爲間隔閃爍;
  3.2 實時溫度處在溫度區間 1, 繼電器關閉,指示燈 L1 以 0.4 秒爲間隔閃爍;
  3.3 實時溫度處在溫度區間 2, 繼電器打開,指示燈 L1 以 0.2 秒爲間隔閃爍。
  4. 初始化狀態說明
  系統默認的溫度上限(TMAX)爲 30℃, 溫度下限(TMIN)爲 20℃, 可以通過矩陣鍵盤修改

(3)軟、硬件統調

  將編譯通過的程序下載到單片機芯片中,進行軟、硬件統調。
  1. 系統初始化狀態正確;
  2. 數碼管顯示功能,界面設計滿足題目要求;
  3. 繼電器控制功能實現,無誤動作;
  4. LED 閃爍控制功能實現;
  5. 溫度測量功能;
  6. 矩陣鍵盤參數設定功能實現 。

2、試題分析

對於溫度傳感器來說:

unsigned char get_wendu(){
unsigned char temp,high,low;

Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);

Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);

low=Read_DS18B20();
high=Read_DS18B20();

temp=(low>>4)|(high<<4);

return temp;
}

一些寄存器相關說明。可參考:

https://blog.csdn.net/fanjufei123456/article/details/104443872

對於矩陣按鍵來說:

//定義r爲行,c爲列,如果r1=0,c1=0,按鍵則爲第一行第一列,其餘同理;
sbit r1=P3^0;
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;
sbit c1=P4^4;
sbit c2=P4^2;
sbit c3=P3^5;
sbit c4=P3^4;

注意按鍵端口表示方法,可參考:

https://blog.csdn.net/fanjufei123456/article/details/104263738

3、全部代碼

 text.c
 

#include<stc15f2k60s2.h>
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int

void delay();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);
void allinit();
void key_scan();
void Time0_init();
void delayms(uchar ms);

sbit r1=P3^0;
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;
sbit c1=P4^4;
sbit c2=P4^2;
sbit c3=P3^5;
sbit c4=P3^4;

sbit led_light=P0^0;

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};

uchar tmin=20;
uchar tmax=30;
uchar mode_1=0;  //溫度顯示桌面
uchar wendu=0;   //實時溫度顯示
uchar f1,f2,f3,f4,f5,f6,f7,f8;
uint count=0;
uchar clean=0;
uchar led1=0;
uchar flag=0;
uchar num=0;

void main(){
allinit();
Time0_init();
ET0=1;
EA=1;
while(1)
{
   key_scan();
   if(mode_1==0)
   {
     wendu=get_wendu();
     if(wendu<tmin)
	 {
	   led1=0;
	   f1=10;f2=0;f3=10;f4=11;f5=11;f6=11;f7=wendu/10;f8=wendu%10;
	 }
	 else if((wendu>=tmin)&&(wendu<=tmax))   
	 {
	   led1=1;
	   f1=10;f2=1;f3=10;f4=11;f5=11;f6=11;f7=wendu/10;f8=wendu%10;
	 }
	 else if(wendu>tmax)
	 {
	   led1=2;
	   f1=10;f2=2;f3=10;f4=11;f5=11;f6=11;f7=wendu/10;f8=wendu%10;
	 }
   }

   else if(mode_1==1)
   {
     if(clean==1)
	 {
	   clean=0;
       f1=10;f2=11;f3=11;f4=11;f5=11;f6=10;f7=11;f8=11;
	 }
	 if((f2==11)&&(flag==1))
	 {
	    flag=0;
	    f2=num;
	 }
	 else if((f3==11)&&(flag==1))
	 {
	    flag=0;
		f3=num;
	 }
	 else if((f7==11)&&(flag==1))
	 {
	    flag=0;
		f7=num;
	 }
	 else if((f8==11)&&(flag==1))
	 {
	    flag=0;
		f8=num;

	   if((f2*10+f3)<(f7*10+f8))
	   {
	      f1=10;f2=11;f3=11;f4=11;f5=11;f6=10;f7=11;f8=11;
		  P2=0X80;
		  P0=0XFD;
	   }
     }
}
  
   display12(f1,f2);
   display34(f3,f4);
   display56(f5,f6);
   display78(f7,f8);
}
}



void key_scan(){
r1=1;r2=1;r3=1;r4=1;
c1=0;c2=1;c3=1;c4=1;
if(!r1)
{
delayms(5); 
{
   num=0;
   flag=1;
}
while(!r1);
}

else if(!r2)
{
   delayms(5);
{
   num=3;
   flag=1;
}
while(!r2);
}

else if(!r3) 
{
  delayms(5);
{
   num=6;
   flag=1;
}
while(!r3);
}
 
else if(!r4)
{
   delayms(5); 
{
   num=9;
   flag=1;
}
while(!r4);
}


r1=1;r2=1;r3=1;r4=1;
c1=1;c2=0;c3=1;c4=1;
if(!r1)
{
delayms(5);
{
   num=1;
   flag=1;
}
while(!r1);
}
else if(!r2)
{
   delayms(5);
{
   num=4;
   flag=1;
}
while(!r2);
}

else if(!r3)
{
  delayms(5);
{
   num=7;
   flag=1;
}
while(!r3);
}
else if(!r4)
{
 delayms(5);
{
 if(mode_1==0)
 {
    mode_1=1;
	EA=0;
	ET0=0;
	P2=0X80;P0=0XFF;
	P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
	f1=10;f2=11;f3=11;f4=11;f5=11;f6=10;f7=11;f8=11;
 }
 else if(mode_1==1)
 {
    mode_1=0;
	EA=1;ET0=1;
	P2=0X80;P0=0XFF;
	tmin=f7*10+f8;
	tmax=f2*10+f3;
 }

}
while(!r4);
}

r1=1;r2=1;r3=1;r4=1;
c1=1;c2=1;c3=0;c4=1;
if(!r1)
{
delayms(5);
{
  num=2;
  flag=1;
}
while(!r1);
}
else if(!r2)
{
delayms(5);
{
  num=5;
  flag=1;
}
while(!r2);
}
else if(!r3)
{
delayms(5);
{
  num=8;
  flag=1;
}
while(!r3);
}
else if(!r4)
{
  delayms(5);
{
  clean=1;
}
while(!r4);
}

}


void delay(){
uchar i,j;
for(i=10;i>0;i--)
for(j=200;j>0;j--);
}

void allinit(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void display12(uchar f1,uchar f2){
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delay();
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delay();
}

void display34(uchar f3,uchar f4){
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delay();
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delay();
}

void display56(uchar f5,uchar f6){
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delay();
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delay();
}

void display78(uchar f7,uchar f8){
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delay();
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delay();
}

void Time0_init(){
TMOD=0x01;
TH0=(65536-10000)/256;	//10000us=10ms=0.01s
TL0=(65536-10000)%256;
TR0=1;
}

void Time0_service() interrupt 1
{
TH0=(65536-10000)/256;	//10000us=10ms=0.01s
TL0=(65536-10000)%256;
count++;
if(led1==0)
{
  {
    P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
  }
   if(count==80)
   {
     count=0;
	 led_light=~led_light;	 
   }
   
}

if(led1==1)
{
   {
    P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
   }
   if(count==40)
   {
      count=0;
      led_light=~led_light;
   }
}

if(led1==2)
{
   {
    P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
   }
   if(count==20)
   {
      count=0;
	  led_light=~led_light;
   }
}
}

void delayms(uchar ms){
uchar i,j,k;
for(k=ms;k>0;k--)
{
   i=12;
   j=169;
   do
   {
     while(j--);
   }
   while(i--);
}
}	 

 onewire.c

#include "onewire.h"

//單總線延時函數
void Delay_OneWire(unsigned int t)
{
  t=t*12;
  while(t--);
}

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(12);
	DQ = 0;
	Delay_OneWire(80); 
	DQ = 1;
	Delay_OneWire(10); 
	initflag = DQ;    
	Delay_OneWire(5);
  
	return initflag;
}

//通過單總線向DS18B20寫一個字節
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//從DS18B20讀取一個字節
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

unsigned char get_wendu(){
unsigned char temp,high,low;

Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);

Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);

low=Read_DS18B20();
high=Read_DS18B20();

temp=(low>>4)|(high<<4);

return temp;
}

 onewire.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include "stc15f2k60s2.h"

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//IC引腳定義
sbit DQ = P1^4;

//函數聲明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char get_wendu();

#endif

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章