【第十四届蓝桥杯单片机冲刺版】

这篇具有很好参考价值的文章主要介绍了【第十四届蓝桥杯单片机冲刺版】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【第十四届蓝桥杯单片机冲刺版】

明天就是正式比赛啦,今天可以在把各个模块练习一遍,常考的外设相关代码一定要熟练哦。
比赛时拿到资料包了,检查驱动文件,使用到的驱动文件,自己做相应的修改,确保是能够正常使用(驱动修改相关可看之前的文章)。
下面是自己将常考的外设结合一起的练习,需要完整工程的自取哈

链接:https://pan.baidu.com/s/1yc-GG_hqpqU5qzTsA8UOtA?pwd=l99q 
提取码:l99q 
--来自百度网盘超级会员V5的分享
祝大家都可以取得好成绩,有帮助就给个赞和关注吧

功能说明

下面练习中结合了温度采集、adc采集、时钟显示、超声波、频率测试、独立按键,矩阵按键、串口接收串口发送、长按等相关操作。
按键操作:
S4作为界面和模式切换(温度、电压、时间、距离)
S5 作为长按(第一次长按关闭LED显示第二次长按打开)
S6 作为长按(第一次长按关闭数码管显示第二次打开)
S7 作为向串口发送按键,会将当前界面的数据发送到串口
串口操作:
通过串口中断接收 字符A B C D 分别进行温度、电压、时间、距离界面和模式的切换并将当前界面数据发送到PC

定时器分配:

定时器1:一般用来做串口
定时器2:数码管以及一些频率变量刷新操作
定时器0:超声波或者频率

#include <STC15F2K60S2.H>
#include "iic.h"
#include "onewire.h"
#include "ds1302.h"

/*========================十四届蓝桥杯单片机考前一天冲刺=========================
@Author:小殷
@Date:2023.4.7
================================================================================*/

sbit TX = P1^0;
sbit RX = P1^1;
typedef unsigned char uchar;
typedef unsigned int  uint;
#define Control_Port(x,y)  P0 = y;P2 = x;P2 = 0
//=======================下面为变量定义==========================
uchar smg_data[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1,0xbf};
uchar smg_bit[9] = {10,10,10,10,10,10,10,10,10};               //数码管初始化全熄灭
uchar L[5];                                                    //LED操作
uchar interface = 1;                                           //界面
static uchar hour = 0,min= 0,sec = 0;                          //时分秒
static uint Temperature = 0;                                   //温度
static uint adc_volt = 0;                                      //电压
static uchar key_feq = 0;                                      //按键刷新频率
static uchar adc_feq = 0;                                      //adc采集频率
static uchar t_feq = 0;                                        //温度刷新频率
static uchar dis_feq = 0;                                      //距离刷新频率
static uchar smg_flag =1;                                      //数码管打开关闭标志
static uchar led_flag =1;                                      //led打开关闭标志
static uchar send_data_flag = 0;                               //按键发送             
static uint distance = 0;                                      //距离
uchar usart_cmd = 0;                                           //串口接收指令缓存

//=======================下面为函数声明===========================
void Timer2Init(void);		                                  //1毫秒@12.0定时器2初始化
void Delay5ms();		                                      //@12.000MHz 5ms延时
void UartInit(void);		                                  //9600bps@12.000MH串口初始化
void Send_Byte(uchar dat);                                    //发送一个字节
void Send_String(uchar *str);                                 //发送字符串
void Delay12us();		                                      //@12.000MHz    12us                        
void Send_Wave(void);                                         //发波8个40khz
uint Get_Distance(void);                                      //获取距离
void Set_DS1302_Timer(uchar hour,uchar min,uchar sec);        //设置ds1302时间
float Read_Temperature(void);                                 //温度获取
uchar Read_Key_Value(void);                                   //键值获取
uchar Read_ADC_Value(uchar addr);                             //ADC获取
void Data_Tackle_Task(void);                                  //数据处理任务
void Key_Tackle_Task(void);                                   //按键处理任务
void SMG_Display_Task(void);                                  //数码管处理任务
void Init_System(void);                                       //系统初始化
void Send_Data(uchar interface);                              //发送数据 串口相关
void Send_Volt(void);                                         //发送电压
void Send_Temperature(void);                                  //发送温度
void Send_Timer(void);                                        //发送时间
void Send_Distance(void);                                     //发送距离
//========================下面为函数实现==========================

void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初值
	T2H = 0xD1;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	IE2 |= 0x04;
	EA = 1;
}



void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}

void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC7;		//设置定时初始值
	TH1 = 0xFE;		//设置定时初始值
	ET1 = 0;		//禁止定时器%d中断
	TR1 = 1;		//定时器1开始计时
	ES = 1;
	EA = 1;
}


void Send_Byte(uchar dat)
{
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}
void Send_String(uchar *str)
{
	while(*str != '\0')
	{
		Send_Byte(*str++);
	}
}
void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}

void Send_Wave(void)
{
	uchar i = 0;
	for(i = 0;i<8;i++)
	{
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}

uint Get_Distance(void)
{
	uint dis = 0;
	TMOD &= 0xf0;
	TH0 = 0;
	TL0 = 0;
	Send_Wave();
	TR0 = 1;
	while((RX == 1) && (TF0 == 0));
	TR0 = 0;
	if(TF0 == 0)
	{
		dis = (TH0 << 8)|TL0;
		dis *= 0.017;
	}
	else
	{
		TF0 = 0;
		dis = 999;
	}
	return dis;
}

uchar Read_Key_Value(void)
{
	static uchar last_trg = 0,cnt = 0;
	uchar cur = 0,trg = 0,value = 3;
	static uint long_count = 0;
	static bit long_flag = 0;
	cur = (P3 | 0x10)^0xff;
	trg = cur^cnt & cur;
	cnt = cur;	
	if((last_trg ^ trg & last_trg) && cur)
	{
		if(cur & 0x08) value = 4;
		else if(cur & 0x04) value = 5;
		else if(cur & 0x02) value = 6;
		else if(cur & 0x01) value = 7;
	}
	last_trg = trg;
	
	if(cur)
	{
		if((!long_flag) && (++long_count == 100)) //1s
		{
			long_flag = 1;
		   if(cur & 0x04) value = 5 + 100;
			else if(cur & 0x02) value = 6 + 100;

		}
	}
	else
	{
		long_count = 0;
		long_flag = 0;
	}
	return value;
}


uchar Read_ADC_Value(uchar addr)
{
	uchar adc = 0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adc = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return adc;
}

void Set_DS1302_Timer(uchar hour,uchar min,uchar sec)
{
	Write_Ds1302_Byte(0x8e,0x00);
	Write_Ds1302_Byte(0x80,sec/10*16 + sec%10);
	Write_Ds1302_Byte(0x82,min/10*16 + min%10);
	Write_Ds1302_Byte(0x84,hour/10*16 + hour%10);
	Write_Ds1302_Byte(0x8e,0x80);
}

float Read_Temperature(void)
{
	uchar LSB = 0,MSB = 0;
	float temp = 0.0;
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	temp = ((MSB << 8)|LSB) * 0.0625;
	return temp;
}

void Key_Tackle_Task(void)
{
	uchar key_value = 0;
	if(key_feq > 10)
	{
		key_feq = 1;
		key_value = Read_Key_Value();
	}
	if(key_value == 4)
	{
		if(++interface > 4)
		{
			interface = 1;
		}
	}
	
	//长按S5 关闭LED 长按S6 关闭SMG
	else if(key_value == 105)
	{
		led_flag = !led_flag;
	}
	else if(key_value == 106)
	{
		smg_flag = !smg_flag;
	}
	//S7 将电压发送到串口
	if(key_value == 7)
	{
		send_data_flag = 1;
	}

}

//对应界面的数据发送
void Send_Data(uchar interface)
{
	switch(interface)
	{
		case 1:Send_Temperature();break;
		case 2:Send_Volt();break;
		case 3:Send_Timer();break;
		case 4:Send_Distance();break;
	}
}
void Send_Volt(void)
{
	Send_String("Volt:");
	Send_Byte(adc_volt/100+'0');
	Send_Byte('.');
	Send_Byte(adc_volt/10%10+'0');
	Send_Byte(adc_volt%10+'0');
	Send_String("v\r\n");
}
void Send_Temperature(void)
{
	Send_String("Temperature:");
	Send_Byte(Temperature/100+'0');
	Send_Byte(Temperature/10%10+'0');
	Send_Byte('.');
	Send_Byte(Temperature%10+'0');
	Send_String("℃\r\n");
}
void Send_Timer(void)
{
	Send_String("Time:");
	Send_Byte(hour/10+'0');
	Send_Byte(hour%10+'0');
	Send_Byte(':');
	Send_Byte(min/10+'0');
	Send_Byte(min%10+'0');
	Send_Byte(':');
	Send_Byte(sec/10+'0');
	Send_Byte(sec%10+'0');
	Send_String("\r\n");
}

void Send_Distance(void)
{
	Send_String("Dis:");
	if(distance > 99)
	{
		Send_Byte(distance/100+'0');
		Send_Byte(distance/10%10+'0');
		Send_Byte(distance%10+'0');
	}
	else if(distance > 9)
	{
		Send_Byte(distance/10%10+'0');
		Send_Byte(distance%10+'0');
	}
	else
	{
		Send_Byte(distance%10+'0');
	}
	Send_String("cm\r\n");
}
void Data_Tackle_Task(void)
{
	uchar time[3];
	if(T2H < 0xd9)
	{
		if(adc_feq > 150)
		{
			adc_feq = 1;
			adc_volt = Read_ADC_Value(0x03) * (5.0/255) * 100;
		}
		
		if(interface == 3)
		{
			time[0] = Read_Ds1302_Byte(0x81);
			time[1] = Read_Ds1302_Byte(0x83);
			time[2] = Read_Ds1302_Byte(0x85);
			hour = (time[2]/16*10 + time[2]%16);
			min  = (time[1]/16*10 + time[1]%16);
			sec  = (time[0]/16*10 + time[0]%16);
		}
		
		if(t_feq > 150)
		{
			t_feq = 1;
			Temperature = Read_Temperature() * 10;
		}
		
		if(dis_feq > 150)
		{
			dis_feq = 1;
			distance = Get_Distance();
		}
		

	}
	

	

	
	//LED控制
	L[1] = (interface == 1)?(1):(0);
	L[2] = (interface == 2)?(1):(0);
	L[3] = (interface == 3)?(1):(0);
	L[4] = (interface == 4)?(1):(0);
	
	//串口发送
	if(send_data_flag)
	{
		send_data_flag = 0;
		Send_Data(interface);
	}
	
	//串口控制界面切换
	switch(usart_cmd)
	{
		case 'A':interface = 1;Send_Data(interface);break;  //温度
		case 'B':interface = 2;Send_Data(interface);break;  //电压
		case 'C':interface = 3;Send_Data(interface);break;  //时间
		case 'D':interface = 4;Send_Data(interface);break;  //距离
		default:break;
	}
	usart_cmd = 0;
	
}
void SMG_Display_Task(void)
{
	if(interface == 1)
	{
		smg_bit[1] = 11;
		smg_bit[2] = interface;
		smg_bit[3] = 10;
		smg_bit[4] = 10;
		smg_bit[5] = 10;
		smg_bit[6] = Temperature/100;
		smg_bit[7] = Temperature/10%10;
		smg_bit[8] = Temperature%10;
	}
	else if(interface == 2)
	{
		smg_bit[1] = 11;
		smg_bit[2] = interface;
		smg_bit[3] = 10;
		smg_bit[4] = 10;
		smg_bit[5] = 10;
		smg_bit[6] = adc_volt/100;
		smg_bit[7] = adc_volt/10%10;
		smg_bit[8] = adc_volt%10;
	}
	else if(interface == 3)
	{
		smg_bit[1] = hour/10;
		smg_bit[2] = hour%10;
		smg_bit[3] = 12;
		smg_bit[4] = min/10;
		smg_bit[5] = min%10;
		smg_bit[6] = 12;
		smg_bit[7] = sec/10;
		smg_bit[8] = sec%10;
	}
	else if(interface == 4)
	{
		smg_bit[1] = 11;
		smg_bit[2] = interface;
		smg_bit[3] = 10;
		smg_bit[4] = 10;
		smg_bit[5] = 10;
		smg_bit[6] = (distance>99)?(distance/100):(10);
		smg_bit[7] = (distance>9)?(distance/10%10):(10);
		smg_bit[8] = distance%10;
	}
}

void Init_System(void)
{
	Control_Port(0x080,0xff);
	Control_Port(0xa0,0x00);
	Control_Port(0xc0,0x00);
	
	while(t_feq++ < 150)
	{
		Temperature = Read_Temperature() * 10;
	}
	UartInit();
	Delay5ms();
	Timer2Init();
	Set_DS1302_Timer(11,59,50);
	Send_String("Usart Test\r\n");
}

void main(void)
{
	Init_System();
	while(1)
	{
		Data_Tackle_Task();
		Key_Tackle_Task();
		SMG_Display_Task();
	}
}


void Timer2_Server() interrupt 12
{
	static uchar dsp_smg = 1;
	if(led_flag)
	{
		Control_Port(0x80,~(L[1] << 0 | L[2] << 1 | L[3] <<2 | L[4] << 3));
	}
	else
	{
		Control_Port(0x80,0xff);
	}
	Control_Port(0xc0,0x00);
	if(smg_flag)
	{
		if((interface == 1 && dsp_smg == 7) || (interface == 2 && dsp_smg == 6))
		{
			Control_Port(0xe0,smg_data[smg_bit[dsp_smg]] & 0x7f);
		}
		else
		{
			Control_Port(0xe0,smg_data[smg_bit[dsp_smg]]);
		}
		
		Control_Port(0xc0,1 << (dsp_smg - 1));
		if(++dsp_smg > 8)
		{
			dsp_smg = 1;			
		}
	}
	else
	{
		Control_Port(0xc0,0x00);
	}
	key_feq++;
	t_feq++;
	adc_feq++;
	dis_feq++;
}

void Usart_Server() interrupt 4
{
	if(RI)
	{
		RI = 0;
		usart_cmd = SBUF;
	}
}

由于超声波和频率都是用定时器0,上面工程中使用的是超声波,频率部分请看下面哈

//频率测量在定时器2中断中进行 (定时器0)
void Init_Timer0(void)
{
	AUXR = 0x80;
	TMOD = 0x04;
	TH0  = 0;
	TL0  = 0;
	TR0  = 1;
}
void Timer2_Server() interrupt 12
{
	static uchar dsp_smg = 1;
	static uint feq_count;

	if(++feq_count == 500)
	{
		feq_count = 0;
		TR0 = 0
		Feq = ((uint)(TH0 << 8) | TL0) * 2;
		TH0 = TL0 = 0;
		TR0 = 1;
	}

	Control_Port(0xc0,0x00);
	Control_Port(0xe0,smg_data[smg_bit[dsp_smg]]);
	Control_Port(0xc0,1 << (dsp_smg -1));
	if(++dsp_smg > 8)
	{
		dsp_smg = 1;
	}
}

【第十四届蓝桥杯单片机冲刺版】文章来源地址https://www.toymoban.com/news/detail-426806.html

到了这里,关于【第十四届蓝桥杯单片机冲刺版】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 蓝桥杯十四届单片机省赛

    【失败的博主】蓝桥杯最后一文 感想 : 练完省赛题就去练国赛题!!! 1.B站小蜜蜂老师(基础模块 )(容易听懂) 2.做一套省赛题、你会发 现无法把模块结合起来。 3.学整体代码的思想(关键!!!) 来源:电子设计工坊、四梯科技、官方源代码、其他人做的题; 4.形成自

    2023年04月10日
    浏览(65)
  • 蓝桥杯十四届单片机国赛试题及代码

        今年十四届单片机国赛试题在程序题设计方面难度有所下降,但选择题没有了以往可以在手册中可以找到的单片机类选择题,选择题难度较高,因此想获得一个不错的成绩,需要在选择题方面有所加强 此次国赛采用了温度传感器DS18B20模块,LED模块,按键模块,Pcf8591DAC模

    2024年02月13日
    浏览(41)
  • 2023年第十四届蓝桥杯单片机开放与设计省赛微析与经验分享

    前言:        2023年4月8日, 就在昨天,本人刚参与了第十四届蓝桥杯单片机开放与设计省赛。         整体做下来,且不谈客观题,今年的程序题,个人感觉有点像大杂烩,题量大,细节多,而且有些要求定义不够清晰,所以本人这次做的不够完美,并且因为时间问题有

    2024年02月08日
    浏览(57)
  • 【第十四届蓝桥杯单片机组客观题1】

    以下客观题来自4T测评的模拟题,希望可以帮助到大家,加油丫 1、C 若希望将IAP15F2K61S2单片机的IO口输出电流能力较强,应将IO配置为( )模式。 IAP15F2K61S2单片机的IO口输出电流能力较强,应将IO配置为推挽输出模式。 2、A 当下列IAP15F2K61S2单片机的中断源同时发出中断请求时

    2023年04月09日
    浏览(40)
  • 蓝桥杯单片机 第十二届 国赛

    蓝桥杯第十二届,模块都比较常规,感觉都和省赛差不多,主要是麻烦在数据处理上,而我们处理的数据又要在界面中显示出来。 对比之前的第十届,其实题目差不多,并且少了串口收发这一比较难的模块。但是多了max,min,avg三个超声波数据的处理。所以按道理时间方面应该

    2023年04月08日
    浏览(51)
  • 蓝桥杯单片机第十三届国赛客观题(深夜学习——单片机)

    1.填空题 (2)不同的地址范围: data:0x00-0xff idata:0x0000-0xffff xdata:0x0000-0xffff pdata:0x00-0xff code:0x0000-0xffff 2.选择题 (3)模电——》多级放大电路 (6)DS18B20 (7)模电——》二极管  (8)单片机      

    2024年02月11日
    浏览(67)
  • 第十二届蓝桥杯单片机省赛

    直接复制粘贴然后运行 然后打开stc烧录到开发板上面就能用 程序哪里不懂的话问我,我闲的蛋疼! #include STC15F2K60S2.H #include intrins.h unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xc6,0x8c,0x88}; unsigned char yi,er,san,si,wu,liu,qi,ba; l

    2023年04月09日
    浏览(59)
  • 蓝桥杯单片机学习14——第十三届省赛题

    上期我们学习了NE555方波发生器频率测量,讲到我会更新之后省赛的题目,那么,他来了。 首先声明:我还没有参加蓝桥杯单片机比赛,也没有拿过奖,所以我写的代码注定不会那么完美,存在BUG是必然的,我写这个系列的目的纯粹是为了记录我的学习………… 关于功能描述

    2024年02月06日
    浏览(56)
  • 蓝桥杯单片机学习15——第十二届省赛题

    书接上文,上期我们基本完成了十三届省赛题,但还是存在一些问题,本期我将对上期存在的一些问题,提出一些解决方案,并加以实践验证可行性,废话少说,让我们往下看。 上期我们提到,数码管和LED在使用的时候会存在外设之间相互干扰的问题,在我们不断的探索之下

    2024年01月25日
    浏览(61)
  • 蓝桥杯第十三届单片机国赛程序

    写在前面: 做完总体来说感觉一年比一年难了(估计是被骂的),虽然十三届用的底层少,但是做起来困难重重。 最难的难点在于定时器安排问题。15F2K60S2系列单片机只有三个定时器,本届题目考到了频率测量、超声波、PWM输出,再加上刷新,每一个都需要一个定时器,比

    2024年02月08日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包