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

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****/
复制代码
jonecolu 回答时间:2018-5-5 15:09:14
不错不错,值得借鉴
sincomaster 回答时间:2018-6-26 14:46:09
谢谢大大的分享
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版