蓝桥杯嵌入式第六届省题


这一届的省题用到的外设比较多一点,有用到i2c、key、led、usart、rtc、adc。并且考点相对比较全一点,但我们只要会了上述的外设配置,总体的main函数的逻辑代码编写,难度不大。

题目分析

我们接下来看看任务要求:
在这里插入图片描述我们再来看看主要的考点并且分析:

RTC时钟

在这里插入图片描述
rtc时钟,并且要设置三个时分秒的变量与RTC时钟去对比,当RTC时钟与设置的阈值相等的时候上报信息。即:

unsigned char shi=0;  //上报时间:时
unsigned char fen=0;   //上报时间:分
unsigned char miao=0;  //上报时间:秒

ADC测量功能

在这里插入图片描述这里主要就是ADC的变量配置和led的显示配置、串口。我们看到题目要求说要我们要输出R32输出的电压V1的值,并且判断V1>Vddk是否成立和通过按键可关闭led闪烁、k的值可以通过串口修改。所以我们读出他的题目要求:
①输出R37模拟电压的值
②可以通过按键开启或者关闭led的闪烁功能
③当led开启闪烁的时候,判断V1>Vdd
k是否成立,成立则以0.2s闪烁,否则led不闪。
④k值可以通过串口修改并且保存于i2c。

我们这里设置led的标志位,是否闪烁的标志位、Vdd、k的初始化的值,存储R37的电压值。即:

unsigned char B1=0;    //led打开和关闭
unsigned char k=1;   //后面处理时要k/10.0
float Vdd=3.3;   //Vdd初始化的值
unsigned int adc_val;    //adc存储值

串行功能

在这里插入图片描述这里主要就是说嘛串口的要实现的功能。我们可以看出主要有两部分是要我们去实现的。“收”和“发”。

我们看设定k的时候我们就知道我们要想PC机发送“k0.x”,这里我们看到首先发送的是k,因此我们可以以这个为一个判断的条件,判断收到的数组里面的首个字符是否为k。然后我们还要将后面k设定的值传输给变量k。并且要传输给i2c。
即:

 if(Rxflay)  //接受到中断
	{
	  Rxflay=0;
		USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
		if(RxBuffer[0]=='k')
		{
		  usart_sending(USART2,"OK\n  \r\n");
			k=(RxBuffer[3]-48);  //传输给变量k
			i2c_wirth(0x01,k);
			Delay_LCD(30);
			i2c_val=i2c_read(0x01); 
		}
		memset(RxBuffer,'\0',sizeof(RxBuffer));  //清空字符串
	}

我们在看看第二部分。这里与第一部分相关联。就是上报的时钟变量与RTC时钟去对比,当RTC时钟与设置的阈值相等的时候上报信息(adc的电压值、k的值、rtc时间)。
即:

	if(((time/3600)==shi)&&(((time%3600)/60)==fen)&&(((time%3600)%60)==miao))   
	{
	  sprintf((char *)str,"%4.2f+%4.2f+%0.2d%0.2d%0.2d\r\n",(float)adc_val*3.3/4095,(float)k/10.0,time/3600,(time%3600)/60,(time%3600)%60);
		usart_sending(USART2,str);
	}

LCD显示

在这里插入图片描述
在这里插入图片描述
在LCD设置上我们看到这主要有两个界面。参数界面和设置上报时间界面
在参数界面上主要有R37模拟电压、k值、LED是否闪烁、RTC时间。
在设置界面上主要就是三个上报时钟的设置。

在lcd上也是一样的要有个标志位进行界面的切换。即为0时参数界面,为1时设定界面。
即;

unsigned char B2=0;     //界面切换

按键功能

在这里插入图片描述
在这里主要就是设定按键的功能了。我们可以看出主要有一下的几种功能:
①B1(按键1)led闪烁的打开和关闭。
②B2(按键2)界面切换设置
③B3(按键3)选择上报的参数。即高亮的设置。
④B4(按键4)对上报参数进行加的操作。

即:

unsigned char B3=0;   //高亮切换
unsigned char key_val;    //key存储值

void key_caozuo(void)
{
  key_val=key_scanf();  //读取按键值  即key_val=1时第一个按键按下 =2时第二个按键按下。。。以此类推
	if(key_val==1)  
	{
	  switch(B1)  //led开关的设置
		{
		  case 0:B1=1;break;
			case 1:B1=0;break;
		}
	}
	if(key_val==2)
	{
	  switch(B2)  //界面切换
		{
		  case 0:B2=1;break;
			case 1:B2=0;break;
		}
	}
	if(key_val==3)  //高亮切换
	{
	  switch(B3)
		{
		  case 0:B3=1;break;
			case 1:B3=2;break;
			case 2:B3=3;break;
			case 3:B3=0;break;
		}
	}
	if(key_val==4)  //上报数值的+
	{
	  if(B2==1)
		{
		  if(B3==1)  //检测为时
			{
			  if(shi!=24)
					shi++;
				 if(shi==24)
					shi=0;
			}
			if(B3==2)  //检测为分
			{
			  if(fen!=60)
					fen++;
			 if(fen==60)
					fen=0;
			}
			if(B3==3)  //检测为秒
			{
			  if(miao!=60)
				  miao++;
				 if(miao==60)
				  miao=0;
			}
		}
	}
}

这样本文对于题目要求分析全部结束,我们接下来在看看对于main函数的编写。

代码

main

#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
#include "key.h"
#include "i2c.h"
#include "rtc.h"
#include "lcd.h"

u32 TimingDelay = 0;
u8 RxBuffer[20];
u8 RxCounter=0;
u8 Rxflay=0;
u8 str[40];
unsigned char shi=0;  //上报时间:时
unsigned char fen=0;   //上报时间:分
unsigned char miao=0;  //上报时间:秒
unsigned char B1=0;    //led打开和关闭
unsigned char B2=0;     //界面切换
unsigned char B3=0;   //高亮切换
unsigned char k=1;    
float Vdd=3.3;
unsigned int adc_val;    //adc存储值
unsigned char key_val;    //key存储值
unsigned char i2c_val;
extern unsigned long time;  //rtc
void Delay_Ms(u32 nTime);
void rtc_widon(void)  //rtc时钟显示
{
	
  time=RTC_GetCounter();
	sprintf((char *)str,"   T:%0.2d-%0.2d-%0.2d   ",time/3600,(time%3600)/60,(time%3600)%60);  //拆分时分秒
	LCD_DisplayStringLine(Line7,str); 
	
}
void lcd_caozuo(void)
{
  if(B2==0)  //显示界面
	{
	  adc_val=adc_scanf();  //读取adc
		sprintf((char *)str,"   V1:%4.2fV       ",(float)adc_val*3.3/4095);
		LCD_DisplayStringLine(Line1,str);
		
		sprintf((char *)str,"   K:%4.2f       ",(float)k/10.0);
		LCD_DisplayStringLine(Line3,str);
		
		if(B1==0)  //led闪烁
		  LCD_DisplayStringLine(Line5,"   LED:OFF            ");
		else if(B1==1)  //led不闪
			LCD_DisplayStringLine(Line5,"   LED:ON             ");
		rtc_widon();     //显示时间
	}
	if(B2==1)   //设置界面
	{
		LCD_DisplayStringLine(Line1,"                        ");
		LCD_DisplayStringLine(Line7,"                        ");
		 LCD_DisplayStringLine(Line3,"      Setting         ");
		if(B3==0)      //不高亮
		{
		   sprintf((char *)str,"     %0.2d-%0.2d-%0.2d    ",shi,fen,miao);
		   LCD_DisplayStringLine(Line5,str);
		}
		if(B3==1)  //shi高亮
		{
		   sprintf((char *)str,"     %0.2d-%0.2d-%0.2d    ",shi,fen,miao);
		   LCD_DisplayStringLine(Line5,str);
			 LCD_SetBackColor(Yellow);
	     LCD_DisplayChar(Line5,(320 - (16 * 5)),str[5]);
			 LCD_DisplayChar(Line5,(320 - (16 * 6)),str[6]);
	     LCD_SetBackColor(Blue);
		}
		if(B3==2)  //fen高亮
		{
		   sprintf((char *)str,"     %0.2d-%0.2d-%0.2d    ",shi,fen,miao);
		   LCD_DisplayStringLine(Line5,str);
			
			 LCD_SetBackColor(Yellow);
	     LCD_DisplayChar(Line5,(320 - (16 * 8)),str[8]);
			 LCD_DisplayChar(Line5,(320 - (16 * 9)),str[9]);
	     LCD_SetBackColor(Blue);
		}
		if(B3==3)  //miao高亮
		{
		   sprintf((char *)str,"     %0.2d-%0.2d-%0.2d    ",shi,fen,miao);
		   LCD_DisplayStringLine(Line5,str);
			
			 LCD_SetBackColor(Yellow);
	     LCD_DisplayChar(Line5,(320 - (16 * 12)),str[12]);
			 LCD_DisplayChar(Line5,(320 - (16 * 11)),str[11]);
	     LCD_SetBackColor(Blue);
		}
		
	  
	}
}

void key_caozuo(void)
{
  key_val=key_scanf();
	if(key_val==1)
	{
	  switch(B1)  //led
		{
		  case 0:B1=1;break;
			case 1:B1=0;break;
		}
	}
	if(key_val==2)
	{
	  switch(B2)  //界面
		{
		  case 0:B2=1;break;
			case 1:B2=0;break;
		}
	}
	if(key_val==3)  //高亮
	{
	  switch(B3)
		{
		  case 0:B3=1;break;
			case 1:B3=2;break;
			case 2:B3=3;break;
			case 3:B3=0;break;
		}
	}
	if(key_val==4)
	{
	  if(B2==1)
		{
		  if(B3==1)
			{
			  if(shi!=24)
					shi++;
				 if(shi==24)
					shi=0;
			}
			if(B3==2)
			{
			  if(fen!=60)
					fen++;
			 if(fen==60)
					fen=0;
			}
			if(B3==3)
			{
			  if(miao!=60)
				  miao++;
				 if(miao==60)
				  miao=0;
			}
		}
	}
}

void usart_caozuo(void)
{
  if(Rxflay)  //接受到中断
	{
	  Rxflay=0;
		USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
		if(RxBuffer[0]=='k')
		{
		  usart_sending(USART2,"OK\n  \r\n");
			k=(RxBuffer[3]-48);
			i2c_wirth(0x01,k);
			Delay_LCD(30);
			i2c_val=i2c_read(0x01);
		}
		memset(RxBuffer,'\0',sizeof(RxBuffer));
	}
	if(((time/3600)==shi)&&(((time%3600)/60)==fen)&&(((time%3600)%60)==miao))
	{
	  sprintf((char *)str,"%4.2f+%4.2f+%0.2d%0.2d%0.2d\r\n",(float)adc_val*3.3/4095,(float)k/10.0,time/3600,(time%3600)/60,(time%3600)%60);
		usart_sending(USART2,str);
	}
}
//Main Body
int main(void)
{
	SysTick_Config(72000);

	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	i2c_init();
	usart_init();
	key_init();
	led_init();
	rtc_init();
	adc_init();
	
	while(1)
	{
	  lcd_caozuo();
		key_caozuo();
		usart_caozuo();
	}
}

//
/*void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}*/

void SysTick_Handler(void)
{
	led_init();  //不加初始化就会混乱,不知道为什么
	if(B1==0)    //led闪烁功能打开
	{
		if((float)adc_val*3.3/4095>((float)k/10.0)*Vdd)  //判断V1>Vdd*k是否成立
		{/*0.2s频率闪烁*/
		  TimingDelay++;
			if(TimingDelay<100)
				led_scanf(0,led1);
			else if(TimingDelay==200)
				TimingDelay=0;
			else if(TimingDelay>100)
				led_scanf(1,led1);
		}
	  
	}
	else if(B1==1)  //led闪烁关闭,led1关闭
	{
	  led_scanf(1,led1);
	}
	
}

现象:
在这里插入图片描述
请添加图片描述
另外,对于其他的资源(adc、rtc、usart、pwm等等)的配置在我的其他蓝桥杯嵌入式专栏里面都有写——蓝桥杯嵌入式专栏。

对于不懂的可以留言,我看到尽量去解答。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶同学要努力呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值