今天是第十三届蓝桥杯单片机国赛的比赛时间,刚比完,简单说一下感想,这次国赛必须要用到三个定时器,昨天刚看了定时器2的使用,不太熟练,所以写的也不是很好,超声波和频率有点冲突,就个人而言,我觉得这一届最大的难点也就是在这里了,其他的应该没什么难的,个人感觉。虽然没有写的很好,但是总体思路还可以说一下,怎么解决定时器问题。
定时器0必须用来测量频率,定时器1必须用来超声波测距,那么还需要一个定时器来实现一些外设的定时,比如数码管的2ms扫描一次,再比如按键的20ms扫描一次,所以这一届国赛,需要用到三个定时器,那就得用到定时器2。这个时候可能就会有疑问,为什么一定要用到定时器2,我简单说明一下,因为定时器0作为计数脉冲,也就是说这时的定时器0是作为计数器使用的,超声波需要用到TF溢出标志位,而这个标志位只有定时器0和定时器1才有,定时器0已经被使用了,所以只能用定时器1。而定时器2既不能作为计数器使用,也没有TF标志位,所以这一届就需要用到三个定时器。(说错请在评论区纠正,个人观点,不喜勿喷)
以后有时间可以出一下第十三届国赛的代码,今天就简单出一下第十届吧,第十届考到了串口,也存在一定难度,说了这么多废话,还是展示代码吧。
对以下代码有疑问的可以评论区问我,我会尽我所能给大家解答,谢谢支持
#include "stc15.h"
#include "iic.h"
#include "onewire.h"
#include "intrins.h"
#include "stdio.h"
typedef unsigned char u8;
typedef unsigned int u16;
u8 code SMG_duan[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 code SMG_com[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
u8 SMG_bit[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
u8 buf[12];
u8 send_buf[12];
sbit TX=P1^0;
sbit RX=P1^1;
bit key_flag=0,temp_flag=0,dis_flag=0,flag=0,dac_flag=0,time_delay=0;
u8 Trg=0,Cont=0;
u8 mode=0,display_mode=0;
u8 distance=0;
u8 temp_para=30,dis_para=35;
u8 a=30,b=35;
u8 led_falg=0;
u8 num=0;
float temp_true=0;
u8 led_para=0xff;
u16 xdata temp_num=0,t=0;
u16 xdata degree=0;
u16 xdata count_s6=0,count_s13=0;
void Delay13us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 36;
while (--i);
}
void Delay3ms() //@12.000MHz
{
unsigned char i, j;
i = 36;
j = 1;
do
{
while (--j);
} while (--i);
}
void Initialize()//初始化函数
{
P0=0xff;P2=(P2&0x1f)|0x80;P2=0x00;
P0=0x00;P2=(P2&0x1f)|0xa0;P2=0x00;
}
unsigned char Key_Read()//键值获取函数
{
unsigned char temp = 0;
P44 = 0;P42 = 1;P35 = 1;P34 = 1;
if(P33 == 0) temp = 0x88;
if(P32 == 0) temp = 0x84;
if(P31 == 0) temp = 0x82;
if(P30 == 0) temp = 0x81;
P44 = 1;P42 = 0;P35 = 1;P34 = 1;
if(P33 == 0) temp = 0x48;
if(P32 == 0) temp = 0x44;
if(P31 == 0) temp = 0x42;
if(P30 == 0) temp = 0x41;
P44 = 1;P42 = 1;P35 = 0;P34 = 1;
if(P33 == 0) temp = 0x28;
if(P32 == 0) temp = 0x24;
if(P31 == 0) temp = 0x22;
if(P30 == 0) temp = 0x21;
P44 = 1;P42 = 1;P35 = 1;P34 = 0;
if(P33 == 0) temp = 0x18;
if(P32 == 0) temp = 0x14;
if(P31 == 0) temp = 0x12;
if(P30 == 0) temp = 0x11;
return temp;
}
void KEY_read_true()//按键执行函数
{
u8 read;
read=Key_Read();
Trg=read&(read^Cont);
Cont=read;
}
void PCF8591_dac(u8 add)//dac函数
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
}
void AT24C02_wrtie(u8 add,u8 val)//存储函数
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(val);
IIC_WaitAck();
IIC_Stop();
}
u8 AT24C02_read(u8 add)
{
u8 temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return temp;
}
void send_wave()//超声波发波函数
{
u8 i=8;
do
{
TX=1;
Delay13us();
TX=0;
Delay13us();
}
while(i--);
}
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初值
TH0 = 0xD1; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void Uart_Send(unsigned char *Uart_String)//串口发送字符函数
{
while(*Uart_String != '\0')
{
SBUF = *Uart_String;
while(TI == 0);
TI = 0;
Uart_String++;
}
}
void UartInit(void) //4800bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0x8F; //设定定时初值
T2H = 0xFD; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES=1;
}
void uart() interrupt 4
{
if(RI)
{
RI=0;
buf[num]=SBUF;
num++;
}
}
void KEY_execute()//按键处理函数
{
if(key_flag)
{
key_flag=0;
KEY_read_true();
switch(Trg)
{
case 0x18:
if((mode==1)&&(display_mode==0))
{
temp_para-=2;
if(temp_para==254)
temp_para=98;
}
if((mode==1)&&(display_mode==1))
{
dis_para-=5;
if(dis_para==251)
dis_para=95;
}
break;//s16
case 0x14:
if((mode==1)&&(display_mode==0))
{
temp_para+=2;
if(temp_para==100)
temp_para=0;
}
if((mode==1)&&(display_mode==1))
{
dis_para+=5;
if(dis_para==100)
dis_para=0;
}
break;//s17
}
if(Cont==0x28)//s12
{
count_s6++;
if(count_s6>=50)//超过1s是长按
degree=0;
}
if((Cont==0x24)&&(led_falg==0))//s13
{
count_s13++;
if(count_s13>=50)
{
dac_flag^=1;
led_falg=1;
}
}
if((Cont==0x00)&&(Trg==0x00))//松手检测
{
if(count_s6>=50)
count_s6=0;
else if(count_s6!=0)
{
count_s6=0;
if(mode==0)
{
if(++display_mode==3)display_mode=0;
}
if(mode==1)
{
if(++display_mode==2)display_mode=0;
}
}
if(count_s13>=50)
{
count_s13=0;
led_falg=0;
}
else if(count_s13!=0)
{
count_s13=0;
display_mode=0;
if(++mode==2)
{
mode=0;
if((a!=temp_para)||(b!=dis_para))
{
degree++;
a=temp_para;b=dis_para;
}
}
}
}
AT24C02_wrtie(0x00,degree/255);
Delay3ms();
AT24C02_wrtie(0x01,degree%255);
}
}
void SMG_execute()//数码管处理函数
{
u8 j=3,i;
for(i=0;i<8;i++)
SMG_bit[i]=0xff;
if(mode==0)
{
switch(display_mode)
{
case 0:
SMG_bit[0]=0x8e;
SMG_bit[1]=SMG_duan[num];
SMG_bit[4]=SMG_duan[temp_num/1000];
SMG_bit[5]=SMG_duan[temp_num/100%10]&0x7f;
SMG_bit[6]=SMG_duan[temp_num/10%10];
SMG_bit[7]=SMG_duan[temp_num%10];
break;
case 1:
SMG_bit[0]=0xc7;
SMG_bit[6]=SMG_duan[distance/10];
SMG_bit[7]=SMG_duan[distance%10];
break;
case 2:
SMG_bit[0]=0x98;
SMG_bit[3]=SMG_duan[degree/10000];
SMG_bit[4]=SMG_duan[degree/1000%10];
SMG_bit[5]=SMG_duan[degree/100%10];
SMG_bit[6]=SMG_duan[degree/10%10];
SMG_bit[7]=SMG_duan[degree%10];
while(SMG_bit[j]==0xc0)
{
SMG_bit[j]=0xff;
j++;
if(j==7)break;
}
break;
}
}
else
{
switch(display_mode)
{
case 0:
SMG_bit[0]=0x92;
SMG_bit[3]=SMG_duan[1];
SMG_bit[6]=SMG_duan[temp_para/10];
SMG_bit[7]=SMG_duan[temp_para%10];
break;
case 1:
SMG_bit[0]=0x92;
SMG_bit[3]=SMG_duan[2];
SMG_bit[6]=SMG_duan[dis_para/10];
SMG_bit[7]=SMG_duan[dis_para%10];
break;
}
}
}
void LED_execute()//LED灯处理函数
{
if(temp_num>temp_para*100)
{
led_para&=~(1<<0);
}
else
{
led_para|=(1<<0);
}
if(distance<dis_para)
{
led_para&=~(1<<1);
}
else
{
led_para|=(1<<1);
}
if(dac_flag==0)
{
led_para&=~(1<<2);
}
else
{
led_para|=(1<<2);
}
}
void main()
{
Initialize();
degree=AT24C02_read(0x00)*255+AT24C02_read(0x01);
Timer0Init();
UartInit();
while(1)
{
if(time_delay)
{
time_delay=0;
if(num>0)
{
if(buf[0]=='S' && buf[1]=='T' && num<=2)
{
sprintf(send_buf,"$%d,%.2f\r\n",(int)distance,temp_true);
Uart_Send(send_buf);
num=0;
}
else if(buf[0]=='P' && buf[1]=='A' && buf[2]=='R' && buf[3]=='A' && num<=4)
{
sprintf(send_buf,"#%d,%d\r\n",(int)dis_para,(int)temp_para);
Uart_Send(send_buf);
num=0;
}
else
{
sprintf(send_buf,"%d:ERROR\r\n",(int)num);
Uart_Send(send_buf);
num=0;
}
}
}
if(temp_flag)
{
temp_flag=0;
temp_true=rd_temperature();
temp_num=temp_true*100;
}
if(dis_flag)
{
dis_flag=0;
send_wave();
TR1=1;
while((TF1==0)&&(RX==1));
TR1=0;
if(TF1==1)
{
TF1=0;
distance=99;
}
else
{
t=(TH1<<8)|TL1;
distance=(unsigned int)(t*0.017);
if(distance>=99)
distance=99;
}
TH1=0;
TL1=0;
}
if(dac_flag==1)
{
PCF8591_dac(255*0.4);
}
else
{
if(distance>dis_para)
PCF8591_dac(204);
else
PCF8591_dac(102);
}
KEY_execute();
if(flag)
{
flag=0;
SMG_execute();
}
LED_execute();
}
}
void Timer0() interrupt 1
{
static int smg_count=0,key_count=0,temp_count=0,dis_count=0,count=0,time_count=0,i=0;
smg_count++;key_count++;temp_count++;dis_count++;count++;time_count++;
if(time_count==20)
{
time_count=0;
time_delay=1;
}
if(count==50)
{
count=0;
flag=1;
}
if(dis_count==200)
{
dis_count=0;
dis_flag=1;
}
if(temp_count==100)
{
temp_count=0;
temp_flag=1;
}
if(key_count==20)
{
key_count=0;
key_flag=1;
}
if(smg_count==2)
{
smg_count=0;
P0=led_para;P2=0x80;P2=0x00;
P0=0x00;P2=0xa0;P2=0x00;
P0=0xff;P2=0xe0;P2=0x00;
P0=SMG_com[i];P2=0xc0;P2=0x00;
P0=SMG_bit[i];P2=0xe0;P2=0x00;
i++;
if(i==8)i=0;
}
}