【第十四屆藍(lán)橋杯單片機(jī)沖刺版】
明天就是正式比賽啦,今天可以在把各個(gè)模塊練習(xí)一遍,??嫉耐庠O(shè)相關(guān)代碼一定要熟練哦。
比賽時(shí)拿到資料包了,檢查驅(qū)動(dòng)文件,使用到的驅(qū)動(dòng)文件,自己做相應(yīng)的修改,確保是能夠正常使用(驅(qū)動(dòng)修改相關(guān)可看之前的文章)。
下面是自己將??嫉耐庠O(shè)結(jié)合一起的練習(xí),需要完整工程的自取哈
鏈接:https://pan.baidu.com/s/1yc-GG_hqpqU5qzTsA8UOtA?pwd=l99q
提取碼:l99q
--來(lái)自百度網(wǎng)盤(pán)超級(jí)會(huì)員V5的分享
祝大家都可以取得好成績(jī),有幫助就給個(gè)贊和關(guān)注吧
功能說(shuō)明
下面練習(xí)中結(jié)合了溫度采集、adc采集、時(shí)鐘顯示、超聲波、頻率測(cè)試、獨(dú)立按鍵,矩陣按鍵、串口接收串口發(fā)送、長(zhǎng)按等相關(guān)操作。
按鍵操作:
S4作為界面和模式切換(溫度、電壓、時(shí)間、距離)
S5 作為長(zhǎng)按(第一次長(zhǎng)按關(guān)閉LED顯示第二次長(zhǎng)按打開(kāi))
S6 作為長(zhǎng)按(第一次長(zhǎng)按關(guān)閉數(shù)碼管顯示第二次打開(kāi))
S7 作為向串口發(fā)送按鍵,會(huì)將當(dāng)前界面的數(shù)據(jù)發(fā)送到串口
串口操作:
通過(guò)串口中斷接收 字符A B C D 分別進(jìn)行溫度、電壓、時(shí)間、距離界面和模式的切換并將當(dāng)前界面數(shù)據(jù)發(fā)送到PC
定時(shí)器分配:
定時(shí)器1:一般用來(lái)做串口
定時(shí)器2:數(shù)碼管以及一些頻率變量刷新操作
定時(shí)器0:超聲波或者頻率
#include <STC15F2K60S2.H>
#include "iic.h"
#include "onewire.h"
#include "ds1302.h"
/*========================十四屆藍(lán)橋杯單片機(jī)考前一天沖刺=========================
@Author:小殷
@Date:2023.4.7
================================================================================*/
sbit TX = P1^0;
sbit RX = P1^1;
typedef unsigned char uchar;
typedef unsigned int uint;
#define Control_Port(x,y) P0 = y;P2 = x;P2 = 0
//=======================下面為變量定義==========================
uchar smg_data[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1,0xbf};
uchar smg_bit[9] = {10,10,10,10,10,10,10,10,10}; //數(shù)碼管初始化全熄滅
uchar L[5]; //LED操作
uchar interface = 1; //界面
static uchar hour = 0,min= 0,sec = 0; //時(shí)分秒
static uint Temperature = 0; //溫度
static uint adc_volt = 0; //電壓
static uchar key_feq = 0; //按鍵刷新頻率
static uchar adc_feq = 0; //adc采集頻率
static uchar t_feq = 0; //溫度刷新頻率
static uchar dis_feq = 0; //距離刷新頻率
static uchar smg_flag =1; //數(shù)碼管打開(kāi)關(guān)閉標(biāo)志
static uchar led_flag =1; //led打開(kāi)關(guān)閉標(biāo)志
static uchar send_data_flag = 0; //按鍵發(fā)送
static uint distance = 0; //距離
uchar usart_cmd = 0; //串口接收指令緩存
//=======================下面為函數(shù)聲明===========================
void Timer2Init(void); //1毫秒@12.0定時(shí)器2初始化
void Delay5ms(); //@12.000MHz 5ms延時(shí)
void UartInit(void); //9600bps@12.000MH串口初始化
void Send_Byte(uchar dat); //發(fā)送一個(gè)字節(jié)
void Send_String(uchar *str); //發(fā)送字符串
void Delay12us(); //@12.000MHz 12us
void Send_Wave(void); //發(fā)波8個(gè)40khz
uint Get_Distance(void); //獲取距離
void Set_DS1302_Timer(uchar hour,uchar min,uchar sec); //設(shè)置ds1302時(shí)間
float Read_Temperature(void); //溫度獲取
uchar Read_Key_Value(void); //鍵值獲取
uchar Read_ADC_Value(uchar addr); //ADC獲取
void Data_Tackle_Task(void); //數(shù)據(jù)處理任務(wù)
void Key_Tackle_Task(void); //按鍵處理任務(wù)
void SMG_Display_Task(void); //數(shù)碼管處理任務(wù)
void Init_System(void); //系統(tǒng)初始化
void Send_Data(uchar interface); //發(fā)送數(shù)據(jù) 串口相關(guān)
void Send_Volt(void); //發(fā)送電壓
void Send_Temperature(void); //發(fā)送溫度
void Send_Timer(void); //發(fā)送時(shí)間
void Send_Distance(void); //發(fā)送距離
//========================下面為函數(shù)實(shí)現(xiàn)==========================
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定時(shí)器時(shí)鐘1T模式
T2L = 0x20; //設(shè)置定時(shí)初值
T2H = 0xD1; //設(shè)置定時(shí)初值
AUXR |= 0x10; //定時(shí)器2開(kāi)始計(jì)時(shí)
IE2 |= 0x04;
EA = 1;
}
void Delay5ms() //@12.000MHz
{
unsigned char i, j;
i = 59;
j = 90;
do
{
while (--j);
} while (--i);
}
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位數(shù)據(jù),可變波特率
AUXR |= 0x40; //定時(shí)器時(shí)鐘1T模式
AUXR &= 0xFE; //串口1選擇定時(shí)器1為波特率發(fā)生器
TMOD &= 0x0F; //設(shè)置定時(shí)器模式
TL1 = 0xC7; //設(shè)置定時(shí)初始值
TH1 = 0xFE; //設(shè)置定時(shí)初始值
ET1 = 0; //禁止定時(shí)器%d中斷
TR1 = 1; //定時(shí)器1開(kāi)始計(jì)時(shí)
ES = 1;
EA = 1;
}
void Send_Byte(uchar dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void Send_String(uchar *str)
{
while(*str != '\0')
{
Send_Byte(*str++);
}
}
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void Send_Wave(void)
{
uchar i = 0;
for(i = 0;i<8;i++)
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
uint Get_Distance(void)
{
uint dis = 0;
TMOD &= 0xf0;
TH0 = 0;
TL0 = 0;
Send_Wave();
TR0 = 1;
while((RX == 1) && (TF0 == 0));
TR0 = 0;
if(TF0 == 0)
{
dis = (TH0 << 8)|TL0;
dis *= 0.017;
}
else
{
TF0 = 0;
dis = 999;
}
return dis;
}
uchar Read_Key_Value(void)
{
static uchar last_trg = 0,cnt = 0;
uchar cur = 0,trg = 0,value = 3;
static uint long_count = 0;
static bit long_flag = 0;
cur = (P3 | 0x10)^0xff;
trg = cur^cnt & cur;
cnt = cur;
if((last_trg ^ trg & last_trg) && cur)
{
if(cur & 0x08) value = 4;
else if(cur & 0x04) value = 5;
else if(cur & 0x02) value = 6;
else if(cur & 0x01) value = 7;
}
last_trg = trg;
if(cur)
{
if((!long_flag) && (++long_count == 100)) //1s
{
long_flag = 1;
if(cur & 0x04) value = 5 + 100;
else if(cur & 0x02) value = 6 + 100;
}
}
else
{
long_count = 0;
long_flag = 0;
}
return value;
}
uchar Read_ADC_Value(uchar addr)
{
uchar adc = 0;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
adc = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return adc;
}
void Set_DS1302_Timer(uchar hour,uchar min,uchar sec)
{
Write_Ds1302_Byte(0x8e,0x00);
Write_Ds1302_Byte(0x80,sec/10*16 + sec%10);
Write_Ds1302_Byte(0x82,min/10*16 + min%10);
Write_Ds1302_Byte(0x84,hour/10*16 + hour%10);
Write_Ds1302_Byte(0x8e,0x80);
}
float Read_Temperature(void)
{
uchar LSB = 0,MSB = 0;
float temp = 0.0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = ((MSB << 8)|LSB) * 0.0625;
return temp;
}
void Key_Tackle_Task(void)
{
uchar key_value = 0;
if(key_feq > 10)
{
key_feq = 1;
key_value = Read_Key_Value();
}
if(key_value == 4)
{
if(++interface > 4)
{
interface = 1;
}
}
//長(zhǎng)按S5 關(guān)閉LED 長(zhǎng)按S6 關(guān)閉SMG
else if(key_value == 105)
{
led_flag = !led_flag;
}
else if(key_value == 106)
{
smg_flag = !smg_flag;
}
//S7 將電壓發(fā)送到串口
if(key_value == 7)
{
send_data_flag = 1;
}
}
//對(duì)應(yīng)界面的數(shù)據(jù)發(fā)送
void Send_Data(uchar interface)
{
switch(interface)
{
case 1:Send_Temperature();break;
case 2:Send_Volt();break;
case 3:Send_Timer();break;
case 4:Send_Distance();break;
}
}
void Send_Volt(void)
{
Send_String("Volt:");
Send_Byte(adc_volt/100+'0');
Send_Byte('.');
Send_Byte(adc_volt/10%10+'0');
Send_Byte(adc_volt%10+'0');
Send_String("v\r\n");
}
void Send_Temperature(void)
{
Send_String("Temperature:");
Send_Byte(Temperature/100+'0');
Send_Byte(Temperature/10%10+'0');
Send_Byte('.');
Send_Byte(Temperature%10+'0');
Send_String("℃\r\n");
}
void Send_Timer(void)
{
Send_String("Time:");
Send_Byte(hour/10+'0');
Send_Byte(hour%10+'0');
Send_Byte(':');
Send_Byte(min/10+'0');
Send_Byte(min%10+'0');
Send_Byte(':');
Send_Byte(sec/10+'0');
Send_Byte(sec%10+'0');
Send_String("\r\n");
}
void Send_Distance(void)
{
Send_String("Dis:");
if(distance > 99)
{
Send_Byte(distance/100+'0');
Send_Byte(distance/10%10+'0');
Send_Byte(distance%10+'0');
}
else if(distance > 9)
{
Send_Byte(distance/10%10+'0');
Send_Byte(distance%10+'0');
}
else
{
Send_Byte(distance%10+'0');
}
Send_String("cm\r\n");
}
void Data_Tackle_Task(void)
{
uchar time[3];
if(T2H < 0xd9)
{
if(adc_feq > 150)
{
adc_feq = 1;
adc_volt = Read_ADC_Value(0x03) * (5.0/255) * 100;
}
if(interface == 3)
{
time[0] = Read_Ds1302_Byte(0x81);
time[1] = Read_Ds1302_Byte(0x83);
time[2] = Read_Ds1302_Byte(0x85);
hour = (time[2]/16*10 + time[2]%16);
min = (time[1]/16*10 + time[1]%16);
sec = (time[0]/16*10 + time[0]%16);
}
if(t_feq > 150)
{
t_feq = 1;
Temperature = Read_Temperature() * 10;
}
if(dis_feq > 150)
{
dis_feq = 1;
distance = Get_Distance();
}
}
//LED控制
L[1] = (interface == 1)?(1):(0);
L[2] = (interface == 2)?(1):(0);
L[3] = (interface == 3)?(1):(0);
L[4] = (interface == 4)?(1):(0);
//串口發(fā)送
if(send_data_flag)
{
send_data_flag = 0;
Send_Data(interface);
}
//串口控制界面切換
switch(usart_cmd)
{
case 'A':interface = 1;Send_Data(interface);break; //溫度
case 'B':interface = 2;Send_Data(interface);break; //電壓
case 'C':interface = 3;Send_Data(interface);break; //時(shí)間
case 'D':interface = 4;Send_Data(interface);break; //距離
default:break;
}
usart_cmd = 0;
}
void SMG_Display_Task(void)
{
if(interface == 1)
{
smg_bit[1] = 11;
smg_bit[2] = interface;
smg_bit[3] = 10;
smg_bit[4] = 10;
smg_bit[5] = 10;
smg_bit[6] = Temperature/100;
smg_bit[7] = Temperature/10%10;
smg_bit[8] = Temperature%10;
}
else if(interface == 2)
{
smg_bit[1] = 11;
smg_bit[2] = interface;
smg_bit[3] = 10;
smg_bit[4] = 10;
smg_bit[5] = 10;
smg_bit[6] = adc_volt/100;
smg_bit[7] = adc_volt/10%10;
smg_bit[8] = adc_volt%10;
}
else if(interface == 3)
{
smg_bit[1] = hour/10;
smg_bit[2] = hour%10;
smg_bit[3] = 12;
smg_bit[4] = min/10;
smg_bit[5] = min%10;
smg_bit[6] = 12;
smg_bit[7] = sec/10;
smg_bit[8] = sec%10;
}
else if(interface == 4)
{
smg_bit[1] = 11;
smg_bit[2] = interface;
smg_bit[3] = 10;
smg_bit[4] = 10;
smg_bit[5] = 10;
smg_bit[6] = (distance>99)?(distance/100):(10);
smg_bit[7] = (distance>9)?(distance/10%10):(10);
smg_bit[8] = distance%10;
}
}
void Init_System(void)
{
Control_Port(0x080,0xff);
Control_Port(0xa0,0x00);
Control_Port(0xc0,0x00);
while(t_feq++ < 150)
{
Temperature = Read_Temperature() * 10;
}
UartInit();
Delay5ms();
Timer2Init();
Set_DS1302_Timer(11,59,50);
Send_String("Usart Test\r\n");
}
void main(void)
{
Init_System();
while(1)
{
Data_Tackle_Task();
Key_Tackle_Task();
SMG_Display_Task();
}
}
void Timer2_Server() interrupt 12
{
static uchar dsp_smg = 1;
if(led_flag)
{
Control_Port(0x80,~(L[1] << 0 | L[2] << 1 | L[3] <<2 | L[4] << 3));
}
else
{
Control_Port(0x80,0xff);
}
Control_Port(0xc0,0x00);
if(smg_flag)
{
if((interface == 1 && dsp_smg == 7) || (interface == 2 && dsp_smg == 6))
{
Control_Port(0xe0,smg_data[smg_bit[dsp_smg]] & 0x7f);
}
else
{
Control_Port(0xe0,smg_data[smg_bit[dsp_smg]]);
}
Control_Port(0xc0,1 << (dsp_smg - 1));
if(++dsp_smg > 8)
{
dsp_smg = 1;
}
}
else
{
Control_Port(0xc0,0x00);
}
key_feq++;
t_feq++;
adc_feq++;
dis_feq++;
}
void Usart_Server() interrupt 4
{
if(RI)
{
RI = 0;
usart_cmd = SBUF;
}
}
由于超聲波和頻率都是用定時(shí)器0,上面工程中使用的是超聲波,頻率部分請(qǐng)看下面哈
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-426806.html
//頻率測(cè)量在定時(shí)器2中斷中進(jìn)行 (定時(shí)器0)
void Init_Timer0(void)
{
AUXR = 0x80;
TMOD = 0x04;
TH0 = 0;
TL0 = 0;
TR0 = 1;
}
void Timer2_Server() interrupt 12
{
static uchar dsp_smg = 1;
static uint feq_count;
if(++feq_count == 500)
{
feq_count = 0;
TR0 = 0
Feq = ((uint)(TH0 << 8) | TL0) * 2;
TH0 = TL0 = 0;
TR0 = 1;
}
Control_Port(0xc0,0x00);
Control_Port(0xe0,smg_data[smg_bit[dsp_smg]]);
Control_Port(0xc0,1 << (dsp_smg -1));
if(++dsp_smg > 8)
{
dsp_smg = 1;
}
}
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-426806.html
到了這里,關(guān)于【第十四屆藍(lán)橋杯單片機(jī)沖刺版】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!