大家好,首先呢介紹一下自己,鄙人現大二,接觸單片機才一年時間(大佬別笑話俺 )
寒假在準備這個比賽,在最近幾天,寫了一篇關于藍橋杯單片機組第七屆省賽的編程題,
想著發個帖子望大家指點一下,自己的也留個紀念。
也是第一次發帖子,哈哈 莫名有點激動 哈哈
程序都是自己慢慢調試的,下了一番功夫,感覺受益匪淺,感觸頗多。
覺的受用的,大家互相學習,覺的有不好的地方,還望能不吝賜教,嘻嘻嘻。
好了,言歸正傳,先看程序。
批注 2020-02-19 213335.jpg (89.91 KB, 下載次數: 40)
下載附件
2020-2-19 21:33 上傳
 
主程序 main.c
/**************************************************
代碼情況
【IRC頻率】11.0592Mhz
【杜邦線】 短接P34 和P07 通過 L8代替電機 觀察pwm脈沖信號
**************************************************/
#include <STC15F2K60S2.H>
#include"smg.h"
#include"ds18b20.h"
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;
sbit PWM = P3^4;
void Keyscan(); //按鍵檢測函數
void ConfigTime0(); //配置定時函數--PWM脈沖
void SMGWorking(); //數碼管工作函數
void LedRunning(); //LED運轉函數
uchar Wind = 1 ; //風速類型狀態:1-“睡眠風”, 2-“自然風”,3-“常風”
uchar F_date = 0; //時間數據
uchar T_date = 0; //溫度數據
uchar cnt = 0; //中斷次數變量
uint t = 0; //中斷定時1s變量
bit flag = 1; //S7控制位
void main()
{
CSH(); //關閉led 蜂鳴器 繼電器
ConfigTime0();
while(1)
{
Keyscan();
SMGWorking();
LedRunning();
}
}
void SMGWorking()
{
if(flag == 0)
{
T_date = R_ds18b20();
display18B20_SMG(4 , T_date);
}
if(flag == 1)
{
displaySMG(Wind , F_date);
}
}
void LedRunning()
{
Select573(4);
if(F_date ==0) P0 = 0xFF; //放在第一個判斷句
else if(Wind == 1)
{
if(F_date>0) P0 = 0xFE;
}
else if(Wind == 2) P0 = 0xFD;
else if(Wind == 3) P0 = 0xFB;
Select573(0);
P0 = 0xFF;
}
void Keyscan()
{
if(S7 == 0)
{
delay(10);
if(S7 == 0)
{
while(!S7)
{
SMGWorking();
}
flag = ~flag;
}
}
if(S6 == 0)
{
delay(10);
if(S6 == 0)
{
while(!S6)
{
SMGWorking();
}
F_date = 0;
}
}
if(S5 == 0)
{
delay(10);
if(S5 == 0)
{
while(!S5)
{
SMGWorking();
}
if(F_date == 0) F_date = 60;
else if(F_date < 60) F_date = 120;
else if(F_date < 120) F_date = 0;
}
}
if(S4 == 0)
{
delay(10);
if(S4 == 0)
{
while(!S4)
{
SMGWorking();
}
if(Wind == 1) Wind = 2;
else if(Wind == 2) Wind = 3;
else if(Wind == 3) Wind = 1;
}
}
}
/*********************************
【函數】 定時器初始化函數
【功能】 頻率為1Khz=1ms , 定時100us , AUXR--1T,不分頻
【返回值】 無
*********************************/
void ConfigTime0() //100微秒@11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0xAE; //設置定時初值
TH0 = 0xFB; //設置定時初值
TF0 = 0; //清除TF0標志
TR0 = 1; //定時器0開始計時
ET0 = 1; //定時器0中斷打開
EA = 1; //打開總中斷
}
/*********************************
【函數】 中斷函數
【功能】 進入中斷10次為一個周期脈沖
【返回值】 無
*********************************/
void Time0() interrupt 1
{
cnt ++; t++;
if(cnt == 11) cnt = 1;
if(F_date > 0)
{
if(Wind == 1)
{
if(cnt < 3) PWM = 1;
else PWM = 0;
}
else if(Wind == 2)
{
if(cnt < 4) PWM = 1;
else PWM = 0;
}
else if(Wind == 3)
{
if(cnt < 8) PWM = 1;
else PWM = 0;
}
}
if(t == 10000) //定時1s
{
t = 0;
if(F_date > 0) F_date --;
}
}
      
底層驅動 ds18b20.c
/*
程序說明: 單總線驅動程序
軟件環境: Keil uVision 4.10
硬件環境: CT107單片機綜合實訓平臺
日 期: 2011-8-9
*/
#include "ds18b20.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 R_ds18b20()
{
unsigned char HS,LS;
unsigned int value = 0 ;
Init_DS18B20();
Write_DS18B20(0xCC); //跳過ROM
Write_DS18B20(0x44);//啟動溫度轉換
Delay_OneWire(200); //溫度轉換需要一定的時間
Init_DS18B20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE); //發送讀命令
LS = Read_DS18B20();
HS = Read_DS18B20();
value = HS; //0x00hs
value <<= 8; //0xhs00
value |= LS; //0x hs ls
value >>= 4; //0x 0h sl //取整
return value;
}
     
篇幅有限程序不全,有需求的朋友,請下載后觀看
第七屆.zip
(75.05 KB, 下載次數: 69)
2020-2-19 22:09 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|