蓝桥杯嵌入式2015第六届省赛真题解答

使用最新版STM32G431系列,cubemx配置

1 题目分析

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

 

 

 

2 Cubemx配置

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

配置完成如下:

时钟树配置如下:

 3 文件移植

 

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

添加到项目中

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

添加头文后再编译一下,确保头文件和.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 "rtc.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;

//led
unsigned char LED_Value;

//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 k = 1;
unsigned char LED_FLAG = 1;//默认开
unsigned char Display_num = 0;
unsigned char SET_TIM_FLAG;
unsigned char RX_FLAG = 0;//有效数据标志位

unsigned char TX_FLAG = 0;//发送标志位 避免多次发送

RTC_DateTypeDef rtc_date;
RTC_TimeTypeDef rtc_time;
RTC_TimeTypeDef set_time;
RTC_TimeTypeDef set_time_change;

int main(void)
{

  HAL_Init();


  SystemClock_Config();

	LCD_Init();
	I2CInit();
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_RTC_Init();
  MX_USART1_UART_Init();
	
	
	HAL_UART_Receive_IT(&huart1,uart_rx_it,1);
	
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	set_time.Hours = 0;
	set_time.Minutes = 0;
	set_time.Seconds = 0;
	
//	i2cWrite(&k,0,1);
	//读取i2c中k值
	HAL_Delay(10);
	i2cRead(&k,0,1);
	

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

}


void lcdPro(void)
{
	if(uwTick - uwtick_Lcd<50) return;
	uwtick_Lcd = uwTick;
	
	
	//时间处理
	HAL_RTC_GetDate(&hrtc,&rtc_date,FORMAT_BIN);
	HAL_RTC_GetTime(&hrtc,&rtc_time,FORMAT_BIN);
	//判断定时时间
	if(rtc_time.Hours==set_time.Hours&&rtc_time.Minutes == set_time.Minutes&&rtc_time.Seconds == set_time.Seconds)
	{
		if(TX_FLAG == 0)
		{
			sprintf(uart_tx,"%4.2f+%3.1f+%02d%02d%02d\n",ADCR38,k*0.1,rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);
			HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
			TX_FLAG = 1;
		}
	}
	else
	{
		TX_FLAG = 0;
	}
	
	if(page == 1)
	{
		sprintf((char *)str,"V1:%4.2fV",ADCR38);
		LCD_DisplayStringLine(Line0,str);
		
		sprintf((char *)str,"k:%3.1f",k*0.1);
		LCD_DisplayStringLine(Line1,str);
		
		if(LED_FLAG == 0)
		{
			sprintf((char *)str,"LED:OFF  ");
		}
		else
		{
			sprintf((char *)str,"LED:ON  ");		
		}
		LCD_DisplayStringLine(Line2,str);
		
		sprintf((char *)str,"T:%02d-%02d-%02d",rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);
		LCD_DisplayStringLine(Line3,str);
		
		
		
	}
	else
	{
		sprintf((char *)str,"Setting");
		LCD_DisplayStringLine(Line1,str);
		
		if(Display_num == 0)
		{
			sprintf((char *)str,"T:%02d-%02d-%02d",set_time.Hours,set_time.Minutes,set_time.Seconds);
		}
		else  //设置状态闪烁
		{
			if(SET_TIM_FLAG<4)//200ms
			{
				if(Display_num == 1)
					sprintf((char *)str,"T:  -%02d-%02d",set_time_change.Minutes,set_time_change.Seconds);
				else if(Display_num == 2)
					sprintf((char *)str,"T:%02d-  -%02d",set_time_change.Hours,set_time_change.Seconds);
				else if(Display_num == 3)
					sprintf((char *)str,"T:%02d-%02d-  ",set_time_change.Hours,set_time_change.Minutes);
			}
			else
			{
				sprintf((char *)str,"T:%02d-%02d-%02d",set_time_change.Hours,set_time_change.Minutes,set_time_change.Seconds);
			}
			SET_TIM_FLAG ++;
			if(SET_TIM_FLAG > 7)
			{
				SET_TIM_FLAG = 0;
			}
		}
		LCD_DisplayStringLine(Line3,str);
	}
	
}

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)
	{
		if(LED_FLAG == 0)
			LED_FLAG = 1;
		else
			LED_FLAG = 0;
	}
	else if(Key_Dowm == 2)
	{
		LCD_Clear(Blue);
		if(page == 1)
		{
			page = 2;
			set_time_change = set_time; //
		}
		else //更新数值
		{
			page = 1;
			set_time = set_time_change;
		}
	}
	else if(Key_Dowm == 3)
	{
		if(Display_num == 0)
			Display_num = 1;
		else if(Display_num == 1)
			Display_num = 2;
		else if(Display_num == 2)
			Display_num = 3;
		else
			Display_num = 1;
	}
	else if(Key_Dowm == 4)
	{
		if(page == 2)
		{
			if(Display_num == 1)
			{
				set_time_change.Hours++;
				if(set_time_change.Hours == 60)
					set_time_change.Hours = 0;
			}
			else if(Display_num == 2)
			{
				set_time_change.Minutes++;
				if(set_time_change.Minutes == 60)
					set_time_change.Minutes = 0;			
			}
			else if(Display_num == 3)
			{
				set_time_change.Seconds++;
				if(set_time_change.Seconds == 60)
					set_time_change.Seconds = 0;			
			}
		}
	}
	
}

void ledPro(void)
{
	if(uwTick - uwtick_Led<200) return;
	uwtick_Led = uwTick;
	
	if(ADCR38>3.3*k*0.1)
	{
		LED_Value^=0x1;
	}
	else
	{
		LED_Value= 0;
	}
	
	if(LED_FLAG)
	{
		Led_Disp(LED_Value);
	}
	
}

void ADCPro(void)
{
	if(uwTick - uwtick_ADC<50) return;
	uwtick_ADC = uwTick;
	
	ADCR38 = GetADC1_R38()*3.3/4096;
	ADCR37 = GetADC2_R37()*3.3/4096;
}


//接受中断  状态机控制接受流程
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
					
	if(uart_rx_it[0] == 'k'&&RX_FLAG == 0)  //有效
	{
		RX_FLAG = 1;
		uwtick_rx_it = uwTick; //开始计时
	}	
	else if(RX_FLAG == 1)   //0
	{
		if(uart_rx_it[0]=='0')
		{
			uart_rx[0] = uart_rx_it[0];
			RX_FLAG++;
		}
		else  //数据无效
		{
			RX_FLAG = 0;
		}
	}
	else if(RX_FLAG == 2) //.
	{
		if(uart_rx_it[0]=='.')
		{
			uart_rx[1] = uart_rx_it[0];
			RX_FLAG++;
		}
		else  //数据无效
		{
			RX_FLAG = 0;
		}
	}
	else if(RX_FLAG == 3) //k
	{
						
		if(uart_rx_it[0]>='0'&&uart_rx_it[0]<='9')//接受成功
		{
			uart_rx[2] = uart_rx_it[0];
			RX_FLAG = 0;
			//更新k值,并保存
			k = uart_rx[2] - 0x30;
			i2cWrite(&k,0,1);		
			//返回ok
			sprintf(uart_tx,"ok\n");
			HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);			
		}
		else
		{
			RX_FLAG = 0;
		}
	}
//	else if(RX_FLAG == 4)  //\n
//	{
//		if(uart_rx_it[0] == 10)  //接受成功
//		{
//			uart_rx[3] = uart_rx_it[0];
//			RX_FLAG = 0;
//			//更新k值,并保存
//			k = uart_rx[2] - '0';
//			i2cWrite(&k,0,1);		
//			//返回ok
//			sprintf(uart_tx,"ok\n");
//			HAL_UART_Transmit(&huart1,(unsigned char *)uart_tx,strlen(uart_tx),50);
//		}
//		else
//		{
//			RX_FLAG = 0;
//		}
//	}
	
	if(uwTick-uwtick_rx_it>200)//超时
	{
		RX_FLAG = 0;
	}
	
	
	HAL_UART_Receive_IT(&huart1,uart_rx_it,1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值