英文:
Using Flash memory with STM32C031C6TX
问题
以下是您要翻译的内容:
"What I am trying to add is after 5 seconds of the LEDs being off, I want to save the last LED color then when I turn the LED back on it is the last color before I previously turned off the LED. What I have read online is that I should use the flash memory with my microcontroller to get the functionality I'm trying to achieve.
The microcontroller I am using is STM32C031C6TX.
I cant seem to get it working properly. This is my current setup:
Included: #include "stm32c0xx_hal_flash.h" and #define LAST_COLOR_ADDRESS ((uint32_t)0x08000000)
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdbool.h>
#include "stm32c0xx_hal_flash.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define LAST_COLOR_ADDRESS ((uint32_t)0x08000000)
/* USER CODE END PD */
void switch_off_all_leds(void)
{
uint32_t lastColor = ((__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_3) << 16) |
(__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_2) << 8) |
(__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_4)));
HAL_FLASH_Unlock();
FLASH_Erase_Sector(FLASH_SECTOR_0, FLASH_VOLTAGE_RANGE_1); // Erase the sector before programming
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, LAST_COLOR_ADDRESS, lastColor);
HAL_FLASH_Lock();
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
Full code:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // Red
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // Green
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); // Blue
uint8_t sins[360] = {
127,129,131,134,136,138,140,143,145,147,149,151,154,156,158,160,162,164,166,169,171,173,175,177,179,181,183,185,187,189,191,193,195,196,198,200,
202,204,205,207,209,211,212,214,216,217,219,220,222,223,225,226,227,229,230,231,233,234,235,236,237,239,240,241,242,243,243,244,245,246,247,248,
248,249,250,250,251,251,252,252,253,253,253,254,254,254,254,254,254,254,255,254,254,254,254,254,254,254,253,253,253,252,252,251,251,250,250,249,
248,248,247,246,245,244,243,243,242,241,240,239,237,236,235,234,233,231,230,229,227,226,225,223,222,220,219,217,216,214,212,211,209,207,205,204,
202,200,198,196,195,193,191,189,187,185,183,181,179,177,175,173,171,169,166,164,162,160,158,156,154,151,149,147,145,143,140,138,136,134,131,129,
127,125,123,120,118,116,114,111,109,107,105,103,100,98,96,94,92,90,88,85,83,81,79,77,75,73,71,69,67,65,63,61,59,58,56,54,
52,50,49,47,45,43,42,40,38,37,35,34,32,31,29,28,27,25,24,23,21,20,19,18,17,15,14,13,12,11,11,10,9,8,7,6,
6,5,4,4,3,3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,3,4,4,5,
6,6,7,8,9,10,11,11,12,13,14,15,17,18,19,20,21,23,24,25,27,28,29,31,32,34,35,37,38,40,42,43,45,47,49,50,
52,54,56,58,59,61,63,65,67,69,71,73,75,77,79,81,83,85,88,90,92,94,96,98,100,103,105,107,109,111,114,116,118,120,123,125
};
enum button_state_e {
BUTTON_NOT_PRESSED,
BUTTON_JUST_PRESSED,
BUTTON_PRESSED
};
static enum button_state_e button_state = BUTTON_NOT_PRESSED;
static uint8_t color_sequence = 0;
void red_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
void green_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0);
<details>
<summary>英文:</summary>
What I am trying to add is after 5 seconds of the LEDs being off, I want to save the last LED color then when I turn the LED back on it is the last color before I previously turned off the LED. What I have read online is that I should use the flash memory with my microcontroller to get the functionality I'm trying to achieve.
The microcontroller I am using is STM32C031C6TX.
I cant seem to get it working properly. This is my current setup:
**Included: #include "stm32c0xx_hal_flash.h" and #define LAST_COLOR_ADDRESS ((uint32_t)0x08000000)**
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------/
/ USER CODE BEGIN Includes */
#include <stdbool.h>
#include "stm32c0xx_hal_flash.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------/
/ USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------/
/ USER CODE BEGIN PD */
#define LAST_COLOR_ADDRESS ((uint32_t)0x08000000)
/* USER CODE END PD */
void switch_off_all_leds(void)
{
uint32_t lastColor = ((__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_3) << 16) |
(__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_2) << 8) |
(__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_4)));
HAL_FLASH_Unlock();
FLASH_Erase_Sector(FLASH_SECTOR_0, FLASH_VOLTAGE_RANGE_1); // Erase the sector before programming
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, LAST_COLOR_ADDRESS, lastColor);
HAL_FLASH_Lock();
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
**Full code:**
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // Red
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // Green
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); // Blue
uint8_t sins[360] = {
127,129,131,134,136,138,140,143,145,147,149,151,154,156,158,160,162,164,166,169,171,173,175,177,179,181,183,185,187,189,191,193,195,196,198,200,
202,204,205,207,209,211,212,214,216,217,219,220,222,223,225,226,227,229,230,231,233,234,235,236,237,239,240,241,242,243,243,244,245,246,247,248,
248,249,250,250,251,251,252,252,253,253,253,254,254,254,254,254,254,254,255,254,254,254,254,254,254,254,253,253,253,252,252,251,251,250,250,249,
248,248,247,246,245,244,243,243,242,241,240,239,237,236,235,234,233,231,230,229,227,226,225,223,222,220,219,217,216,214,212,211,209,207,205,204,
202,200,198,196,195,193,191,189,187,185,183,181,179,177,175,173,171,169,166,164,162,160,158,156,154,151,149,147,145,143,140,138,136,134,131,129,
127,125,123,120,118,116,114,111,109,107,105,103,100,98,96,94,92,90,88,85,83,81,79,77,75,73,71,69,67,65,63,61,59,58,56,54,
52,50,49,47,45,43,42,40,38,37,35,34,32,31,29,28,27,25,24,23,21,20,19,18,17,15,14,13,12,11,11,10,9,8,7,6,
6,5,4,4,3,3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,3,4,4,5,
6,6,7,8,9,10,11,11,12,13,14,15,17,18,19,20,21,23,24,25,27,28,29,31,32,34,35,37,38,40,42,43,45,47,49,50,
52,54,56,58,59,61,63,65,67,69,71,73,75,77,79,81,83,85,88,90,92,94,96,98,100,103,105,107,109,111,114,116,118,120,123,125
};
enum button_state_e {
BUTTON_NOT_PRESSED,
BUTTON_JUST_PRESSED,
BUTTON_PRESSED
};
static enum button_state_e button_state = BUTTON_NOT_PRESSED;
static uint8_t color_sequence = 0;
void red_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
void green_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
void blue_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 230); // Blue
};
void pink_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 50); // Blue
};
void teal_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 230); // Blue
};
void yellow_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 140); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
void orange_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 25); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
void purple_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 100); // Blue
};
void white_sequence(void) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 230); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 230); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 230); // Blue
};
void party_sequence(void) {
int i = 0;
while (1) {
for (i = 0; i < 360; i++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sins[i]); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, sins[(i + 120) % 360]); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, sins[(i + 240) % 360]); // Blue
HAL_Delay(2);
if (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) != GPIO_PIN_SET)
return;
}
}
};
void switch_off_all_leds(void)
{
uint32_t lastColor = ((__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_3) << 16) |
(__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_2) << 8) |
(__HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_4)));
HAL_FLASH_Unlock();
FLASH_Erase_Sector(FLASH_SECTOR_0, FLASH_VOLTAGE_RANGE_1);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, LAST_COLOR_ADDRESS, lastColor);
HAL_FLASH_Lock();
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, 0); // Blue
};
while (1)
{
bool pressed = (HAL_GPIO_ReadPin(Toggle_Switch_GPIO_Port, Toggle_Switch_Pin) == GPIO_PIN_SET);
switch (button_state)
{
case BUTTON_NOT_PRESSED:
if (pressed)
button_state = BUTTON_JUST_PRESSED;
break;
case BUTTON_JUST_PRESSED:
if (pressed)
{
button_state = BUTTON_PRESSED;
switch (color_sequence) {
case 0:
red_sequence();
break;
case 1:
green_sequence();
break;
case 2:
blue_sequence();
break;
case 3:
pink_sequence();
break;
case 4:
teal_sequence();
break;
case 5:
yellow_sequence();
break;
case 6:
orange_sequence();
break;
case 7:
purple_sequence();
break;
case 8:
white_sequence();
break;
case 9:
party_sequence();
break;
}
color_sequence = (color_sequence + 1) % 10;
}
else
button_state = BUTTON_NOT_PRESSED;
break;
case BUTTON_PRESSED:
if (!pressed)
{
button_state = BUTTON_NOT_PRESSED;
switch_off_all_leds();
}
break;
}
HAL_Delay(10);
}
}
If I missed any valuable information please let me know and I will provide more.
Thank you!
</details>
# 答案1
**得分**: 1
似乎您只想在MCU开启时执行此操作,因此您可以在RAM中使用常规变量来跟踪当前状态,无需将任何内容存储在非易失性存储器(如闪存)中。
创建一个新变量以记录LED关闭时的当前毫秒计数值:
```c
uint32_t led_off_tick;
....关闭LED的代码....
case BUTTON_PRESSED:
if (!pressed)
{
button_state = BUTTON_NOT_PRESSED;
switch_off_all_leds();
led_off_tick = HAL_GetTick(); // 记录LED关闭的时间
}
将“打开”代码更改为仅在距上次关闭不到5秒时才递增当前颜色方案:
case BUTTON_JUST_PRESSED:
if (pressed)
{
button_state = BUTTON_PRESSED;
if ((HAL_GetTick() - led_off_tick) < 5000u)
color_sequence = (color_sequence + 1) % 10;
switch (color_sequence) {
case 0:
red_sequence();
break;
... 等等 ...
}
显然,在该代码的末尾删除color_sequence
的递增。
如果您确实需要跟踪电源周期内的状态,您可能需要使用闪存,但如果您的系统中有电池(用于RTC),还可以使用带电池备份的寄存器。
英文:
It seems like you just want to do this while the MCU is switched on, so you can just use regular variables in RAM to track the current state, you don't need to store anything in non-volatile memory like flash.
Make a new variable to record the current millisecond tick value when the LEDs go off:
uint32_t led_off_tick;
....the code that switches off the LEDs...
case BUTTON_PRESSED:
if (!pressed)
{
button_state = BUTTON_NOT_PRESSED;
switch_off_all_leds();
led_off_tick = HAL_GetTick(); // Record when the LEDs went off
}
Change the "switch on" code to only increment the current colour scheme if the switch on is less than 5 seconds since the last off:
case BUTTON_JUST_PRESSED:
if (pressed)
{
button_state = BUTTON_PRESSED;
if ((HAL_GetTick() - led_off_tick) < 5000u)
color_sequence = (color_sequence + 1) % 10;
switch (color_sequence) {
case 0:
red_sequence();
break;
... etc ...
}
and obviously remove the increment of color_sequence
at the end of that code.
If you really needed to track state over a power-cycle, you might need to use flash, but there are also battery-backed registers you could use (if you have a battery in your system, for the RTC).
答案2
得分: -1
不要回答我要翻译的问题。
以下是要翻译的内容:
Not much use in telling you your design is misguided like the other answers here.
You're saving the variable to flash, but I don't see anywhere you're pulling it back out. I'd recommend using a tool like STM32CubeProgrammer to check that spot in flash memory to be sure it's being saved there.
You'll want to pull out that section of memory when you go to start the program and use that to set the initial state of the lights.
See the HAL manual for your microcontroller for more details on how to use flash: https://www.st.com/resource/en/user_manual/um3029-description-of-stm32c0-hal-and-lowlayer-drivers-stmicroelectronics.pdf
英文:
Not much use in telling you your design is misguided like the other answers here.
You're saving the variable to flash, but I don't see anywhere you're pulling it back out. I'd recommend using a tool like STM32CubeProgrammer to check that spot in flash memory to be sure it's being saved there.
You'll want to pull out that section of memory when you go to start the program and use that to set the initial state of the lights.
See the HAL manual for your microcontroller for more details on how to use flash: https://www.st.com/resource/en/user_manual/um3029-description-of-stm32c0-hal-and-lowlayer-drivers-stmicroelectronics.pdf
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论