前言
上期我們學(xué)習(xí)了NE555方波發(fā)生器&頻率測量,講到我會更新之后省賽的題目,那么,他來了。
首先聲明:我還沒有參加藍(lán)橋杯單片機(jī)比賽,也沒有拿過獎,所以我寫的代碼注定不會那么完美,存在BUG是必然的,我寫這個系列的目的純粹是為了記錄我的學(xué)習(xí)…………
任務(wù)要求
1.基本要求
2.競賽板配置要求
3.硬件框圖
4.功能描述
關(guān)于功能描述,我只想說是真的多,第一次寫,花了我快一天的時間,但好在功能大部分已經(jīng)實現(xiàn)完全了,不說了,看吧…………
看到這里,說明你是一個有耐心的人,那么作為一個有耐心的人,我覺得你一定能繼續(xù)看下去的,下面,未來講一下我的代碼實現(xiàn)思路。
實現(xiàn)思路
首先我們拿到題目,必須要大概的看一遍,明確用到了那些模塊,一些大概的要求什么的,重點要完成哪些部分。
【1】編寫一些基本的函數(shù)內(nèi)容,完成相關(guān)外設(shè)的初始化。
【2】完成數(shù)碼管顯示相關(guān)變量的各個頁面,
【3】定義變量,實現(xiàn)數(shù)碼管顯示頁面和顯示內(nèi)容的改變
【4】 按照任務(wù)要求在此基礎(chǔ)上不斷的修正代碼結(jié)構(gòu)框架
【5】檢驗代碼的可行性,不斷的DeBug…………
具體代碼框架如下:
可能光看這個圖會顯得有些抽象,不知道在寫什么,所以我們來嘗試加上代碼一起理解。文章來源:http://www.zghlxwxcb.cn/news/detail-736064.html
代碼實現(xiàn)
1.main.C
#include <STC15F2K60S2.H>
#include "LS138.h"
#include "Key.h"
#include "ds1302.h"
#include "onewire.h"
unsigned int Mode = 1;
struct Environment
{
unsigned int Tempreature; //定義溫度變量
unsigned int Tempreature_Set; //定義溫度設(shè)置值
unsigned int Key_Vlaue; //定義按鍵值
unsigned int Time_Show_Mode; //定義時間顯示模式
unsigned int Control_Mode; //定義溫度/時間控制模式
unsigned char Relay_Flag; //定義繼電器狀態(tài)
unsigned int LED0_Flag ; //定義LED0/L1狀態(tài)
unsigned int LED2_Flag ; //定義LED1/L2狀態(tài)
unsigned long int Tick; //定義時間值/tick為一天過了多少秒
}E1;
void Timer_Init(void)
{
ET1 = 1;
TMOD = 0x00;
TH1 = 0xFC;
TL1 = 0x18;
EA = 1;
TR1 = 1;
}
void Environment_Init(void)
{
E1.Tempreature = 235;
E1.Tempreature_Set = 230;
E1.Key_Vlaue = 0;
E1.Relay_Flag = 0;
E1.Tick = 3595;
E1.Time_Show_Mode = 1;
E1.Control_Mode = 1;
E1.LED0_Flag = 0;
E1.LED2_Flag = 0;
}
void Init(void)
{
Environment_Init();
LS_Init();
DS1302_Write_Time(E1.Tick);
Timer_Init();
}
void SEG_Task(void)
{
switch(Mode)
{
case 1: SEG_Page1(E1.Tempreature);
break;
case 2: SEG_Page2(E1.Time_Show_Mode,E1.Tick);
break;
case 3: SEG_Page3(E1.Tempreature_Set);
break;
}
}
void Key_Task(void)
{
E1.Key_Vlaue = KeyScan();
if(E1.Key_Vlaue == 12)
{
Mode++;
if(Mode >3)
{
Mode = 1;
}
}
if(E1.Key_Vlaue == 13)
{
E1.Control_Mode ++;
if(E1.Control_Mode >=3)
{
E1.Control_Mode = 1;
}
}
if(E1.Control_Mode == 1)
{
if(E1.Tempreature > E1.Tempreature_Set)
{
Relay_Control(1);
E1.LED2_Flag = 1;
}
else
{
Relay_Control(0);
E1.LED2_Flag = 0;
}
}
if(E1.Control_Mode == 2)
{
if(E1.Tick % 3600 == 0 )
{
E1.Relay_Flag = 1;
E1.LED2_Flag = 1;
}
if(E1.LED0_Flag == 1)
{
LED_Write(0xFE);
}
else
{
LED_Write(0xFF);
}
}
if(E1.Tick % 3600 == 0 )
{
E1.LED0_Flag = 1;
}
if(E1.LED0_Flag == 1)
{
LED_Write(0xFE);
}
if(E1.LED0_Flag == 0)
{
LED_Write(0xFF);
}
if(Mode == 3)
{
if(E1.Key_Vlaue == 16)
{
E1.Tempreature_Set = E1.Tempreature_Set + 10;
if(E1.Tempreature_Set > 999)
{
E1.Tempreature_Set = 999;
}
}
if(E1.Key_Vlaue == 17)
{
E1.Tempreature_Set = E1.Tempreature_Set - 10;
if(E1.Tempreature_Set < 100)
{
E1.Tempreature_Set = 100;
}
}
}
if(Mode == 2)
{
if(E1.Key_Vlaue == 17)
{
E1.Time_Show_Mode++;
}
}
}
void main()
{
Init();
while(1)
{
E1.Tempreature = DS_Read_Tempreatur();
E1.Tick = DS1302_Read_Time();
SEG_Task();
Key_Task();
}
}
void Timer0_Handler() interrupt 3
{
static unsigned int Timer1_Count = 0;
static unsigned int Relay_Count = 0;
static unsigned int LED0_Count = 0;
static unsigned int LED2_Count = 0;
Timer1_Count++;
if(E1.Control_Mode == 1)
{
if(E1.LED0_Flag == 1)
{
LED_Write(0xFC);
}
else
{
LED_Write(0xFD);
}
}
if(Timer1_Count % 100 == 0)
{
if(E1.LED2_Flag == 1)
{
LED2_Count++;
if(LED2_Count%2)
{
LED_Write(0xFB);
}
else
{
LED_Write(0xFF);
}
}
}
if(Timer1_Count >= 1000)
{
Timer1_Count = 0;
if(E1.Relay_Flag == 1)
{
Relay_Count++;
if(Relay_Count < 5)
{
Relay_Control(1);
}
else
{
Relay_Count = 0;
E1.Relay_Flag = 0;
E1.LED2_Flag = 0;
Relay_Control(0);
}
}
if(E1.LED0_Flag == 1)
{
LED0_Count++;
if(LED0_Count >= 6)
{
LED0_Count = 0;
E1.LED0_Flag = 0;
}
}
}
}
LS138.h
#ifndef _LS138_H_
#define _LS138_H_
#include <STC15F2K60S2.H>
sbit LS_A = P2^5;
sbit LS_B = P2^6;
sbit LS_C = P2^7;
void LS_Init(void);
void LS138_Set(unsigned int dat);
void LS138_Clear(void);
void DelayXms(unsigned int x);
void LED_Control(unsigned int Flag);
void LED_Write(unsigned char dat);
void BEEP_Control(unsigned int Flag);
void Relay_Control(unsigned int Flag);
void SEG_Write(unsigned char pos, unsigned char dat);
void SEG_Page1(unsigned int tempreature);
void SEG_Page2(unsigned int Flag,unsigned long int Tick);
void SEG_Page3(unsigned int tempreature);
#endif
LS138.C
#include "LS138.h"
// 0 1 2 3 4 5 6 7 8 9
unsigned char code SEG_Index[25] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
/* 0. 1. 2. ………… 9.*/
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,
/* U - */
0xc1,0xbf};
void LS_Init(void)
{
BEEP_Control(0);
Relay_Control(0);
LED_Control(0);
LED_Write(0xFF);
}
void LS138_Set(unsigned int dat)
{
switch(dat)
{
case 0: LS_A = 0; LS_B = 0; LS_C = 0;
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4: LS_A = 0; LS_B = 0; LS_C = 1;
break;
case 5: LS_A = 1; LS_B = 0; LS_C = 1;
break;
case 6: LS_A = 0; LS_B = 1; LS_C = 1;
break;
case 7: LS_A = 1; LS_B = 1; LS_C = 1;
break;
}
}
void LS138_Clear(void)
{
LS_A = 0; LS_B = 0; LS_C = 0;
}
void DelayXms(unsigned int x) //@12.000MHz
{
unsigned char i, j,k;
for(k=0;k<x;k++)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
void LED_Control(unsigned int Flag)
{
if(Flag == 1)
{
LS138_Clear();
LS138_Set(4);
P0 = 0x00;
LS138_Clear();
}
else
{
LS138_Clear();
LS138_Set(4);
P0 = 0xFF;
LS138_Clear();
}
}
void LED_Write(unsigned char dat)
{
LS138_Clear();
LS138_Set(4);
P0 = dat;
LS138_Clear();
}
void BEEP_Control(unsigned int Flag)
{
if(Flag == 1)
{
LS138_Clear();
LS138_Set(5);
P0 = 0x40;
LS138_Clear();
}
else
{
LS138_Clear();
LS138_Set(5);
P0 = 0x00;
LS138_Clear();
}
}
void Relay_Control(unsigned int Flag)
{
if(Flag == 1)
{
LS138_Clear();
LS138_Set(5);
P0 = 0x10;
LS138_Clear();
}
else
{
LS138_Clear();
LS138_Set(5);
P0 = 0x00;
LS138_Clear();
}
}
void SEG_Write(unsigned char pos, unsigned char dat)
{
LS138_Set(7);
P0 = SEG_Index[dat];
LS138_Clear();
LS138_Set(6);
P0 = 0x01 << pos;
LS138_Clear();
LED_Control(0);
DelayXms(1);
}
void SEG_Page1(unsigned int tempreature)
{
SEG_Write(0,20);
SEG_Write(1,1);
SEG_Write(5,tempreature/100%10);
SEG_Write(6,tempreature/10%10 + 10);
SEG_Write(7,tempreature %10);
}
void SEG_Page2(unsigned int Flag,unsigned long int Tick)
{
SEG_Write(0,20);
SEG_Write(1,2);
SEG_Write(5,21);
if(Flag % 2)
{
SEG_Write(3,Tick/3600/10%10);
SEG_Write(4,Tick/3600%10);
SEG_Write(6,Tick/3600/60/10%10);
SEG_Write(7,Tick/3600/60%10);
}
else
{
SEG_Write(3,Tick/3600/60/10%10);
SEG_Write(4,Tick/3600/60%10);
SEG_Write(6,Tick%60/10%10);
SEG_Write(7,Tick%60%10);
}
}
void SEG_Page3(unsigned int tempreature)
{
SEG_Write(0,20);
SEG_Write(1,3);
SEG_Write(6,tempreature/100%10);
SEG_Write(7,tempreature/10%10);
}
Key.C
#include "Key.h"
unsigned int KeyScan(void)
{
static unsigned char cnt = 0, //continue value
last_trg = 0; //last trigger value
unsigned char trg = 0, //trigger value
cur = 0, //current value
value = 3, //必須初始化為3
key_x = 0,
key_y = 0;
P3 = 0x0f;
P4 = 0x00;
if(!P30) key_x = 3; //獲取X軸坐標(biāo)
else if(!P31) key_x = 2;
else if(!P32) key_x = 1;
else if(!P33) key_x = 0;
P3 = 0xf0;
P4 = 0xff;
if(!P34) key_y = 4; //獲取Y軸坐標(biāo)
else if(!P35) key_y = 3;
else if(!P42) key_y = 2;
else if(!P44) key_y = 1;
cur = key_y^0;
trg = cur^cnt & cur;
cnt = cur;
if((last_trg ^ trg & last_trg) && cur)
{
//計算矩陣按鍵的鍵值
value = key_x + key_y * 4;
}
last_trg = trg;
return value; //返回獨立按鍵的鍵值
}
Key.h這里就不寫了,里面也沒啥,就是一個KeyScan函數(shù)的聲明
溫度讀取函數(shù)
unsigned int DS_Read_Tempreatur(void)
{
unsigned int dat =0;
unsigned char HSB,LSB;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
LSB = Read_DS18B20();
HSB = Read_DS18B20();
init_ds18b20();
dat = (HSB << 8) | LSB ;
if((dat & 0xF800) == 0x0000)
{
dat = (dat >> 4) * 10 ;
dat =dat + (LSB & 0x0F) * 0.625 ;
return dat ;
}
return dat ;
}
DS1302時間寫入函數(shù)
void DS1302_Write_Time(unsigned long int Tick)
{
unsigned char sec,min,hour;
sec = Tick % 60;
sec = (sec/10 * 16) +( sec %10);
min = Tick / 60;
min = (min/10 * 16) +( min %10);
hour = Tick / 3600;
hour = (hour/10* 16) +( hour %10);
Write_Ds1302_Byte(0x8E,0x00);
Write_Ds1302_Byte(0x80,sec);
Write_Ds1302_Byte(0x82,min);
Write_Ds1302_Byte(0x84,hour);
Write_Ds1302_Byte(0x8E,0xFF);
}
DS1302時間讀取函數(shù)
unsigned long int DS1302_Read_Time(void)
{
unsigned long int tick = 0;
unsigned char sec,min,hour;
sec = Read_Ds1302_Byte(0x81);
min = Read_Ds1302_Byte(0x83);
hour = Read_Ds1302_Byte(0x85);
sec =(sec /16 * 10) + sec %16;
min =(min /16 * 10) + min %16;
hour =(hour /16 * 10) + hour %16;
tick = hour * 3600 + min * 60 + sec;
return tick;
}
關(guān)于DS1302和DS18B20的底層驅(qū)動函數(shù),我就不貼出來了,官方會提供的,我前面幾期的博客里面也有,需要的可以自己去看看。
總結(jié)
- 這一次的省賽題總體來說還算是比較正常的,我也完成了七七八八,但沒有完全完成,畢竟我只是個菜鳥,能不能拿獎還是未知呢…………
- 通過這次的實踐,我也發(fā)現(xiàn)了許多的問題,我發(fā)現(xiàn)我寫的代碼存在可優(yōu)化的地方,許多模塊一起使用的話,會存在互相干擾的問題,針對這些問題,我也在想辦法,希望在比賽前解決掉這些問題吧。
- 不出意外的話,下一期會更新12屆省賽題目的代碼。
存在的問題
- 調(diào)用數(shù)碼管顯示函數(shù)的時候,LED不受控制,時不時的亂跳,關(guān)于這個BUG,我想了好久,但是還是沒法解決,所以我只能通過程序控制,把影響盡可能地減小,希望哪位大神來解答一下我的疑惑。
- 關(guān)于矩陣按鍵的掃描函數(shù),我用的是我們老師提供的代碼,因為我發(fā)現(xiàn)我之前寫的代碼存在使用過程中會影響其他外設(shè)正常工作,容易誤觸發(fā)等問題,而且我們老師提供的代碼出奇的好用(我們老師就是厲害)。但是我還是沒看懂原理,同樣希望哪位大佬可以幫我解釋一些。
你都看到這里了,說明你是一個很有耐心的人,那么這個有耐心的陌生人,能支持我一下嗎?文章來源地址http://www.zghlxwxcb.cn/news/detail-736064.html
到了這里,關(guān)于藍(lán)橋杯單片機(jī)學(xué)習(xí)14——第十三屆省賽題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!