第十四届蓝桥杯单片机模拟题2解析
第十四届蓝桥杯单片机模拟题2
此题目来自4T测评,模拟题2和1都考了串口的使用,这一次的省赛题考的几率应该也很大,可以多多练习一下,加油。
代码
#include <STC15F2K60S2.H>
#include "iic.h"
#include <stdio.h>
#include <string.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;
unsigned char str[24] = {0},usart_flag = 0,buf[12] = {0},count = 0;
unsigned int db_param = 65;
float db_data = 0.0;
unsigned char mode = 1,led_status = 0xff,flash_flag = 0,l8_flag = 0;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned char code smg_dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//简单延时
void delay(unsigned int t)
{
while(t--);
}
//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_By_Bit(unsigned char pos,unsigned char dat)
{
P0 = (0x01 << pos);
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//操作所有数码管
void SMG_ALL(unsigned char dat)
{
P0 = 0xff;
Init_74HC138(6);
P0 = dat;
Init_74HC138(7);
}
//ADC采集
void Read_ADC(void)
{
unsigned int volt_t = 0;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
volt_t = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
db_data = (18 * volt_t * (5.0/255)) * 10;
}
//数码管功能显示
void SMG_Display_DB(void)
{
//1000 0011
SMG_By_Bit(0,0xc1);
delay(200);
SMG_By_Bit(1,smg_data[mode]);
delay(200);
SMG_By_Bit(2,0xff);
delay(200);
SMG_By_Bit(3,0xff);
delay(200);
SMG_By_Bit(4,0xff);
delay(200);
if(db_data > 99)
{
SMG_By_Bit(5,smg_data[(int)db_data/100]);
delay(200);
}
if(db_data > 9)
{
SMG_By_Bit(6,smg_dot[(int)db_data/10%10]);
delay(200);
}
SMG_By_Bit(7,smg_data[(int)db_data%10]);
delay(200);
SMG_ALL(0xff);
delay(200);
}
void SMG_Display_Set_DB(void)
{
//1000 0011
SMG_By_Bit(0,0xc1);
delay(200);
SMG_By_Bit(1,smg_data[mode]);
delay(200);
SMG_By_Bit(2,0xff);
delay(200);
SMG_By_Bit(3,0xff);
delay(200);
SMG_By_Bit(4,0xff);
delay(200);
SMG_By_Bit(5,0xff);
delay(200);
if(db_param > 9)
{
SMG_By_Bit(6,smg_data[db_param/10]);
delay(200);
}
SMG_By_Bit(7,smg_data[db_param%10]);
delay(200);
SMG_ALL(0xff);
delay(200);
}
//按键处理
void Key_Scan(void)
{
H4 = 0;
H1 = H2 = H3 = 1;
//S12
if(L2 == 0)
{
delay(20);
if(L2 == 0)
{
if(mode == 1)
{
while(L2 == 0)
{
SMG_Display_DB();
}
mode = 2;
}
else if(mode == 2)
{
while(L2 == 0)
{
SMG_Display_Set_DB();
}
mode = 1;
}
}
}
//S16 db加
if(mode == 2)
{
if(L1 == 0)
{
delay(20);
if(L1 == 0)
{
while(L1 == 0)
{
SMG_Display_Set_DB();
}
if(db_param < 90)
{
db_param += 5;
}
else
{
db_param = 90;
}
}
}
H3 = 0;
H1 = H2 = H4;
//S17 db减
if(L1 == 0)
{
delay(20);
if(L1 == 0)
{
while(L1 == 0)
{
SMG_Display_Set_DB();
}
if(db_param > 0)
{
db_param -= 5;
}
else
{
db_param = 0;
}
}
}
}
}
//LED控制
void Led_Running(void)
{
if(mode == 1)
{
//L1 0111 1111
led_status &= 0xfe; //bit0置0 其余位不变
}
else
{
//L1 1000 0000
led_status |= 0x01; //bit0置1 其余位不变
}
if(mode == 2)
{
//L2 1011 1111
led_status &= 0xfd; //bit1置0 其余位不变
}
else
{
//0100 0000
led_status |= 0x02; //bit1置1 其余位不变
}
if(db_param * 10 < db_data)
{
l8_flag = 1;
if(flash_flag == 1)
{
//L8 1111 1110
led_status &= 0x7f;
flash_flag = 0;
}
else
{
//0000 0001
led_status |= 0x80;
}
}
else
{
l8_flag = 0;
led_status |= 0x80;
}
P0 = led_status;
Init_74HC138(4);
}
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++);
}
}
void Init_Timer(void)
{
TMOD = 0x01;
TH0 = (65535 - 1000)/256; //1ms
TL0 = (65535 - 1000)%256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//系统初始化
void Init_System(void)
{
P0 = 0xff;
Init_74HC138(4);
P0 = 0x00;
Init_74HC138(5);
SMG_ALL(0xff);
}
void main(void)
{
Init_System();
Init_Timer();
initUart();
while(1)
{
Read_ADC();
Led_Running();
Key_Scan();
switch(mode)
{
case 1:SMG_Display_DB();break;
case 2:SMG_Display_Set_DB();break;
default:break;
}
if(usart_flag == 1)
{
//if(buf[0] == 'R' && buf[1] == 'e' && buf[2] == 't' && buf[3] == 'u' && buf[4] == 'r' && buf[5] == 'n')
if(strcmp(buf,"Return") == 0)
{
sprintf(str,"Noises:%.1f\r\n",db_data/10);
SendString(str);
}
usart_flag = 0;
}
}
}
void Timer0_Server() interrupt 1
{
static unsigned char t = 0;
TH0 = (65535 - 1000)/256; //1ms
TL0 = (65535 - 1000)%256;
if(l8_flag == 1)
{
t++;
if(t == 100) //0.1s
{
t = 0;
flash_flag = 1;
}
}
}
//串口中断接收
void Usart_Server() interrupt 4
{
unsigned char temp =0;
if(RI)
{
RI = 0;
temp = SBUF;
if(temp == 0 || temp == '\r' || temp == '\n') //结束符判断
{
usart_flag = 1; //接收完成标志
buf[count] = '\0';
count = 0; //计数清零等待下一帧数据
}
else
{
buf[count++] = temp;
}
}
}
题目功能都实现了滴,在数码管显示上存在点瑕疵,如有更好的处理方式,望大佬指正
作者:小殷学长