使用 Flash 存储器与 STM32C031C6TX

huangapple go评论85阅读模式
英文:

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&#39;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 &quot;stm32c0xx_hal_flash.h&quot; 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(&amp;htim3, TIM_CHANNEL_3) &lt;&lt; 16) |
(__HAL_TIM_GET_COMPARE(&amp;htim3, TIM_CHANNEL_2) &lt;&lt; 8) |
(__HAL_TIM_GET_COMPARE(&amp;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(&amp;htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&amp;htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&amp;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 &lt; 360; i++) {
__HAL_TIM_SET_COMPARE(&amp;htim3, TIM_CHANNEL_3, sins[i]); // Red
__HAL_TIM_SET_COMPARE(&amp;htim3, TIM_CHANNEL_2, sins[(i + 120) % 360]); // Green
__HAL_TIM_SET_COMPARE(&amp;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(&amp;htim3, TIM_CHANNEL_3) &lt;&lt; 16) |
(__HAL_TIM_GET_COMPARE(&amp;htim3, TIM_CHANNEL_2) &lt;&lt; 8) |
(__HAL_TIM_GET_COMPARE(&amp;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(&amp;htim3, TIM_CHANNEL_3, 0); // Red
__HAL_TIM_SET_COMPARE(&amp;htim3, TIM_CHANNEL_2, 0); // Green
__HAL_TIM_SET_COMPARE(&amp;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) &lt; 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

huangapple
  • 本文由 发表于 2023年7月28日 04:25:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76783188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定