答主今年大二,第一次参加蓝桥杯,大概花了三个月左右的时间备考,stm32从0入门,考前把15-21年的真题撸了两遍;到后面基本可以不看任何教程完成任一年省赛的全部功能了。
考前一天晚上睡觉前,答主还把代码都看了一遍,重点看了IIC,以为万无一失了,没想到大意了 (ノへ ̄、) ≡(▔﹏▔)≡ ╯︿╰,把EEPROM读模式和写模式搞混了...........
十三届的第一场和第二场的题目都蛮简单的,答主前三个小时就已经实现除EEPEROM读数据以外的所有功能了,最后两个小时一直在盯着i2c.c找bug,直到最后十分钟才发现0xa0和0xa1写反了!!!于是迅速改代码,商品库存能实现存储了,价格死活读不出来,考试结束前两分钟带着价格无法存储的小bug提交了设计题。
然鹅,刚提交完答主就想到浮点型数据要取整后再存储,可惜已经来不及了(ノへ ̄、)(ノへ ̄、)(ノへ ̄、),改完已经没有时间压缩提交了。
唉~~~就以这一段代码浅浅纪念这三个月吧~~
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "key_led.h"
#include "lcd.h"
#include "i2c_hal.h"
/*******************************子函数声明区*********************************/
void SystemClock_Config(void);
void Key_Process(void);
void Led_Process(void);
void Lcd_Process(void);
/*******************************全局变量声明区*****************************/
__IO uint32_t uwTick_key_speed = 0;
__IO uint32_t uwTick_led_speed = 0;
__IO uint32_t uwTick_lcd_speed = 0;
__IO uint32_t uwTick_LD1_Count = 0;//LD1亮五秒计时
__IO uint32_t uwTick_LD2_Count = 0;//LD2以0.1秒闪烁计时
//按键滤波专用变量
uint8_t key_val, key_down, key_up, key_old;
//Lcd显示专用变量
unsigned char Lcd_DispString[21];
//LED显示专用变量
uint8_t led_disp_value=0;
//串口收发专用变量
uint8_t uart_rx_1B=0;//接收数据一字节
char uart_tx_str[40];//串口数据发送数组
//EEPROM专用变量
uint8_t EEPROM_Write[6] = {10, 10, 1.0, 1.0, 5, 5};//初始值
uint8_t EEPROM_Ctrl[6];//非第一次上电所用值
/***************************本题相关变量**************************/
uint8_t LCD_Page = 0;//LCD显示界面控制
uint16_t Buy_Num_X = 0;//X的购买数量
uint16_t Actually_Buy_Num_X = 0;//X的真实购买数量
uint16_t Buy_Num_Y = 0;//Y的购买数量
uint16_t Actually_Buy_Num_Y = 0;//Y的真实购买数量
float X_Price;//X的价格
float Y_Price;//Y的价格
uint16_t X_Storage_Num;//X的库存数量
uint16_t Y_Storage_Num;//Y的库存数量
uint8_t B4_Uart_Flag = 0;//串口发送控制位
float Total_Price=0;//购买商品总价
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_Key_Led_Init();
MX_TIM2_Init();
MX_UART1_Init();
I2CInit();
LCD_Init();
LCD_SetTextColor(White);
LCD_SetBackColor(Black);
LCD_Clear(Black);
HAL_UART_Receive_IT(&huart1, &uart_rx_1B, 1);//开启串口接收中断
//EEPROM
IIC_EEPROM_Read(EEPROM_Ctrl, 0, 6);
if((EEPROM_Ctrl[4]!=5)&&(EEPROM_Ctrl[5]!=5))//第一次上电判别
{
IIC_EEPROM_Write(EEPROM_Write, 0, 6);
HAL_Delay(500);
IIC_EEPROM_Read(EEPROM_Ctrl, 0, 6);
}
//启动PWM输出
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 25);//输出占空比5%
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
while (1)
{
Key_Process();
Led_Process();
Lcd_Process();
}
}
void Key_Process(void)
{
if(uwTick - uwTick_key_speed < 50) return;
uwTick_key_speed = uwTick;
key_val = Key_Scan();
key_down = key_val & (key_val ^ key_old);
key_up = ~key_val & (key_val ^ key_old);
key_old = key_val;
switch(key_down)
{
case 1://界面切换
if((LCD_Page+1) != 3)
{
LCD_Page++;
LCD_Clear(Black);
}
else
{
LCD_Page=0;
LCD_Clear(Black);
}
break;
case 2://X相关变量控制
if(LCD_Page == 0)//购买数量界面
{
if((Buy_Num_X+1)<=X_Storage_Num)
{
Buy_Num_X++;
}
}
else if(LCD_Page == 1)//商品价格界面
{
if((int)((X_Price+0.1)*10) <=20)
{
X_Price += 0.1;
}
else if((int)((X_Price+0.1)*10) >20)
{
X_Price = 1.0;
}
EEPROM_Ctrl[2] = X_Price*10;//更新X价格
IIC_EEPROM_Write(EEPROM_Ctrl, 0, 6);//将更新价格写进EEPROM
}
else if(LCD_Page == 2)//商品库存界面
{
X_Storage_Num++;
EEPROM_Ctrl[0] = X_Storage_Num;//EEPROM更新
IIC_EEPROM_Write(EEPROM_Ctrl, 0, 6);//将更新库存写进EEPROM
}
break;
case 3://Y相关变量控制
if(LCD_Page == 0)//购买数量界面
{
if((Buy_Num_Y+1)<=X_Storage_Num)
{
Buy_Num_Y++;
}
}
else if(LCD_Page == 1)//商品价格界面
{
if((int)((Y_Price+0.1)*10) <=20)
{
Y_Price += 0.1;
}
else if((int)((Y_Price+0.1)*10) >20)
{
Y_Price = 1.0;
}
EEPROM_Ctrl[3] = Y_Price*10;//更新Y价格
IIC_EEPROM_Write(EEPROM_Ctrl, 0, 6);//将更新价格写进EEPROM
}
else if(LCD_Page == 2)//商品库存界面
{
Y_Storage_Num++;
EEPROM_Ctrl[1] = Y_Storage_Num;//EEPROM更新
IIC_EEPROM_Write(EEPROM_Ctrl, 0, 6);//将更新库存写进EEPROM
}
break;
case 4://确认按键
if(LCD_Page == 0)
{
if(X_Storage_Num>=Buy_Num_X)//库存数量大于购买数量,满足购买
{
Actually_Buy_Num_X = Buy_Num_X;
X_Storage_Num -= Buy_Num_X;
}
if(Y_Storage_Num>=Buy_Num_Y)//库存数量大于购买数量,满足购买
{
Actually_Buy_Num_Y = Buy_Num_Y;
Y_Storage_Num -= Buy_Num_Y;
}
EEPROM_Ctrl[0] = X_Storage_Num;//EEPROM更新
EEPROM_Ctrl[1] = Y_Storage_Num;//EEPROM更新
IIC_EEPROM_Write(EEPROM_Ctrl, 0, 6);//将更新库存写进EEPROM
Buy_Num_X = 0;//清零
Buy_Num_Y = 0;//清零
B4_Uart_Flag = 1;
uwTick_LD1_Count = uwTick;//LD1亮开始计时
led_disp_value |= 0x01;
}
break;
}
}
void Led_Process(void)
{
if(uwTick - uwTick_led_speed < 50) return;
uwTick_led_speed = uwTick;
if(uwTick - uwTick_LD1_Count > 5000)
{
led_disp_value &= ~0x01;//时间到,熄灭LD1
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, 25);//PWM借用,输出占空比5%
}
else
{
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2 , 150);//PWM借用,输出占空比3%
}
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
if((X_Storage_Num == 0)&&(Y_Storage_Num == 0))//库存为0,LD2以0.1S闪烁
{
if(uwTick - uwTick_LD2_Count > 100)
{
led_disp_value ^= 0x02;
uwTick_LD2_Count = uwTick;
}
}
else
{
led_disp_value &= ~0x02;//熄灭LD2
}
Led_Disp(led_disp_value);
}
void Lcd_Process(void)
{
if(uwTick - uwTick_lcd_speed < 50) return;
uwTick_lcd_speed = uwTick;
X_Price = (float)EEPROM_Ctrl[2]/10.0;
Y_Price = (float)EEPROM_Ctrl[3]/10.0;
X_Storage_Num = EEPROM_Ctrl[0];
Y_Storage_Num = EEPROM_Ctrl[1];
if(LCD_Page == 0)//购买数量页面
{
sprintf((char*)Lcd_DispString, " SHOP");
LCD_DisplayStringLine(Line1, Lcd_DispString);
sprintf((char*)Lcd_DispString, " X:%d ", Buy_Num_X);
LCD_DisplayStringLine(Line3, Lcd_DispString);
sprintf((char*)Lcd_DispString, " Y:%d ", Buy_Num_Y);
LCD_DisplayStringLine(Line4, Lcd_DispString);
}
else if(LCD_Page == 1)//价格页面
{
sprintf((char*)Lcd_DispString, " PRICE");
LCD_DisplayStringLine(Line1, Lcd_DispString);
sprintf((char*)Lcd_DispString, " X:%3.1f ", X_Price);
LCD_DisplayStringLine(Line3, Lcd_DispString);
sprintf((char*)Lcd_DispString, " Y:%3.1f ", Y_Price);
LCD_DisplayStringLine(Line4, Lcd_DispString);
}
else if(LCD_Page == 2)//库存页面
{
sprintf((char*)Lcd_DispString, " REP");
LCD_DisplayStringLine(Line1, Lcd_DispString);
sprintf((char*)Lcd_DispString, " X:%02d ", X_Storage_Num);
LCD_DisplayStringLine(Line3, Lcd_DispString);
sprintf((char*)Lcd_DispString, " Y:%02d ", Y_Storage_Num);
LCD_DisplayStringLine(Line4, Lcd_DispString);
}
//串口发送数据借用
if(B4_Uart_Flag == 1)
{
//总价格折算
Total_Price = Actually_Buy_Num_X*X_Price + Actually_Buy_Num_Y*Y_Price;
sprintf(uart_tx_str, "X:%d, Y:%d, Z:%3.1f\n", Actually_Buy_Num_X, Actually_Buy_Num_Y, Total_Price);
HAL_UART_Transmit(&huart1, (unsigned char*)uart_tx_str, strlen(uart_tx_str), 50);
B4_Uart_Flag = 0;
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收完成回调函数
{
if(uart_rx_1B == '?')
{
sprintf(uart_tx_str, "X:%3.1f, Y:%3.1f\n", X_Price, Y_Price);
HAL_UART_Transmit(&huart1, (unsigned char*)uart_tx_str, strlen(uart_tx_str), 50);
}
HAL_UART_Receive_IT(&huart1, &uart_rx_1B, 1);//开启串口接收中断
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)