藍橋杯第七屆省賽(單片機)_模擬風扇控制系統
題目



大家好各位,我又回來了,最近由于忙于過年和開學所以沒有時間來寫博客,不過這段時間到有空閑的時間,我會陸續的把藍橋杯單片機的博客給補上,廢話不多說,那我們開始主題吧!
這是第七屆藍橋杯單片機組的省賽題,我感覺整體的難度不大,可能有點挑戰性的就是pwm,按鍵更換模式,其他大部分考察的也就是數碼管顯示,ds18b20,按鍵和led顯示,這些都是藍橋杯的必考模塊,大部門都很簡單,只要根據平時我們所寫的模塊嵌套上去就行,
題目分析
1 數碼管顯示單元
根據題目分析,本次賽題要求我們有兩種數碼管的顯示狀況,作業模式和室溫模式兩種,其實對于兩種的數碼管狀態的顯示我們可以根據變數來進行控制與表達,例如我們設一個變數flag_smg,當flag_smg等于1時,數碼管顯示作業狀態,當flag_smg等于2時,數碼管顯示室溫狀態,這里可能講的比較簡潔,等下我會把代碼發布,到時候看代碼就比較好理解了,
2 溫度測量單元
這題比較簡單,只需要改寫底層驅動代碼(onewhile)就可以測量了,
3 按鍵控制單元
這里主要考察的是獨立按鍵,獨立按鍵比較簡單,只需要寫好相應的按鍵代碼格式就行,然后通過不同按鍵來控制不同的變數來控制溫度值的變數,
(這里的按鍵代碼格式我會在下面的代碼顯示部分表達出來,每個人有不同的獨立按鍵的模塊格式,其實原理都是一樣的)
4 LED燈顯示與pwm
led燈顯示是單片機的基礎部分比較簡單,打開鎖存器就行,而pwm與電機有關,我想等等有代碼來表示這pwm的意思,
代碼部分
time.c
# include "time.h"
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定時器時鐘12T模式
TMOD &= 0xF0; //設定定時器模式
TL0 = 0x18; //設定定時初值
TH0 = 0xFC; //設定定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
EA=ET0=1;
}
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定時器時鐘12T模式
TMOD &= 0x0F; //設定定時器模式
TL1 = 0x18; //設定定時初值
TH1 = 0xFC; //設定定時初值
TF1 = 0; //清除TF1標志
TR1 = 1; //定時器1開始計時
}
//**這里有兩個定時器,一個是Pwm的定時器,另一個是主要函式的安放的**
time.h
# ifndef _TIME_H
# define _TIME_H
# include <STC15F2K60S2.h>
void Timer0Init(void);
void Timer1Init(void);
# endif
smg.c
# include "smg.h"
unsigned char tab[13]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0XC6};
unsigned char dspbuf[8]={10,10,10,10,10,10,10,10};
void smg_display(void)
{
static unsigned char i;
P0=0XFF;
P2&=0X1F;
P2=0XE0;
P2&=0X1F;
P0=(0X01<<i);
P2&=0X1F;
P2=0XC0;
P2&=0X1F;
P0=tab[dspbuf[i]];
P2&=0X1F;
P2=0XE0;
P2&=0X1F;
if(++i==8)
i=0;
}
smg.h
# ifndef _SMG_H
# define _SMG_H
# include <STC15F2K60S2.H>
void smg_display(void);
extern unsigned char dspbuf[8];
# endif
key.c
# include "key.h"
unsigned char key_value;
void key_read(void)
{
static unsigned char i;
if(P30!=1||P31!=1||P32!=1||P33!=1)
{
i++;
if(i==1)
{
if(P30!=1)
key_value=1;
if(P31!=1)
key_value=2;
if(P32!=1)
key_value=3;
if(P33!=1)
key_value=4;
}
else if(++i>=33)
{
i=0;
key_value=0;
}
}
else
i=0;
}
key.h
# ifndef _KEY_H
# define _KEY_H
# include <STC15F2K60S2.H>
void key_read(void);
extern unsigned char key_value;
# endif
ds18b20.c
#include "ds18b20.h"
sbit DQ = P1^4; //單總線介面
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
//單總線延時函式
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t*=12;
while(t--);
}
//通過單總線向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;
}
unsigned int ds18b20_read(void)
{
unsigned char TL,TH;
unsigned int dat;
init_ds18b20();
Delay1ms();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
init_ds18b20();
Delay1ms();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);
TL=Read_DS18B20();
TH=Read_DS18B20();
dat=((TH<<8)|TL);
dat*=0.0625;
return dat;
}
ds18b20.h
# ifndef _DS18B20_H
# define _DS18B20_H
# include <STC15F2K60S2.H>
unsigned int ds18b20_read(void);
# endif
other.c
# include "other.h"
void led1_on(void)
{
P2=(P2&0X1F)|0X80;
P0=0XFE;
P2&=0X1F;
}
void led2_on(void)
{
P2=(P2&0X1F)|0X80;
P0=0XFD;
P2&=0X1F;
}
void led3_on(void)
{
P2=(P2&0X1F)|0X80;
P0=0XFB;
P2&=0X1F;
}
void led_off(void)
{
P2=(P2&0X1F)|0X80;
P0=0XFF;
P2&=0X1F;
}
other.h
# ifndef _OTHER_H
# define _OTHER_H
# include <STC15F2K60S2.H>
void led1_on(void);
void led2_on(void);
void led3_on(void);
void led_off(void);
# endif
main.c
# include <STC15F2K60S2.H>
# include "time.h"
# include "smg.h"
# include "key.h"
# include "ds18b20.h"
# include "other.h"
unsigned char key_allow;
unsigned char work_value;
unsigned char flag_led;
unsigned char mode;
unsigned char add_time;
unsigned char temp;
unsigned char time;
unsigned char k7_count;
unsigned char flag_smg;
unsigned char flag_time;
unsigned char flag_count_down;
unsigned char pwm;
void allinit(void)
{
P0=0X00;
P2&=0X1F;
P2=0XA0;
P2&=0X1F;
P0=0XFF;
P2&=0X1F;
P2=0X80;
P2&=0X1F;
}
void main (void)
{
allinit();
Timer0Init();
Timer1Init();
while(1)
{
/**********************key**********************/
if(key_allow==1)
{
key_allow=0;
key_read();
}
if(key_value==4) //s4
{
key_value=0;
if(++work_value==4) //按鍵回圈更改模式
work_value=1;
switch(work_value)
{
case 1:
flag_led=1;
pwm=20;
mode=1;
break;
case 2:
flag_led=2;
pwm=30;
mode=2;
break;
case 3:
flag_led=3;
pwm=70;
mode=3;
break;
}
}
if(key_value==3) //s5
{
key_value=0;
if(++add_time==4)
add_time=1;
switch(add_time)
{
case 1:
time=0;
break;
case 2:
time+=60;
flag_led=mode;
break;
case 3:
time+=60;
flag_led=mode;
break;
}
if(time>180)
time=0;
}
if(key_value==2) //s6
{
key_value=0;
add_time=1;
time=0;
flag_led=0;
pwm=0;
}
if(key_value==1) //s7
{
key_value=0;
mode=4;
if(k7_count^=1)
flag_smg=1;
else
flag_smg=0;
}
/******************count down***********************/
if(time==0)
flag_count_down=0;
else
flag_count_down=1;
if(flag_time==1)
{
flag_time=0;
if(--time<0)
{
time=0;
flag_led=0;
}
}
/************************ds18b20************************/
temp=ds18b20_read();
/************************SMG**************************/
if(flag_smg==1) //室溫
{
dspbuf[0]=10;
dspbuf[1]=4;
dspbuf[2]=10;
dspbuf[3]=11;
dspbuf[4]=11;
dspbuf[5]=temp/10;
dspbuf[6]=temp%10;
dspbuf[7]=12;
}
if(flag_smg==0) //作業模式
{
dspbuf[0]=10;
dspbuf[1]=mode;
dspbuf[2]=10;
dspbuf[3]=11;
dspbuf[4]=0;
dspbuf[5]=time/100;
dspbuf[6]=time%100/10;
dspbuf[7]=time%10;
}
}
}
void time0(void) interrupt 1
{
static unsigned char key_times;
static unsigned int flag_1s_time;
if(++key_times==30)
{
key_times=0;
key_allow=1;
}
if(flag_count_down==1)
{
if(++flag_1s_time==1000)
{
flag_1s_time=0;
flag_time=1;
}
}
/*********************LED*************************/
if(flag_led==1)
{
led1_on();
}
if(flag_led==2)
{
led2_on();
}
if(flag_led==3)
{
led3_on();
}
if(flag_led==0)
{
led_off();
}
smg_display();
}
void time1(void) interrupt 3
{
static unsigned char fre=0;
if(fre<pwm)
P34=1;
else
P34=0;
if(++fre==100)
fre=0;
}
結語
其實這道題的難度不是很大,大家只要認真的做這道題大部分還是可以做出來的,
我最近也看了一些大佬的文章,感覺自己的代碼還是有許多問題,比如代碼過長,不簡便,所以,我認為我自己還是要好好學習,也感謝大家的觀看,如果你認為可以的話可以收藏一下哦(⊙o⊙)!實在不行也給個贊( ̄▽ ̄)"吧!謝謝大家,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/266004.html
標籤:其他
上一篇:排序演算法之快速排序的優化
