蓝桥杯嵌入式13届省赛真题
·
一、题目展示

二、代码解析
1、头文件的相关定义与声明
#ifndef _code_h
#define _code_h
#include "stm32g4xx.h" // Device header
#include "stdio.h"
#include "string.h"
#include "stdint.h"
#include "main.h"
#include "gpio.h"
#include "lcd.h"
#include "i2c_hal.h"
#include "usart.h"
#include "tim.h"
void lcd_proc(void);
void key_proc(void);
void led_proc(u8 led_x,u8 led_mode);
u8 i2c_read(u8 addr);
void i2c_write(u8 addr,u8 data);
void uasrt_proc(void);
#endif
2、主函数的初始化
#include "code.h"
……
……
……
extern u8 REP[2];
extern double PRICE[2];
if(i2c_read(0x88)!='N'&&i2c_read(0x99)!='B')//判断是否为初次上电,是的话则设置标志位
{
i2c_write(0x88,'N');//设置标志位
i2c_write(0x99,'B');
i2c_write(0x00,REP[0]);//写入数值
i2c_write(0x01,REP[1]);
i2c_write(0x02,PRICE[0]*10);
i2c_write(0x03,PRICE[1]*10);
}
REP[0]=i2c_read(0x00);
REP[1]=i2c_read(0x01);
PRICE[0]=(double)i2c_read(0x02)/10;
PRICE[1]=(double)i2c_read(0x03)/10;
extern u8 my_pData;
HAL_UART_Receive_IT(&huart1,&my_pData,1);
while (1)
{
lcd_proc();
key_proc();
uasrt_proc();
}
3、各个模块的编写
#include "code.h"
char tx_val[10];
u8 led_it_mode;
/*-----------------------------lcd--------------------------------*/
u8 ui;//界面参数
char lcd_val[30];//lcd显示数组
u8 SHOP[2],REP[2]={10,10};
double PRICE[2]={1.0,1.0};
void lcd_proc(void)
{
if(ui==0)
{
sprintf(lcd_val," SHOP ");
LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
sprintf(lcd_val," X:%d ",SHOP[0]);
LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
sprintf(lcd_val," Y:%d ",SHOP[1]);
LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
// sprintf(lcd_val," %d %d ",i2c_read(0x00),i2c_read(0x01));
// LCD_DisplayStringLine(Line8,(u8 *)lcd_val);
// sprintf(lcd_val," %.1f %.1f ",(double)i2c_read(0x02)/10,(double)i2c_read(0x03)/10);
// LCD_DisplayStringLine(Line9,(u8 *)lcd_val);
}
else if(ui==1)
{
sprintf(lcd_val," PRICE ");
LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
sprintf(lcd_val," X:%.1f ",PRICE[0]);
LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
sprintf(lcd_val," Y:%.1f ",PRICE[1]);
LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
}
else
{
sprintf(lcd_val," REP ");
LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
sprintf(lcd_val," X:%d ",REP[0]);
LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
sprintf(lcd_val," Y:%d ",REP[1]);
LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
}
}
/*-----------------------------key--------------------------------*/
u8 key_val[4];
u8 key_old[4];
u8 key;
void key_proc(void)
{
for(u8 i=0;i<4;i++)
{
key_val[i] = HAL_GPIO_ReadPin(i<3?GPIOB:GPIOA,GPIO_PIN_0<<i%3);
}
for(u8 i=0;i<4;i++)
{
if(key_val[i]==0&&key_old[i]==1)
{
HAL_Delay(20);
if(key_val[i]==0&&key_old[i]==1)
{
key=i+1;
}
}
}
for(u8 i=0;i<4;i++)
{
key_old[i]=key_val[i];
}
switch(key)
{
case 1:
{
ui++;
ui%=3;
LCD_Clear(Black);
SHOP[0]=SHOP[1]=0;
break;
}
case 4:
{
if(ui==0)
{
REP[0]=REP[0]-SHOP[0];
REP[1]=REP[1]-SHOP[1];
sprintf(tx_val,"X:%d,Y:%d,Z:%.1f",SHOP[0],SHOP[1],SHOP[0]*PRICE[0]+SHOP[1]*PRICE[1]);
HAL_UART_Transmit(&huart1,(u8 *)tx_val,strlen(tx_val),50);
SHOP[0]=SHOP[1]=0;
i2c_write(0x00,REP[0]);
i2c_write(0x01,REP[1]);
TIM3->CNT=0;
led_proc(1,1);
TIM2->CCR2=30;
}
break;
}
default ://按下B2和B3时
{
if(key)
{
if(ui==0)
{
SHOP[key-2]++;
if(SHOP[key-2]>REP[key-2])
SHOP[key-2]=0;
}
else if(ui==1)
{
PRICE[key-2]+=0.1;
if(PRICE[key-2]>2.1)
PRICE[key-2]=1.0;
i2c_write(0x02+key-2,PRICE[key-2]*10);
}
else
{
REP[key-2]++;
i2c_write(0x00+key-2,REP[key-2]);
}
}
}
}
key=0;
if(TIM3->CNT>50000)
{
led_proc(1,0);
TIM2->CCR2=5;
}
if(REP[0]==0&&REP[1]==0)led_proc(2,led_it_mode);
else led_proc(2,0);
}
/*-----------------------------led--------------------------------*/
void led_proc(u8 led_x,u8 led_mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
if(led_mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led_x-1),GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led_x-1),GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
/*-----------------------------usart--------------------------------*/
u8 my_pData;
char rx_val[10];
u8 count;
u8 rx_flag;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
rx_val[count]=my_pData;
count++;
rx_flag=1;
TIM6->CNT=0;;
HAL_UART_Receive_IT(&huart1,&my_pData,1);
}
void uasrt_proc(void)
{
if(rx_flag==1)
{
if(TIM6->CNT>20)
{
if(rx_val[0]=='?')
{
sprintf(tx_val,"X:%.1f,Y:%.1f",PRICE[0],PRICE[1]);
HAL_UART_Transmit(&huart1,(u8 *)tx_val,strlen(tx_val),50);
}
memset(rx_val,NULL,strlen(rx_val));
count=0;
rx_flag=0;
}
}
}
/*-----------------------------tim--------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM4)
led_it_mode=!led_it_mode;
}
u8 i2c_read(u8 addr)
{
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0xA1);
I2CWaitAck();
u8 data=I2CReceiveByte();
I2CSendNotAck();
I2CStop();
HAL_Delay(20);
return data;
}
void i2c_write(u8 addr,u8 data)
{
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
HAL_Delay(20);
}
三、结语
难度还好,这一套应该注意I2C的使用,因为I2C的读取很慢,而这题又涉及到led闪烁,如果你频繁的使用I2C进行数据的读取,你会发现led的闪烁频率是不正常的。
更多推荐
所有评论(0)