蓝桥杯嵌入式2016第七届省赛真题解答

1 题目分析

使用到的外设:LED、LCD、按键、串口、ADC、I2C。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_14,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_18,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_13,color_FFFFFF,t_70,g_se,x_16

2 Cubemx配置

外设具体方法参考我写的其他文章

配置完成如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_16,color_FFFFFF,t_70,g_se,x_16

时钟树配置如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_20,color_FFFFFF,t_70,g_se,x_16 

 3 文件移植 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_16,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_15,color_FFFFFF,t_70,g_se,x_16

其中灯和按键程序自己添加 

添加到项目中

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_14,color_FFFFFF,t_70,g_se,x_16

先编译,左边会显示出添加的文件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGnmn5DlvIDov4flhYnvvIg15Z2X77yJ,size_12,color_FFFFFF,t_70,g_se,x_16 

添加头文后再编译一下,确保头文件和.c文件都被正确引用

4 代码

所有的外设配置Cubemx都配置好了,无需自己配置(巨省工作量)

下面介绍自己添加的部分

4.1 led和Key部分

头文件 ledAndKey.h

#include "main.h"
void Led_Disp(unsigned char c);
unsigned char Key_Scan(void);

 .c文件

#include "ledAndKey.h"
 
//灯
void Led_Disp(unsigned char c)
{
	//全部熄灭
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
	  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
	//点亮对应位
	  HAL_GPIO_WritePin(GPIOC, c<<8, GPIO_PIN_RESET);
	  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
 
//按键扫描
unsigned char Key_Scan(void)
{
	unsigned char c;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)
	{
		c = 1;
	}
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET)
	{
		c = 2;
	}
	else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET)
	{
		c = 3;
	}
	else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)
	{
		c = 4;
	}
	
	return c;
}

4.2 ADC部分

ADC文件最后添加两个函数

int GetADC1_R38(void);
int GetADC2_R37(void);
int GetADC1_R38(void)
{
	int a;
	HAL_ADC_Start(&hadc2);
	a = HAL_ADC_GetValue(&hadc2);
	return a;
}
 
int GetADC2_R37(void)
{
	int a;
	HAL_ADC_Start(&hadc1);
	a = HAL_ADC_GetValue(&hadc1);
	return a;
}

4.3 i2c部分

添加读和写两个函数

void i2cWrite(unsigned char *p,unsigned char addr,unsigned char num);
void i2cRead(unsigned char *p,unsigned char addr,unsigned char num);
void i2cWrite(unsigned char *p,unsigned char addr,unsigned char num)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(addr);
	I2CWaitAck();
	
	while(num--)
	{
		I2CSendByte(*p++);
		I2CWaitAck();
	}
	I2CStop();
	delay1(500);
}
 
void i2cRead(unsigned char *p,unsigned char addr,unsigned char num)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(addr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	
	while(num--)
	{
		*p++ = I2CReceiveByte();
		if(num)
			I2CSendAck();
		else
			I2CSendNotAck();		
	}
		I2CStop();
}

4.4 主函数部分

#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"
#include "ledAndKey.h"
#include <stdio.h>
#include "i2c - hal.h"
#include "lcd.h"


void SystemClock_Config(void);
void keyPro(void);
void lcdPro(void);
void ledPro(void);
void ADCPro(void);


//dida
__IO uint32_t uwtick_Key,uwtick_Lcd,uwtick_Led,uwtick_ADC,uwtick_rx_it;

//key
unsigned char Key_Value,Key_Old,Key_Up,Key_Dowm;

//adc
double ADCR37,ADCR38;
double adc_value[3]; //滤波器太长会有延迟,是否是题中所述?
double adc_value1;
unsigned char adc_index = 1;

//led
unsigned char LED_Value;
unsigned char Led_index = 0;
unsigned char Led2_flag = 0;
unsigned char Led3_flag = 0;
//user
unsigned char page = 1;
unsigned char str[20];
unsigned char uart_rx_it[1];
//unsigned char uart_rx[5];
char uart_tx[20];

unsigned char high;
unsigned char level = 0;
unsigned char level_old = 0;

unsigned char set_L1 = 30;
unsigned char set_L2 = 50;
unsigned char set_L3 = 70;

unsigned char set_L11;
unsigned char set_L22;
unsigned char set_L33;

unsigned char i2ctxbuf[3];
unsigned char i2crxbuf[3];

unsigned char set_num = 0; //设置参数选择

int main(void)
{

  HAL_Init();


  SystemClock_Config();
	LCD_Init();
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_USART1_UART_Init();
	I2CInit();
	
	HAL_UART_Receive_IT(&huart1,uart_rx_it,1);
	
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	ADCR38 = GetADC1_R38()*3.3/4096;
	for(int i = 0;i<3;i++)  //均值滤波初始化
	{
		adc_value[i] =  ADCR38;
	}
	
//	i2ctxbuf[0] = set_L1;
//	i2ctxbuf[1] = set_L2;
//	i2ctxbuf[2] = set_L3;
//	
//	i2cWrite(i2ctxbuf,0,3);	
//	HAL_Delay(10);
	i2cRead(i2crxbuf,0,3);
	set_L1 = i2crxbuf[0];
	set_L2 = i2crxbuf[1];
	set_L3 = i2crxbuf[2];


  while (1)
  {
		keyPro();
		ADCPro();
		ledPro();
		lcdPro();
  }

}

//lcd显示
void lcdPro(void)
{
	if(uwTick - uwtick_Lcd<50) return;
	uwtick_Lcd = uwTick;
	
	if(page == 1)
	{
		sprintf((char *)str,"  Liquid Level");		
		LCD_DisplayStringLine(Line1,str);	

		sprintf((char *)str," Height: %d",high);		
		LCD_DisplayStringLine(Line3,str);			

		sprintf((char *)str," ADC: %4.2f",adc_value1);		
		LCD_DisplayStringLine(Line5,str);		

		sprintf((char *)str," Level: %d",level);		
		LCD_DisplayStringLine(Line7,str);				
	}
	else //
	{
		sprintf((char *)str,"  Parameter Setup");		
		LCD_DisplayStringLine(Line1,str);	
		if(set_num == 0)
		{
			sprintf((char *)str," Threshold 1: %02d",set_L1);		
			LCD_DisplayStringLine(Line3,str);	
			sprintf((char *)str," Threshold 2: %02d",set_L2);		
			LCD_DisplayStringLine(Line5,str);		
			sprintf((char *)str," Threshold 3: %02d",set_L3);		
			LCD_DisplayStringLine(Line7,str);				
		}
		else
		{
			if(set_num == 1)
			{
					LCD_SetTextColor(Green);
			}
			else
			{
					LCD_SetTextColor(White);
			}
			sprintf((char *)str," Threshold 1: %02d",set_L11);		
			LCD_DisplayStringLine(Line3,str);	

			if(set_num == 2)
			{
					LCD_SetTextColor(Green);
			}
			else
			{
					LCD_SetTextColor(White);
			}
			sprintf((char *)str," Threshold 2: %02d",set_L22);		
			LCD_DisplayStringLine(Line5,str);	

			if(set_num == 3)
			{
					LCD_SetTextColor(Green);
			}
			else
			{
					LCD_SetTextColor(White);
			}		
			sprintf((char *)str," Threshold 3: %02d",set_L33);		
			LCD_DisplayStringLine(Line7,str);	
			LCD_SetTextColor(White);
		}
	}
}



void keyPro(void)
{
	if(uwTick - uwtick_Key<50) return;
	uwtick_Key = uwTick;
	
	Key_Value = Key_Scan();
	Key_Dowm = Key_Value&(Key_Value^Key_Old);
	Key_Up = ~Key_Value&(Key_Value^Key_Old);
	Key_Old = Key_Value;
	
	if(Key_Dowm == 1)  //页面切换
	{
		LCD_Clear(Blue);
		if(page == 1)
		{
			page = 2;
			set_L11 = set_L1;
		  set_L22 = set_L2;
		  set_L33 = set_L3;
		}
		else
		{
			page = 1;
			set_L1 = set_L11;
			set_L2 = set_L22;
			set_L3 = set_L33;
			//保存
			i2ctxbuf[0] = set_L1;
			i2ctxbuf[1] = set_L2;
			i2ctxbuf[2] = set_L3;
			i2cWrite(i2ctxbuf,0,3);

		}
	}
	else if(Key_Dowm == 2)
	{
		if(page==2)
		{
			set_num++;
			if(set_num>3)
				set_num = 1;
		}
		else
		{
			set_num = 0;
		}
	}
	else if(Key_Dowm  == 3)
	{
		if(set_num == 1)
		{
			set_L11+=5;		
			if(set_L11>=set_L22)
				set_L11 = set_L22;
			if(set_L11>=95)
				set_L11 = 95;
		}
		else if(set_num == 2)
		{
			set_L22+=5;
			if(set_L22>=set_L33)
				set_L22 = set_L33;				
			if(set_L22>=95)
				set_L22 = 95;		
		}
		else if(set_num == 3)
		{
			set_L33+=5;
			if(set_L33>=95)
				set_L33 = 95;		
		}
	}
	else if(Key_Dowm == 4)
	{
		if(set_num == 1)
		{
			set_L11-=5;
			if(set_L11<=5)
				set_L11 = 5;
		}
		else if(set_num == 2)
		{
			set_L22-=5;
			if(set_L22<=set_L11)
				set_L22 = set_L11;
			if(set_L22<=5)
				set_L22 = 5;
		}
		else if(set_num == 3)
		{
			set_L33-=5;
			if(set_L33<=set_L22)
				set_L33= set_L22;
			if(set_L33<=5)
				set_L33 = 5;	
		}	
	}
	
	
}




void ledPro(void)
{
	if(uwTick - uwtick_Led<200) return;
	uwtick_Led = uwTick;
	
	Led_index++;
	
	if(Led2_flag != 0)
	{
		LED_Value^=0x2;
		Led2_flag++;
		if(Led2_flag > 10)
			Led2_flag = 0;
	}
	
	if(Led3_flag != 0)
	{
		LED_Value^=0x4;
		Led3_flag++;
		if(Led3_flag > 10)
			Led3_flag = 0;
	}
	
	if(Led_index == 5)
	{
		LED_Value^=0x1;
		Led_index = 0;
	}
	
	Led_Disp(LED_Value);
	
}

void ADCPro(void)
{
	if(uwTick - uwtick_ADC<100) return;
	uwtick_ADC = uwTick;
	
	ADCR38 = GetADC1_R38()*3.3/4096;
	ADCR37 = GetADC2_R37()*3.3/4096;
	
	//更新队列
	int index = 1;
	while(index<=2)
	{
		adc_value[adc_index - 1] = adc_value[adc_index];
		index++;
	}
	adc_value[2] = ADCR38;
	
	adc_index++;
	if(adc_index > 10)
		adc_index = 1;
	
	if(adc_index == 1)  //1s算一次
	{
		adc_value1 = 0;
		for(int k = 0;k<3;k++)
		{
			adc_value1+=adc_value[k];
		}
		adc_value1 = adc_value1/3;
		high = adc_value1*100/3.3;
	}
	
		if(high<=set_L1)
		{
			level = 0;
		}
		else if(high<=set_L2)
		{
			level = 1;
		}
		else if(high<=set_L3)
		{
			level = 2;
		}
		else
		{
			level = 3;
		}
		
		if(level != level_old) //液位等级变化
		{
			Led2_flag = 1;
			if(level>level_old)
				sprintf(uart_tx,"A:H%02d+L%d+U\r\n",high,level);
			else 
				sprintf(uart_tx,"A:H%02d+L%d+D\r\n",high,level);
			HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
		}
		
		level_old = level;
}


//接受中断  
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(uart_rx_it[0] == 'C')
	{
		Led3_flag = 1;
		sprintf(uart_tx,"C:H%02d+L%d\r\n",high,level);
		HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
	}
	else if(uart_rx_it[0] == 'S')
	{
		Led3_flag = 1;
		sprintf(uart_tx,"S:TL%02d+TM%02d+TH%02d\r\n",set_L1,set_L2,set_L3);
		HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
	}
	
	HAL_UART_Receive_IT(&huart1,uart_rx_it,1);
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值