第十四届蓝桥杯单片机组模拟赛1
距第十四届蓝桥杯单片机还有不到一个月的时间啦,加油
源码
/*------------------------------第十四届蓝桥杯单片机模式赛--------------------------
@Author:小殷丫
@Date:2023.03.11
-----------------------------------------------------------------------------------*/
#include <STC15F2K60S2.H>
#include "absacc.h"
#include "intrins.h"
#include <stdio.h>
//定义行
sbit H1 = P3^0;
sbit H2 = P3^1;
sbit H3 = P3^2;
sbit H4 = P3^3;
//定义列
sbit L1 = P3^4;
sbit L2 = P3^5;
sbit L3 = P4^2;
sbit L4 = P4^4;
sbit TX = P1^0;
sbit RX = P1^1;
int distance = 0,distance_param = 30; //实时距离和设置参数
unsigned char L3_flag = 0,L3_Flash = 0; //LED 相关标志位
char usart_flag = 0,mode = 1; //串口发送标志和界面模式
char str[24] = {0}; //存储字符串数据
char led_status = 0xff; //LED 控制
//数码管段码
char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
void delay(unsigned int t); //简单延时
void Delay12us(); //@12.000MHz 延时12us
void Delay200ms(); //@12.000MHz
void Init_74HC138(unsigned char dat); //74HC138锁存器初始化
void SMG_Choice_By_Bit(unsigned char pos,unsigned char dat); //数码管安位操作
void Controal_ALL_SMG(unsigned char dat); //所以数码管控制
void Key_Controal(void); //按键控制
void Display_Distance(void); //实时距离显示
void Display_Distance_Param(void); //设置参数距离
void Send_Wave(); //产生8个40KHx超声波信号
void Measure_Distance(); //超声波测距
void initUart(void); //9600bps@12.000MHz
void SendByte(unsigned char dat); //发送单个字符
void SendString(unsigned char *str); //字符串发送
void Init_Timer1(void); //定时器1初始化
void Led_Running(void); //led功能函数
void Init_System(void); //上电初始化相关
/*===============================================下面为正式功能实现=========================================*/
void delay(unsigned int t)
{
while(t--);
}
void Delay200ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 10;
j = 31;
k = 147;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//74HC138初始化
void Init_74HC138(unsigned char dat)
{
switch(dat)
{
case 4:P2 = (P2 & 0x1f)|0x80;break;
case 5:P2 = (P2 & 0x1f)|0xa0;break;
case 6:P2 = (P2 & 0x1f)|0xc0;break;
case 7:P2 = (P2 & 0x1f)|0xe0;break;
case 0:P2 = (P2 & 0x1f)|0x00;break;
}
P2 = (P2 & 0x1f)|0x00;
}
//数码管位选操作
void SMG_Choice_By_Bit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//控制所有数码管
void Controal_ALL_SMG(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
void Key_Controal(void)
{
H4 = 0;
H1 = H2 = H3 = 1;
if(mode == 2)
{
//S12
if(L2 == 0)
{
delay(20);
if(L2 == 0)
{
while(L2 == 0)
{
Display_Distance_Param();
}
if(mode == 2)
{
distance_param += 10;
}
}
}
//S16
if(L1 == 0)
{
delay(20);
if(L1 == 0)
{
while(L1 == 0)
{
Display_Distance_Param();
}
if(mode == 2)
{
if(distance_param - 10 < 0)
{
distance_param = 0;
}
else
{
distance_param -= 10;
}
}
}
}
}
if(mode == 1)
{
//S8
if(L3 == 0)
{
delay(20);
if(L3 == 0)
{
while(L3 == 0)
{
Display_Distance();
}
distance_param = distance ;
}
}
}
//S4
if(L4 == 0)
{
delay(20);
if(L4 == 0)
{
if(mode == 1)
{
while(L4 == 0)
{
Display_Distance();
}
mode = 2;
}
else if(mode == 2)
{
while(L4 == 0)
{
Display_Distance_Param();
}
mode = 1;
}
}
}
//S9 串口发送
H3 = 0;
H1 = H2 = H4 = 1;
if(L3 == 0)
{
delay(20);
if(L3 == 0)
{
while(L3 == 0)
{
if(mode == 1)
{
Display_Distance();
}
else
{
Display_Distance_Param();
}
}
usart_flag = 1;
}
}
}
void Display_Distance(void)
{
//U 1000 0011 0xc1
SMG_Choice_By_Bit(0,0xc1);
delay(500);
SMG_Choice_By_Bit(1,smg_data[mode]);
delay(500);
SMG_Choice_By_Bit(5, smg_data[distance / 100]);
delay(500);
SMG_Choice_By_Bit(6, smg_data[(distance % 100) / 10]);
delay(500);
SMG_Choice_By_Bit(7, smg_data[distance % 10]);
delay(500);
}
void Display_Distance_Param(void)
{
//U 1000 0011 0xc1
SMG_Choice_By_Bit(0,0xc1);
delay(500);
SMG_Choice_By_Bit(1,smg_data[mode]);
delay(500);
SMG_Choice_By_Bit(5, smg_data[distance_param / 100]);
delay(500);
SMG_Choice_By_Bit(6, smg_data[(distance_param /10) % 10]);
delay(500);
SMG_Choice_By_Bit(7, smg_data[distance_param % 10]);
delay(500);
}
void Delay12us() //@12.000MHz 延时12us
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void Send_Wave() //产生8个40KHx超声波信号
{
unsigned char i;
for(i = 0; i < 8; i++)
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void Measure_Distance() //超声波测距
{
unsigned int time = 0;
TMOD &= 0xf0; //定时器0模式0,13位,最大8192个计数脉冲
TL0 = 0x00;
TH0 = 0x00;
Send_Wave(); //发送超声波信号
TR0 = 1; //启动定时器
while((RX == 1) && (TF0 == 0)); //等待超声波信号返回或者等到测量超出范围
TR0 = 0; //停止定时器
if(TF0 == 0) //正常测量范围
{
time = TH0;
time = (time << 8) | TL0;
distance = ((time / 10) * 17) / 100 + 3;
//distance = time * 0.017;
}
else //超出测量范围
{
TF0 = 0;
distance = 999;
}
}
void initUart(void) //9600bps@12.000MHz
{
SCON = 0x50;
AUXR |= 0x01;
AUXR &= 0xFB;
T2L = 0xE6;
T2H = 0xFF;
AUXR |= 0x10;
ES = 1;
EA = 1;
}
//发送一个字节
void SendByte(unsigned char dat)
{
SBUF = dat;
while(TI == 0); //等待发送完成
TI = 0; //清除标志位
}
//发送一个字符串
void SendString(unsigned char *str)
{
//字符串以'\0'为结束标志
while(*str != '\0')
{
SendByte(*str++);
}
}
//定时器1初始化
void Init_Timer1(void)
{
TMOD = 0x10; // 定时器1方式1 16
TH1 = (65535 - 50000)/256; //50ms
TL1 = (65535 - 50000)%256;
ET1 = 1;
TR1 = 1;
EA = 1;
}
void Led_Running(void)
{
if(mode == 1)
{
//0111 1111 将bit0置0 其他位不变
led_status &= 0xfe;
}
else
{
//1000 0000 将bit0置1 其他位不变
led_status |= 0x01;
}
if(mode == 2)
{
//1011 1111 将bit2置0 其他位不变
led_status &= 0xfd;
}
else
{
//0100 0000 将bit2置1 其他位不变
led_status |= 0x02;
}
if(distance_param < distance)
{
L3_flag = 1;
if(L3_Flash)
{
//1101 1111 将bit3置0 其他位不变
led_status &= 0xfb;
L3_Flash = 0;
}
else
{
//0100 0000 将bit3置1 其他位不变
led_status |= 0x04;
}
}
else
{
L3_flag = 0;
//0100 0000 将bit3置1 其他位不变
led_status |= 0x04;
}
P0 = led_status;
Init_74HC138(4);
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
Controal_ALL_SMG(0xff);
}
void main(void)
{
Init_System(); //系统初始化
Init_Timer1(); //定时器1初始化
initUart(); //串口初始化
while(1)
{
Led_Running();
Key_Controal();
Measure_Distance();
switch(mode)
{
case 1:Display_Distance();break;
case 2:Display_Distance_Param();break;
}
if(usart_flag)
{
usart_flag = 0;
sprintf(str,"Distance:%dcm\r\n",distance);
SendString(str);
Delay200ms();
}
}
}
//定时器中断服务函数 50ms进一次中断
void Timer1_Server() interrupt 3
{
static unsigned char t = 0;
TH1 = (65535 - 50000)/256; //50ms
TL1 = (65535 - 50000)%256;
if(L3_flag)
{
t++;
if(t == 4)//200ms
{
t = 0;
L3_Flash = 1;
}
}
}