本人近期会分享蓝桥杯单片机各届的代码,希望能给新手朋友一些思路和参考,也请各位高手朋友指正批评,这是本人完成的第十届代码参考,本人代码风格是师从电子设计工坊,谢谢。
#include "STC15F2K60S2.H"
#include "iic.h"
#include "intrins.h"
#include "onewire.h"
#include "string.h"
#include "math.h"
#define u8 unsigned char
#define u16 unsigned int
u8 code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
#define key_state0 0
#define key_state1 1
#define key_state2 2
//超声波
sbit TX=P1^0;
sbit RX=P1^1;
bit display_distance=0;
u16 timer,distance;
bit key_flag;
u8 j=0;//实现定时长按时间,要在全局定义
u8 z=0;
bit s8_flag;
bit s9_flag;
//串口通信
u8 Rdat[10];
u8 recv=0;//Rdat[recv]
u8 len=0;//设置数组的长度
u8 smg1[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg2[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg3[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg4[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg5[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u16 pinlv=0;
bit xs_mode;//0是数据界面,1是参数界面
bit xs_cs_mode=0;//0是温度参数,1是距离参数
u8 xianshi_mode=0;//0是温度界面,1是距离界面,2是变更次数显示界面
u16 wendu_zhi;
u16 biangeng_cs=2;//变更次数
u8 wendu_cs=30;
u8 juli_cs=35;
bit dac_shuchu1=0;//开启和关闭dac,0是开启,1是关闭
void Timer0Init(void);
void Device(u8 p2,u8 p0);
void system_init();
u8 read_kbd();
void key_use();
void Delay12us();
void smg_xs();
void csb_hs();
void Delay10ms();
void send_wave(void);
void csb_distance1(void);
void timer00();
void UartInit(void);
void chuankou();
void clear_Rdat();
void wendu_hs();
void dac_hs();
void Delay5ms();
void led_hs();
void led_Device(u8 p3);
void main()
{
Timer0Init();
system_init();
UartInit();
biangeng_cs=read_24c02(0x00);
while(1)
{
key_use();
smg_xs();
wendu_hs();
csb_hs();
chuankou();
dac_hs();
led_hs();
}
}
void time0() interrupt 1 //定时器0是中断1,定时器是中断号3
{
static int smg_count,key_count,i=0;
u16 a0;
// if(++count_f==500)
// {
// count_f=0;
// TR0=0;
// pinlv=(TH0*256+TL0)*2.3;
// TH0=0X00;TL0=0X00;
// TR0=1;
// }
if(++a0==350)
{
display_distance=1;
a0=0;
}
if(++key_count==12)
{
key_count=0;
key_flag=1;
}
if(++smg_count==2)
{
smg_count=0;
Device(0xc0,0x00);
if(xs_mode==0)//数据界面
{
if(xianshi_mode==0)
{
Device(0xe0,~smg1[i]);
}
else if(xianshi_mode==1)
{
Device(0xe0,~smg2[i]);
}
else if(xianshi_mode==2)
{
Device(0xe0,~smg3[i]);
}
}
else //参数界面
{
if(xs_cs_mode==0)//温度
{
Device(0xe0,~smg4[i]);
}
else //距离参数
{
Device(0xe0,~smg5[i]);
}
}
Device(0xc0,smg_wei[i]);
i++;
if(i==8) i=0;
}
}
void key_use()
{
u8 key_val_zhi=0;
if(key_flag)
{
key_flag=0;
key_val_zhi=read_kbd();
switch(key_val_zhi)
{
case 12:
z=100;
j=0;
if(xs_mode==0)
{
xianshi_mode++;
if(xianshi_mode==3)
xianshi_mode=0;
}
else
{
xs_cs_mode=~xs_cs_mode;
}
break;
case 13:
j=100;
z=0;
xs_mode=~xs_mode;
break;
case 16:
if(xs_mode==1)
{
if(xs_cs_mode==0)
{
biangeng_cs++;
write_24c02(0x00,biangeng_cs);
if(biangeng_cs>65535)
biangeng_cs=0;
if(wendu_cs>1)
wendu_cs-=2;
}
else
{
biangeng_cs++;
write_24c02(0x00,biangeng_cs);
if(biangeng_cs>65535)
biangeng_cs=0;
if(juli_cs>4)
juli_cs-=5;
}
}
break;
case 17:
if(xs_mode==1)
{
if(xs_cs_mode==0)
{
biangeng_cs++;
write_24c02(0x00,biangeng_cs);
if(biangeng_cs>65535)
biangeng_cs=0;
if(wendu_cs<99)
wendu_cs+=2;
if(wendu_cs>99)
wendu_cs=99;
}
else
{
biangeng_cs++;
write_24c02(0x00,biangeng_cs);
if(biangeng_cs>65535)
biangeng_cs=0;
if(juli_cs<99)
juli_cs+=5;
if(juli_cs>99)
juli_cs=99;
}
}
break;
}
}
}
void smg_xs()
{
if(xs_mode==0)//数据界面
{
if(xianshi_mode==0)//温度
{
smg1[0]=0x39;
smg1[4]=smg_du[wendu_zhi/1000];smg1[5]=smg_du[wendu_zhi/100%10]|0x80;
smg1[6]=smg_du[wendu_zhi/10%10];smg1[7]=smg_du[wendu_zhi%10];
}
else if(xianshi_mode==1)//距离
{
smg2[0]=0x38;
smg2[6]=smg_du[distance/10];smg2[7]=smg_du[distance%10];
}
else if(xianshi_mode==2)//变更参数
{
if(biangeng_cs>9999)
{
smg3[0]=0xbf;
smg3[3]=smg_du[biangeng_cs/10000];smg3[4]=smg_du[biangeng_cs/1000%10];
smg3[5]=smg_du[biangeng_cs/100%10];smg3[6]=smg_du[biangeng_cs/10%10];
smg3[7]=smg_du[biangeng_cs%10];
}
else if(biangeng_cs>999)
{
smg3[0]=0xbf;
smg3[3]=0x00;smg3[4]=smg_du[biangeng_cs/1000];
smg3[5]=smg_du[biangeng_cs/100%10];smg3[6]=smg_du[biangeng_cs/10%10];
smg3[7]=smg_du[biangeng_cs%10];
}
else if(biangeng_cs>99)
{
smg3[0]=0xbf;
smg3[3]=0x00;smg3[4]=0x00;
smg3[5]=smg_du[biangeng_cs/100];smg3[6]=smg_du[biangeng_cs/10%10];
smg3[7]=smg_du[biangeng_cs%10];
}
else if(biangeng_cs>9)
{
smg3[0]=0xbf;
smg3[3]=0x00;smg3[4]=0x00;
smg3[5]=0x00;smg3[6]=smg_du[biangeng_cs/10];
smg3[7]=smg_du[biangeng_cs%10];
}
else if(biangeng_cs<=9)
{
smg3[0]=0xbf;
smg3[3]=0x00;smg3[4]=0x00;
smg3[5]=0x00;smg3[6]=0x00;
smg3[7]=smg_du[biangeng_cs%10];
}
}
}
else // 参数界面
{
if(xs_cs_mode==0)//温度参数
{
smg4[0]=0x73;
smg4[3]=smg_du[1];
smg4[6]=smg_du[wendu_cs/10];
smg4[7]=smg_du[wendu_cs%10];
}
else // 距离参数
{
smg5[0]=0x73;
smg5[3]=smg_du[2];
smg5[6]=smg_du[juli_cs/10];
smg5[7]=smg_du[juli_cs%10];
}
}
}
void send_byte(u8 dat)
{
SBUF=dat;
while(TI==0);//等待发送标志位置1
TI=0;
}
void sendstring(u8 *s)
{
while(*s!='\0')
{
send_byte(*s++);
}
}
void timer2() interrupt 4
{
//发送字符串
if(RI==1)
{
Rdat[recv]=SBUF;
RI=0;
recv++;
}
}
//数字变字符在后面加 ’0‘
void chuankou()
{
if(Rdat[0]=='S')
{
len=3;
}
else if(Rdat[0]=='P')
{
len=5;
}
while(Rdat[len]!='\0')
{
if(strcmp(Rdat,"ST\r\n")==0)
{
send_byte('$');
send_byte((distance/10)+'0');
send_byte((distance%10)+'0');
send_byte(',');
send_byte((wendu_zhi/1000)+'0');
send_byte((wendu_zhi/100%10)+'0');
send_byte('.');
send_byte((wendu_zhi/10%10)+'0');
send_byte((wendu_zhi%10)+'0');
sendstring("\r\n");
}
else if(strcmp(Rdat,"PARA\r\n")==0)
{
send_byte('#');
send_byte((juli_cs/10)+'0');
send_byte((juli_cs%10)+'0');
send_byte(',');
send_byte((wendu_cs/10)+'0');
send_byte((wendu_cs%10)+'0');
sendstring("\r\n");
}
else
{
sendstring("ERROR");
sendstring("\r\n");
}
clear_Rdat();
len=0;
recv=0;
}
}
void wendu_hs()
{
wendu_zhi=ra_temprature();
}
void dac_hs()
{
if(dac_shuchu1)
{
write_dac(21);
}
else
{
if(distance<=juli_cs)
{
write_dac(102);
}
else
{
write_dac(255);
}
}
}
void led_hs()
{
if((wendu_zhi/100)>wendu_cs)
{
led_Device(~0x01);
}
else
{led_Device(~0x00);}
Delay5ms();
Delay12us();
Delay12us();
Delay12us();
Delay12us();
if(distance<juli_cs)
{
led_Device(~0x02);
}
else
{led_Device(~0x00);}
Delay5ms();
Delay12us();
Delay12us();
Delay12us();
Delay12us();
if(dac_shuchu1)
{
led_Device(~0x00);
}
else
{
led_Device(~0x04);
}
}
void clear_Rdat()//清除数组函数
{
u8 i;
for(i=0;i<9;i++)
{
Rdat[i]='\0';
}
}
void send_wave()
{
u8 i;
for(i=0;i<10;i++)
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}
}
void csb_distance1()
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x00; //设置定时初值
TH1 = 0x00; //设置定时初值
TF1 = 0; //清除TF0标志
TR1=0; //定时器1开始计时
send_wave();
TR1=1;
while(RX==1&&TF1==0);//破案了,这里要加;号,注意注意!
TR1 = 0;
if(TF1==0)
{
timer=(TH1<<8)|TL1;
distance=timer*0.017;
}
else
{
TF1=0;
distance=99;
}
}
void csb_hs()
{
if(display_distance==1)
{
csb_distance1();
display_distance=0;
}
if(distance>99)
distance=99;
}
u8 read_kbd()
{
static char key_state=0;
u8 key_val=0,key_press;
u8 key1,key2;
P44=1;P42=1;P35=1;P34=1;
P33=0;P32=0;P31=0;P30=0;
if(P44==0) key1=0x70;
else if(P42==0) key1=0xb0;
else if(P35==0) key1=0xd0;
else if(P34==0) key1=0xe0;
else key1=0xf0;
P44=0;P42=0;P35=0;P34=0;
P33=1;P32=1;P31=1;P30=1;
if(P33==0) key2=0x07;
else if(P32==0) key2=0x0b;
else if(P31==0) key2=0x0d;
else if(P30==0) key2=0x0e;
else key2=0x0f;
key_press=key1|key2;
switch(key_state)
{
case key_state0:
if(key_press!=0xff)
key_state=key_state1;
break;
case key_state1:
if(key_press!=0xff)
{
if(key_press==0x77) key_val=4;
else if(key_press==0x7b) key_val=5;
else if(key_press==0x7d) key_val=6;
else if(key_press==0x7e) key_val=7;
else if(key_press==0xb7) key_val=8;
else if(key_press==0xbb) key_val=9;
else if(key_press==0xbd) key_val=10;
else if(key_press==0xbe) key_val=11;
else if(key_press==0xd7) key_val=12;
else if(key_press==0xdb) key_val=13;
else if(key_press==0xdd) key_val=14;
else if(key_press==0xde) key_val=15;
else if(key_press==0xe7) key_val=16;
else if(key_press==0xeb) key_val=17;
else if(key_press==0xed) key_val=18;
else if(key_press==0xee) key_val=19;
key_state=key_state2;
}
else
key_state=key_state0;
break;
case key_state2:
if(key_press==0xff)
key_state=key_state0;
//可以在这里做手脚,实现松开按住显示界面
if(j<100)
j++;
if(j==99)//实现定时长按操作
{
biangeng_cs=0;
j++;
}
if(z<100)
z++;
if(z==99)//实现定时长按操作
{
dac_shuchu1=~dac_shuchu1;
z++;
}
break;
}
return key_val;
}
void Device(u8 p2,u8 p0)
{
P2=(P2&0X1F)|p2;
P0=p0;
P2=P2&0X1F;
}
void led_Device(u8 p3)
{
P0=0xff;
Device(0x80,p3);
}
void system_init()
{
Device(0x80,0xff);
Device(0xa0,0x00);
Device(0xc0,0x00);
Device(0xe0,0xff);
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void Delay10ms() //@12.000MHz
{
unsigned char i, j;
i = 117;
j = 184;
do
{
while (--j);
} while (--i);
}
void Delay5ms() //@12.000MHz
{
unsigned char i, j;
i = 59;
j = 90;
do
{
while (--j);
} while (--i);
}
void timer00()//ne555定时0的操作
{
TMOD=0X04;
TL0=0X00;
TH0=0X00;
TF0=0;
ET0=0;
}
void UartInit(void) //4800bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xC0; //设定定时初值
T2H = 0xFD; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES=1;
}
请大家指点批评,谢谢。