1. 程式人生 > >第四屆藍橋杯比賽題目——風扇控制系統

第四屆藍橋杯比賽題目——風扇控制系統

black play 程序說明 sign 狀態機 stat mode led 可用

技術分享圖片

技術分享圖片

/*
程序說明: 第七屆省賽風扇控制系統
軟件環境: Keil uVision 4.10
硬件環境: CT107單片機綜合實訓平臺(內部晶振11.0592MHZ) STC15F2K60S2單片機
日 期: 2018-5-22
備註:不用示波器,直接用led1反應PWN波形,我習慣於一個定時器工作,如覺得有幹擾可用第二個
*/
#include <stc15f2k60s2.h>
#include <onewire.h>

typedef unsigned char u8;
typedef unsigned int u16;
/************* 宏定義 **************/
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2

/************* 本地常量聲明 **************/
u8 code t_display[]={ //標準字庫
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位碼
bit key_flag;
u8 key_scan();
u8 mode=1;
u8 set_time=0;
u8 real_time=50;
u8 smg_on[8],smg_temp[8];
u8 temperature=0;
u8 s7_count =0;

/************* 定時器初始化程序 **************/
void Timer0Init(void) //0.1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0xAE; //設置定時初值
TH0 = 0xFB; //設置定時初值
TF0 = 0; //清除TF0標誌
TR0 = 1; //定時器0開始計時
ET0 = 1;
EA = 1;
}
/************* 中斷服務程序 **************/
void timer0() interrupt 1 using 1
{
static char smg_count=0,key_count =0,i=0,pwn_count=0;//中斷溢出計數
static int time_count=0;
smg_count++;key_count++;time_count++;pwn_count++;//每進一次中斷加一,也就是計時數0.1毫秒自增1
//調用顯示模塊
if(smg_count==30) //產生3毫秒定時
{
smg_count =0;
if(s7_count==1)
{P2=0XE0;P0=~smg_temp[i];P2=0X00;}
else
{P2=0XE0;P0=~smg_on[i];P2=0X00;}
P2=0XC0;P0=T_COM[i];P2=0X00;
i++;
if(i==8)i=0;
}
//
//調用按鍵模塊
if(key_count==100)
{
key_count = 0;
key_flag = 1;
}
//倒計時發生數
if(time_count==10000)
{
time_count=0;
if(real_time>0)real_time--;
}
//pwn(脈寬調制信號)設置模塊
if(real_time!=0)
{
if(mode==1)
{
if(pwn_count==8)
{
P2=0X80;P0=~0x01;P2=0X00;
}
if(pwn_count==10)
{
P2=0X80;P0=0xff;P2=0X00;
}
}

if(mode==2)
{
if(pwn_count==7)
{
P2=0X80;P0=~0x01;P2=0X00;
}
if(pwn_count==10)
{
P2=0X80;P0=0xff;P2=0X00;
}
}

if(mode==3)
{
if(pwn_count==3)
{
P2=0X80;P0=~0x01;P2=0X00;
}
if(pwn_count==10)
{
P2=0X80;P0=0xff;P2=0X00;
}
}
}
}

/************* 主函數體 **************/
void main(void)
{
u8 key_val;
P2=0XA0;P0=0X00;P2=0X00;//關定時器
Timer0Init();//調用定時器初始化

while(1)
{
if(real_time==0){P2=0X80;P0=0Xff;P2=0X00;}//檢測是否還在定時周期中

temperature=(unsigned char)rd_temprature_f();//調用單總線

//工作計時顯示模塊
smg_on[0]=t_display[17];smg_on[1]=t_display[mode];smg_on[2]=t_display[17];smg_on[3]=t_display[16];
smg_on[4]=t_display[real_time/1000];smg_on[5]=t_display[real_time/100%10];
smg_on[6]=t_display[real_time/10%10];smg_on[7]=t_display[real_time%10];
//溫度顯示模塊
smg_temp[0]=t_display[17];smg_temp[1]=t_display[4];smg_temp[2]=t_display[17];
smg_temp[3]=t_display[16];smg_temp[4]=t_display[17];
smg_temp[5]=t_display[temperature/10];smg_temp[6]=t_display[temperature%10];smg_temp[7]=t_display[12];
//按鍵檢測
if(key_flag)
{
key_flag =0;
key_val=key_scan();
switch(key_val)
{
case 4:
mode++;//按下一次模式自增一次
if(mode==4)mode =1;
break;
case 5:
real_time = set_time; //把設定的時間賦給操作時間
set_time+=60;
if(set_time==240)set_time=0;
break;
case 6:
real_time = 0;//關閉計時
break;
case 7:
s7_count++; //記錄s7按下次數
if(s7_count==3)s7_count=1;

break;
}
}
}

}
/************* 按鍵及狀態機消抖 **************/
u8 key_scan()
{
static char key_state = key_state_0;
u8 key1,key2,key_temp,key_value=0;

P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
if(P44==0)key1=0x70;
if(P42==0)key1=0xb0;
if(P35==0)key1=0xd0;
if(P34==0)key1=0xe0;
if((P44==1)&&(P42==1)&&(P35==1)&&(P34==1))key1=0xf0;

P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
if(P33==0)key2=0x07;
if(P32==0)key2=0x0b;
if(P31==0)key2=0x0d;
if(P30==0)key2=0x0e;
if((P33==1)&&(P32==1)&&(P31==1)&&(P30==1))key2=0x0f;
key_temp = key1|key2;

switch(key_state)
{
case key_state_0:
if(key_temp!=0xff)key_state = key_state_1;
break;
case key_state_1:
if(key_temp==0xff)key_state = key_state_0;
else
{
switch(key_temp)
{
case 0x77:key_value=4;break;
case 0x7b:key_value=5;break;
case 0x7d:key_value=6;break;
case 0x7e:key_value=7;break;

case 0xb7:key_value=8;break;
case 0xbb:key_value=9;break;
case 0xbd:key_value=10;break;
case 0xbe:key_value=11;break;

case 0xd7:key_value=12;break;
case 0xdb:key_value=13;break;
case 0xdd:key_value=14;break;
case 0xde:key_value=15;break;

case 0xe7:key_value=16;break;
case 0xeb:key_value=17;break;
case 0xed:key_value=18;break;
case 0xee:key_value=19;break;

}
key_state = key_state_2;
}
break;
case key_state_2:
if(key_temp==0xff)key_state = key_state_0;
break;
}
return key_value;
}

附件(單總線協議程序)

/*
程序說明: 單總線驅動程序
軟件環境: Keil uVision 4.10
硬件環境: CT107單片機綜合實訓平臺(外部晶振12MHz) STC89C52RC單片機
日 期: 2018-5-22
*/
#include "reg52.h"

sbit DQ = P1^4; //單總線接口

//單總線延時函數
void Delay_OneWire(unsigned int t) //STC89C52RC
{
unsigned char i;
while(t--)
for(i=0;i<12;i++);
}

//通過單總線向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;
}

//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;
}








float rd_temprature_f(void)
{
unsigned int temp;
float temperature;
unsigned char low,high;

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 = high;
temp <<=8;
temp|=low;
temperature = temp*0.0625;
return temperature;

}

第四屆藍橋杯比賽題目——風扇控制系統