写一个STM32L051C8T6的代码,使用HAL库,使用内部EEPROM存储,要求上电发送进入地址设置指令,进入地址设定状态,保证7个RGBLED灭,然后在对应地址放入瓶子,轮询三次,相应的RGBLED闪三下,LED闪三下一样的绿色则最后显示绿灯,LED闪三下不同的(绿色或红色)则最后显示红灯,显示绿灯则串口1显示正确的地址,显示红灯则不显,当地址设定正确后,地址设定状态结束,进入工作状态,运行其他工作代码
时间: 2023-10-02 14:12:09 浏览: 79
以下是一个可能的实现代码,需要根据具体硬件和接口进行调整:
```
#include "stm32l0xx_hal.h"
#include <string.h>
#define EEPROM_START_ADDR 0x08080000 // 内部EEPROM地址
#define ADDR_SET_CMD 0xA5 // 进入地址设置模式的指令
#define LED_PORT GPIOA
#define LED_PIN_1 GPIO_PIN_1
#define LED_PIN_2 GPIO_PIN_2
#define LED_PIN_3 GPIO_PIN_3
#define GREEN_LED_ON HAL_GPIO_WritePin(LED_PORT, LED_PIN_1, GPIO_PIN_RESET)
#define GREEN_LED_OFF HAL_GPIO_WritePin(LED_PORT, LED_PIN_1, GPIO_PIN_SET)
#define RED_LED_ON HAL_GPIO_WritePin(LED_PORT, LED_PIN_2, GPIO_PIN_RESET)
#define RED_LED_OFF HAL_GPIO_WritePin(LED_PORT, LED_PIN_2, GPIO_PIN_SET)
#define BLUE_LED_ON HAL_GPIO_WritePin(LED_PORT, LED_PIN_3, GPIO_PIN_RESET)
#define BLUE_LED_OFF HAL_GPIO_WritePin(LED_PORT, LED_PIN_3, GPIO_PIN_SET)
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_FLASH_Init(void);
void enter_address_setting_mode(void);
void exit_address_setting_mode(void);
void write_address_to_eeprom(uint8_t addr);
uint8_t read_address_from_eeprom(void);
void blink_leds(uint8_t color, uint8_t times);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_FLASH_Init();
// 上电发送进入地址设置指令
enter_address_setting_mode();
// 等待地址设置完成
uint8_t addr = 0;
while (addr == 0)
{
addr = read_address_from_eeprom();
HAL_Delay(100);
}
// 进入工作状态
exit_address_setting_mode();
// 运行其他工作代码
while (1)
{
// do something
}
}
void enter_address_setting_mode(void)
{
// 发送进入地址设置指令
uint8_t cmd = ADDR_SET_CMD;
HAL_UART_Transmit(&huart1, &cmd, 1, HAL_MAX_DELAY);
// 等待进入地址设置状态
HAL_Delay(1000);
// 保证RGBLED灭
BLUE_LED_OFF;
GREEN_LED_OFF;
RED_LED_OFF;
}
void exit_address_setting_mode(void)
{
// 离开地址设置状态
uint8_t cmd = 0;
HAL_UART_Transmit(&huart1, &cmd, 1, HAL_MAX_DELAY);
// 确认地址正确性
uint8_t addr = read_address_from_eeprom();
if (addr > 0 && addr < 8)
{
// 正确的地址,绿灯亮
GREEN_LED_ON;
// 显示地址
char buf[32];
sprintf(buf, "Address: %d\r\n", addr);
HAL_UART_Transmit(&huart1, (uint8_t *)buf, strlen(buf), HAL_MAX_DELAY);
}
else
{
// 错误的地址,红灯亮
RED_LED_ON;
}
}
void write_address_to_eeprom(uint8_t addr)
{
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef erase_init;
erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
erase_init.PageAddress = EEPROM_START_ADDR;
erase_init.NbPages = 1;
uint32_t page_err;
HAL_FLASHEx_Erase(&erase_init, &page_err);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, EEPROM_START_ADDR, addr);
HAL_FLASH_Lock();
}
uint8_t read_address_from_eeprom(void)
{
return *(uint8_t *)EEPROM_START_ADDR;
}
void blink_leds(uint8_t color, uint8_t times)
{
for (int i = 0; i < times; i++)
{
if (color == 0) // 红
{
RED_LED_ON;
HAL_Delay(500);
RED_LED_OFF;
HAL_Delay(500);
}
else if (color == 1) // 绿
{
GREEN_LED_ON;
HAL_Delay(500);
GREEN_LED_OFF;
HAL_Delay(500);
}
else // 红绿交替
{
RED_LED_ON;
HAL_Delay(250);
RED_LED_OFF;
GREEN_LED_ON;
HAL_Delay(250);
GREEN_LED_OFF;
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_FLASH_Init(void)
{
/* FLASH Initialization */
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t SectorError;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = EEPROM_START_ADDR;
EraseInitStruct.NbPages = 1;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
{
Error_Handler();
}
HAL_FLASH_Lock();
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED_PORT, LED_PIN_1 | LED_PIN_2 | LED_PIN_3, GPIO_PIN_RESET);
/*Configure GPIO pins : LED_PIN_1 LED_PIN_2 LED_PIN_3 */
GPIO_InitStruct.Pin = LED_PIN_1 | LED_PIN_2 | LED_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
}
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
```
阅读全文