你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8S的EEPROM块编程问题。

[复制链接]
w453509596 提问时间:2015-6-14 18:54 /
经过小弟的一个周末的努力,终于发现STM8S不能块编程的原因了。首先STM8S的块编程,需要把程序放在RAM中运行。对于像我这样没学过汇编的,也不了解编译器原理的,只知道用C语言写写程序的朋友。有点摸不着头脑。那么如何让程序在RAM中运行呢?
我们看下STM8S的库函数数就知道了。下面是库函数的代码。

IN_RAM(void FLASH_EraseBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType));

我刚开始就被这个函数定义给骗了。以为加了IN_RAM( ),就可以在RAM中运行了。我们看下 IN_RAM() 的定义
  #define IN_RAM(a)  a
在默认情况下,它什么都没干。仔细一下,在默认情况下,是不库函数把在RAM中运行程序的功能给屏蔽了。

/* Uncomment the line below to enable the FLASH functions execution from RAM */
#if !defined (RAM_EXECUTION)
/*#define RAM_EXECUTION  (1) */
#endif /* RAM_EXECUTION */


取消掉这个注释就可以了。把它变成

/* Uncomment the line below to enable the FLASH functions execution from RAM */
#if !defined (RAM_EXECUTION)
   #define RAM_EXECUTION  (1)
#endif /* RAM_EXECUTION */


这样IN_RAM()的定义就变成了
  #define IN_RAM(a)   __ramfunc  a

再去调试程序。就好了。

自己写程序其实就是在函数前面加下  __ramfunc  


下面是我测试成功的程序


uint8_t  block_buff[128];

__ramfunc  void  WriteBlock(void)
{
  uint8_t i;

    FLASH_Unlock(FLASH_MEMTYPE_DATA);
    FLASH->CR2 |= FLASH_CR2_PRG;
    FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NPRG);

  for(i=0; i<128; i++)
  {
    *((PointerAttr uint8_t*) (MemoryAddressCast)0x4000 + i) = block_buff[i];
  }

   FLASH_Lock(FLASH_MEMTYPE_DATA);
}


祝还不会块编程的朋友们好运!!!!!




但是看门狗我还不知道原因。在接上STLINK调试的时候,看门狗会死机,但是在程序自己运行时,它就正常了








收藏 2 评论11 发布时间:2015-6-14 18:54

举报

11个回答
gameng 回答时间:2016-9-12 23:43:44
真不错!学习啦
ZHONGLAN 回答时间:2016-3-20 22:52:16
学习学习
zcl201207 回答时间:2016-3-21 21:40:13
gavinliang 回答时间:2016-9-12 16:45:00
这是因为你在解锁时,是不能设置监控的,你用STLINK调试时,在这里是容易出问题的,一般不作监控。
gavinliang 回答时间:2016-9-12 17:00:26
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "stm8s.h"
#include <stdio.h>
int _fctcpy(char name);
main()
{
u8 block_buff[128] ={0};
u8 i = 0;
u8 c = 0;
_fctcpy('F');

CLK_DeInit();
  CLK_HSICmd(ENABLE);
CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);

  UART1_DeInit();
  UART1_Init((u32)115200, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO,
UART1_SYNCMODE_CLOCK_DISABLE,UART1_MODE_TXRX_ENABLE);
  UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
  UART1_Cmd(ENABLE);
  
GPIO_DeInit(GPIOD);
  GPIO_Init(GPIOD, GPIO_PIN_LNIB, GPIO_MODE_OUT_PP_LOW_FAST);

for(i=0;i<128;i++)
   block_buff=i;

  FLASH_DeInit();
  FLASH_Unlock(FLASH_MEMTYPE_DATA);
  FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_TPROG);
  FLASH_ProgramBlock(0x0001, FLASH_MEMTYPE_DATA, FLASH_PROGRAMMODE_STANDARD, block_buff);
FLASH_EraseBlock(0x0001, FLASH_MEMTYPE_DATA);

c = FLASH_ReadByte(0x40ff);//读出值到变量中
printf("c=%x\r\n",(u16)c);//打印
c = FLASH_ReadByte(0x407f);
printf("c=%x\r\n",(u16)c);
c = FLASH_ReadByte(0x4080);
printf("c=%x\r\n",(u16)c);
c = FLASH_ReadByte(0x4100);
printf("c=%x\r\n",(u16)c);

_asm("rim");
while (1)
  {
  GPIO_WriteHigh(GPIOD, GPIO_PIN_LNIB);
}
}
char putchar (char c)    //串口打印重定向,只要有这个函数,然后包含stdio.h就可以直接调用打印函数了,若有不成功时请把参数前强转为(u16)
{
  if (c == '\n')
  {
    /* put '\r' to hardware here */
    /* Wait transmission is completed : otherwise the first data is not sent */
    while (!(UART1->SR & 0x40));
    UART1->DR = ('\r');
    /* Wait transmission is completed */
    while (!(UART1->SR & 0x40));
}
  /* put c to hardware here */
  /* Wait transmission is completed : otherwise the first data is not sent */
  while (!(UART1->SR & 0x80));
  UART1->DR = (c);
  /* Wait transmission is completed */
  while (!(UART1->SR & 0x80));
  return (c);
}
gavinliang 回答时间:2016-9-12 17:01:49
用Cosmic编译,使用ST库函数,已经调试通过,供大家参考一下。
gavinliang 回答时间:2016-9-12 17:03:20
  1. //用Cosmic编译,使用ST库函数,已经调试通过,供大家参考一下。
  2. /* MAIN.C file
  3. *
  4. * Copyright (c) 2002-2005 STMicroelectronics
  5. */
  6. #include "stm8s.h"
  7. #include <stdio.h>
  8. int _fctcpy(char name);
  9. main()
  10. {
  11. u8 block_buff[128] ={0};
  12. u8 i = 0;
  13. u8 c = 0;
  14. _fctcpy('F');

  15. CLK_DeInit();
  16.   CLK_HSICmd(ENABLE);
  17. CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);

  18.   UART1_DeInit();
  19.   UART1_Init((u32)115200, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO,
  20. UART1_SYNCMODE_CLOCK_DISABLE,UART1_MODE_TXRX_ENABLE);
  21.   UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
  22.   UART1_Cmd(ENABLE);
  23.   
  24. GPIO_DeInit(GPIOD);
  25.   GPIO_Init(GPIOD, GPIO_PIN_LNIB, GPIO_MODE_OUT_PP_LOW_FAST);

  26. for(i=0;i<128;i++)
  27.    block_buff=i;

  28.   FLASH_DeInit();
  29.   FLASH_Unlock(FLASH_MEMTYPE_DATA);
  30.   FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_TPROG);
  31.   FLASH_ProgramBlock(0x0001, FLASH_MEMTYPE_DATA, FLASH_PROGRAMMODE_STANDARD, block_buff);
  32. FLASH_EraseBlock(0x0001, FLASH_MEMTYPE_DATA);

  33. c = FLASH_ReadByte(0x40ff);//读出值到变量中
  34. printf("c=%x\r\n",(u16)c);//打印
  35. c = FLASH_ReadByte(0x407f);
  36. printf("c=%x\r\n",(u16)c);
  37. c = FLASH_ReadByte(0x4080);
  38. printf("c=%x\r\n",(u16)c);
  39. c = FLASH_ReadByte(0x4100);
  40. printf("c=%x\r\n",(u16)c);

  41. _asm("rim");
  42. while (1)
  43.   {
  44.   GPIO_WriteHigh(GPIOD, GPIO_PIN_LNIB);
  45. }
  46. }
  47. char putchar (char c)    //串口打印重定向,只要有这个函数,然后包含stdio.h就可以直接调用打印函数了,若有不成功时请把参数前强转为(u16)
  48. {
  49.   if (c == '\n')
  50.   {
  51.     /* put '\r' to hardware here */
  52.     /* Wait transmission is completed : otherwise the first data is not sent */
  53.     while (!(UART1->SR & 0x40));
  54.     UART1->DR = ('\r');
  55.     /* Wait transmission is completed */
  56.     while (!(UART1->SR & 0x40));
  57. }
  58.   /* put c to hardware here */
  59.   /* Wait transmission is completed : otherwise the first data is not sent */
  60.   while (!(UART1->SR & 0x80));
  61.   UART1->DR = (c);
  62.   /* Wait transmission is completed */
  63.   while (!(UART1->SR & 0x80));
  64.   return (c);
  65. }
复制代码
gavinliang 回答时间:2016-9-12 17:09:22
另:两把密钥的顺序不是随便的,解锁eeprom时顺序是0xae,0x56,解锁flash时顺序是0x56,0xae,我见过网上有人说顺序不分的,纠正下,不要误人子弟!顺序出错是了怎么都出不来的,ST英文原文写得很清楚了,有些翻译就是翻译错了,大家注意一下。
gavinliang 回答时间:2016-9-12 17:14:05
再贴上ST公司调用库文件的例子,供参考:
  1. /**
  2.   ******************************************************************************
  3.   * @file     FLASH/FLASH_DataProgram/main.c
  4.   * @author   MCD Application Team
  5.   * @version  V2.2.0
  6.   * @date     30-September-2014
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
  11.   *
  12.   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  13.   * You may not use this file except in compliance with the License.
  14.   * You may obtain a copy of the License at:
  15.   *
  16.   *        http://www.st.com/software_license_agreement_liberty_v2
  17.   *
  18.   * Unless required by applicable law or agreed to in writing, software
  19.   * distributed under the License is distributed on an "AS IS" BASIS,
  20.   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21.   * See the License for the specific language governing permissions and
  22.   * limitations under the License.
  23.   *
  24.   ******************************************************************************
  25.   */

  26. /* Includes ------------------------------------------------------------------*/
  27. #include "stm8s.h"
  28. #include "stm8s_eval.h"

  29. /**
  30.   * @addtogroup FLASH_DataProgram
  31.   * @{
  32.   */

  33. /* Private typedef -----------------------------------------------------------*/
  34. typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;
  35. /* Private define ------------------------------------------------------------*/
  36. #define BLOCK_OPERATION    0    /* block 0 in data eeprom memory: address is 0x4000 */
  37. /* Private macro -------------------------------------------------------------*/
  38. /* Private variables ---------------------------------------------------------*/
  39. uint8_t GBuffer[FLASH_BLOCK_SIZE];
  40. __IO TestStatus OperationStatus;

  41. #ifdef _RAISONANCE_
  42. /* needed by memcpy for raisonance */
  43. #include <string.h>
  44. extern int __address__FLASH_EraseBlock;
  45. extern int __size__FLASH_EraseBlock;
  46. extern int __address__FLASH_ProgramBlock;
  47. extern int __size__FLASH_ProgramBlock;
  48. #endif /*_RAISONANCE_*/

  49. /* Private function prototypes -----------------------------------------------*/
  50. /* Declare _fctcpy function prototype as it is packaged by default in the Cosmic
  51.    machine library */
  52. #ifdef _COSMIC_
  53. int _fctcpy(char name);
  54. #endif /*_COSMIC_*/

  55. void Delay (uint16_t nCount);
  56. static void CLK_Config(void);
  57. static void GPIO_Config(void);
  58. static void FLASH_Config(void);
  59. /* Private functions ---------------------------------------------------------*/

  60. /**
  61.   * @brief  Main program.
  62.   * @param  None
  63.   * @retval None
  64.   */
  65. void main(void)
  66. {
  67.   uint32_t add = 0, startadd = 0, stopadd = 0;
  68.   uint8_t newval = 0xAA;
  69.   uint8_t i = 0;

  70. #ifdef _COSMIC_
  71. /* Call the _fctcpy() function with the first segment character as parameter
  72.    "_fctcpy('F');"  for a manual copy of the declared moveable code segment
  73.    (FLASH_CODE) in RAM before execution*/
  74.   _fctcpy('F');
  75. #endif /*_COSMIC_*/

  76. #ifdef _RAISONANCE_
  77. /* Call the standard C library: memcpy() or fmemcpy() functions available through
  78.    the <string.h> to copy the inram function to the RAM destination address */
  79.   MEMCPY(FLASH_EraseBlock,
  80.          (void PointerAttr*)&__address__FLASH_EraseBlock,
  81.          (int)&__size__FLASH_EraseBlock);
  82.   MEMCPY(FLASH_ProgramBlock,
  83.          (void PointerAttr*)&__address__FLASH_ProgramBlock,
  84.          (int)&__size__FLASH_ProgramBlock);
  85. #endif /*_RAISONANCE_*/


  86.   /* Clock configuration -----------------------------------------*/
  87.   CLK_Config();

  88.   /* GPIO Configuration ------------------------------------------*/
  89.   GPIO_Config();

  90.   /* FLASH Configuration ------------------------------------------*/
  91.   FLASH_Config();

  92.   /* Fill the buffer in RAM */
  93.   for (i = 0; i < FLASH_BLOCK_SIZE; i++)
  94.   {
  95.     GBuffer[i] = newval;
  96.   }
  97.   /* This function is executed from RAM */
  98.   FLASH_ProgramBlock(BLOCK_OPERATION, FLASH_MEMTYPE_DATA, FLASH_PROGRAMMODE_STANDARD, GBuffer);
  99.   
  100.   /* Wait until End of high voltage flag is set*/
  101.   while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET)
  102.   {}
  103.   /* Check the programmed block */
  104.   startadd = FLASH_DATA_START_PHYSICAL_ADDRESS + ((uint16_t)BLOCK_OPERATION * (uint16_t)FLASH_BLOCK_SIZE);
  105.   stopadd = startadd + (uint16_t)FLASH_BLOCK_SIZE;
  106.   for (add = startadd; add < stopadd; add++)
  107.       {
  108.         if (FLASH_ReadByte(add) != newval)
  109.         {
  110.           /* Error */
  111.           OperationStatus = FAILED;
  112.           /* OperationStatus = PASSED, if the data written/read to/from Flash program memory is correct */
  113.           /* OperationStatus = FAILED, if the data written/read to/from Flash program memory is corrupted */
  114.           while (1)
  115.           {
  116.             STM_EVAL_LEDToggle(LED1); /*FAIL: write error */
  117.             Delay(0xFFFF);
  118.           }
  119.         }
  120.       }
  121.   /* Erase block 0 and verify it */
  122.   /* This function is executed from RAM */
  123.   FLASH_EraseBlock(BLOCK_OPERATION, FLASH_MEMTYPE_DATA);

  124.   /* Wait until End of high voltage flag is set*/
  125.   while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET)
  126.   {}

  127.   for (add = startadd; add < stopadd; add++)
  128.       {
  129.         if (FLASH_ReadByte(add) != 0x00)
  130.         {
  131.           /* Error */
  132.           OperationStatus = FAILED;
  133.           /* OperationStatus = PASSED, if the data written/read to/from Flash program memory is correct */
  134.           /* OperationStatus = FAILED, if the data written/read to/from Flash program memory is corrupted */
  135.           while (1)
  136.           {
  137.             STM_EVAL_LEDToggle(LED2); /* FAIL: Erase error */
  138.             Delay(0xFFFF);
  139.           }
  140.         }
  141.       }

  142.   /* Pass */
  143.   OperationStatus = PASSED;
  144.   /* OperationStatus = PASSED, if the data written/read to/from Flash program memory is correct */
  145.   /* OperationStatus = FAILED, if the data written/read to/from Flash program memory is corrupted */
  146.   while (1)
  147.   {
  148.     STM_EVAL_LEDToggle(LED3); /* PASS: without errors*/
  149.     Delay(0xFFFF);
  150.   }
  151. }

  152. /**
  153.   * @brief  Configure system clock to run at 16Mhz
  154.   * @param  None
  155.   * @retval None
  156.   */
  157. void CLK_Config(void)
  158. {
  159.     /* Initialization of the clock */
  160.     /* Clock divider to HSI/1 */
  161.     CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  162. }

  163. /**
  164.   * @brief  Configure GPIO for LEDs available on the evaluation board
  165.   * @param  None
  166.   * @retval None
  167.   */
  168. void GPIO_Config(void)
  169. {
  170.     /* Initialize LEDs mounted on STM8-128 EVAL board */
  171.     STM_EVAL_LEDInit(LED2);
  172.     STM_EVAL_LEDInit(LED3);
  173.     STM_EVAL_LEDInit(LED1);
  174.                
  175.                 /* All leds are Off */
  176.     STM_EVAL_LEDOff(LED2);
  177.     STM_EVAL_LEDOff(LED3);
  178.     STM_EVAL_LEDOff(LED1);
  179. }

  180. /**
  181.   * @brief  Configure the FLASH for block programming
  182.   * @param  None
  183.   * @retval None
  184.   */
  185. void FLASH_Config(void)
  186. {
  187. /* Define flash programming Time*/
  188.   FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);

  189.   FLASH_Unlock(FLASH_MEMTYPE_PROG);
  190.   /* Wait until Flash Program area unlocked flag is set*/
  191.   while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET)
  192.   {}

  193.   /* Unlock flash data eeprom memory */
  194.   FLASH_Unlock(FLASH_MEMTYPE_DATA);
  195.   /* Wait until Data EEPROM area unlocked flag is set*/
  196.   while (FLASH_GetFlagStatus(FLASH_FLAG_DUL) == RESET)
  197.   {}
  198. }

  199. /**
  200.   * @brief  Delay.
  201.   * @param  nCount
  202.   * @retval None
  203.   */
  204. void Delay(uint16_t nCount)
  205. {
  206.     /* Decrement nCount value */
  207.     while (nCount != 0)
  208.     {
  209.         nCount--;
  210.     }
  211. }

  212. #ifdef  USE_FULL_ASSERT
  213. /**
  214.   * @brief  Reports the name of the source file and the source line number
  215.   *   where the assert_param error has occurred.
  216.   * @param  file: pointer to the source file name
  217.   * @param  line: assert_param error line source number
  218.   * @retval None
  219.   */
  220. void assert_failed(uint8_t* file, uint32_t line)
  221. {
  222.   /* User can add his own implementation to report the file name and line number,
  223.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  224.   /* Infinite loop */
  225.   while (1)
  226.   {}
  227. }
  228. #endif

  229. /**
  230.   * @}
  231.   */

  232. /**
  233.   * @}
  234.   */

  235. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版