第十四届蓝桥杯单片机模拟题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;
		}
	}
}

题目功能都实现了滴,在数码管显示上存在点瑕疵,如有更好的处理方式,望大佬指正

作者:小殷学长

物联沃分享整理
物联沃-IOTWORD物联网 » 第十四届蓝桥杯单片机模拟题2解析

发表评论