蓝桥杯单片机第14届模拟题一(基于西风大模板)

题目要求:

程序实现:

main.c

/*头文件声明区*/
#include <STC15F2K60S2.H>
#include <Init.h>
#include <Key.h>
#include <Led.h>
#include <Seg.h>
#include <Uart.h>
#include <stdio.h>
#include <Wave.h>
#include <String.h>



/*头文件变量声明区*/
unsigned char Key_Val,Key_Dwon,Key_Up,Key_Old;
unsigned char Key_Slow_Down;
idata unsigned char Seg_Buf[8] = {16,16,16,16,16,16,16,16};
idata unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};
unsigned char Seg_Pos;
unsigned int Seg_Slow_Down;
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};

/*串口数据*/
idata unsigned char Uart_Recv[10]; // 串口接收数据缓冲区
unsigned char Uart_Recv_Index;  // 串口接收数据索引
bit Uart_flag;       // 串口标志位
unsigned char Sys_Tick;  // 系统时钟计数

bit Seg_Disp_Mode;//0-距离显示界面 1-参数显示界面
unsigned int dat;
unsigned int Can_Disp;
unsigned int Can_Ctrol = 30;
unsigned char Timer_200ms;
bit Timer_200ms_flag;//0
	

/*键盘处理函数*/
void Key_Proc()
{
	if(Key_Slow_Down) return;
	Key_Slow_Down = 1;
	
	Key_Val = Key_Read();
	Key_Dwon = Key_Val & (Key_Val ^ Key_Old);
	Key_Up = ~Key_Val & (Key_Val ^ Key_Old);
	Key_Old = Key_Val;

	switch(Key_Dwon)
	{

		case 4://切换界面按键
			Seg_Disp_Mode ^= 1;
		if(Seg_Disp_Mode == 1)
			Can_Disp = Can_Ctrol;
		if(Seg_Disp_Mode == 0)
			Can_Ctrol = Can_Disp;
		break;
		case 8://参数按键
			if(Seg_Disp_Mode == 0)
			{
				Can_Ctrol = dat;
			}
		break;
		case 12:
			if(Seg_Disp_Mode == 1)
			{
				Can_Disp = Can_Disp + 10;
				if(Can_Disp > 999)
					Can_Disp = 999;				
			}
		break;
		case 16:
			if(Seg_Disp_Mode == 1)
			{
				Can_Disp = Can_Disp - 10;
				if(Can_Disp > 10000)
					Can_Disp = 0;
			}
		break;
		case 9:
			printf("Distance:%dcm\r\n",(unsigned int)dat);
		break;		
	}
}

/*信息处理函数*/
void Seg_Proc()
{
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	
	/*信息获取区域*/
	dat = Ut_Wave_String();
	if(Seg_Disp_Mode == 0)//距离显示界面
	{
		Seg_Buf[0] = 18;
		Seg_Buf[1] = 1;
		Seg_Buf[5] = dat / 100 % 10;
		Seg_Buf[6] = dat / 10 % 10;
		Seg_Buf[7] = dat % 10;
		if(Seg_Buf[5] == 0)
		{
			Seg_Buf[5] = 16;
			if(Seg_Buf[6] == 0)
				Seg_Buf[6] = 16;
		}
	}
	if(Seg_Disp_Mode == 1)//参数显示界面
	{
		Seg_Buf[0] = 18;
		Seg_Buf[1] = 2;
		Seg_Buf[5] = Can_Disp / 100 % 10;
		Seg_Buf[6] = Can_Disp / 10 % 10;
		Seg_Buf[7] = Can_Disp % 10;
		if(Seg_Buf[5] == 0)
		{
			Seg_Buf[5] = 16;
			if(Seg_Buf[6] == 0)
				Seg_Buf[6] = 16;
		}
	}
}
/*其他显示函数*/
void Led_Proc()
{
	if(Seg_Disp_Mode == 0)
	{
		ucLed[0] = 1;
	}
  else
		ucLed[0] = 0;
	
	if(Seg_Disp_Mode == 1)
	{
		ucLed[1] = 1;
	}
  else
		ucLed[1] = 0;

	ucLed[2] = Timer_200ms_flag;

}
/*串口处理函数*/
// 处理串口接收到的数据,当接收到数据时更新接收索引和缓冲区。
void Uart_Proc()
{
	if(Uart_Recv_Index == 0) return;
	if(Sys_Tick >= 10)
	{
		Sys_Tick = Uart_flag = 0;
		//逻辑函数
		
		
		
		memset(Uart_Recv,0,Uart_Recv_Index);//清空Uart_Recv数组中的数据
		Uart_Recv_Index = 0;//重置接收索引
	}	
}

/*定时器1初始化*/
void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	
	ET1 = 1;
	EA = 1;
}

/*定时器1中断服务函数*/
void Timer1server() interrupt 3
{
	if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
	if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
	if(Uart_flag) Sys_Tick++;
	if(++Seg_Pos == 8) Seg_Pos = 0;
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
	

	//dat = Ut_Wave_String();
	if(dat > Can_Ctrol)
	{
		if(++Timer_200ms == 200)
		{
			Timer_200ms = 0;
			Timer_200ms_flag ^= 1;
			
		}
	}
}
	
/*串口1中断服务函数*/
void Uart1server() interrupt 4
{
	if(RI == 1)// 检测到串口接收中断
	{
	  Uart_flag = 1;     // 设置串口标志位
		Sys_Tick = 0;      // 重置系统时钟
		Uart_Recv[Uart_Recv_Index] = SBUF;  // 保存接收到的数据
		Uart_Recv_Index++;        // 更新接收索引
		RI = 0;               // 清除中断标志位
	}
	if(Uart_Recv_Index > 10) 
		Uart_Recv_Index = 0;
		
}

/*主函数*/
void main()
{
	System_Init();
	Timer1Init();
	UartInit();
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
		Uart_Proc();
	}
}

Uart.c

#include <Uart.h>


void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0xC7;		//设定定时初值
	T2H = 0xFE;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	
	ES = 1;
	EA = 1;
}

extern char putchar (char ch)
{
	SBUF = ch;  // 将ch写入SBUF,发出数据
	while(TI == 0); // 等待发送完成
	TI = 0;    // 清除发送完成标志
	return ch;
}

Wave.c

#include <Wave.h>

void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 38;//38
	while (--i);
}

void Ut_Wave_Init()
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		Tx = 1;
		Delay12us();
		Tx = 0;
		Delay12us();
	}
}

unsigned char Ut_Wave_String()
{
	unsigned int time;
	CH = CL =0;
	CMOD = 0x00;
	EA = 0;
	Ut_Wave_Init();
	EA = 1;
	CR = 1;
	while(Rx && !CF);
	CR = 0;
	if(!CF)
	{
		time = CH << 8| CL;
		return(0.017 * time + 3);
	}
	else
	{
		CF = 0;
		return 0;
	}
}

测试结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值