[STM8] STM8S EEPROM块编程 库函数操作之完美解析

[复制链接]
 楼主| aaronji 发表于 2012-12-20 14:43 | 显示全部楼层 |阅读模式
    众里寻她兜错路,蓦然回首,她却在那库函数!
    一直以来我未曾在网上找到一个专门解析eeprom块编程的库函数,要么遇到的就说库函数太烂了,自己写挺好,要么就是王志杰的例程,这对于初学者来说无非是件很悲催的事情,今天我就了了这个心愿,给后来者栽棵树,希望能茁壮成长!
    我个人觉得stm8s的库函数很强大,用起来很方便,看着她的源代码也是那么的有条理,堪称规范,对于初学者来说她的库函数代码很值得学习,学习她的思路,她的布局会使你获益匪浅!
    步入正题,先上代码!(我用的是STVD4.3.2 外挂Cosmic4.3.4**版)如有需要我会上传分享给大家,这里不讨论开发环境孰好孰坏,用好了奥拓便是奥迪,就这么简单!
/* 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);
}

这是我的实验例程,板子是stm8s207s6,函数的意思很明确,不再解释,下面开始解析配置步骤!
/**
@code
All the functions defined below must be executed from RAM exclusively, except
for the FLASH_WaitForLastOperation function which can be executed from Flash.

Steps of the execution from RAM differs from one toolchain to another:
- For Cosmic Compiler:
    1- Define a segment FLASH_CODE by the mean of " #pragma section (FLASH_CODE)".
    This segment is defined in the stm8s_flash.c file.
  2- Uncomment the "#define RAM_EXECUTION  (1)" line in the stm8s.h file,
    or define it in Cosmic compiler preprocessor to enable the FLASH_CODE segment
   definition.
  3- In STVD Select Project\Settings\Linker\Category "input" and in the RAM section
    add the FLASH_CODE segment with "-ic" options.
  4- In main.c file call the _fctcpy() function with first segment character as
    parameter "_fctcpy('F');" to load the declared moveable code segment
    (FLASH_CODE) in RAM before execution.
  5- By default the _fctcpy function is packaged in the Cosmic machine library,
    so the function prototype "int _fctcopy(char name);" must be added in main.c
    file.

解析(stvd+cosmic+4.0官方库函数):
  第一步:#pragma section (FLASH_CODE)库函数stm8s_flash.c中代码第520行已经有了,并且没被注释掉,原型为:
#if defined (_COSMIC_) && defined (RAM_EXECUTION)
#pragma section (FLASH_CODE)
#endif  /* _COSMIC_ && RAM_EXECUTION */

IN_RAM(FLASH_Status_TypeDef FLASH_WaitForLastOperation(FLASH_MemType_TypeDef FLASH_MemType))
{

      ......//库函数代码
}
IN_RAM(void FLASH_EraseBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType))
{

    ......库函数代码
}
IN_RAM(void FLASH_ProgramBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType,
                        FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer))
{

     ......//库函数代码
}
#if defined (_COSMIC_) && defined (RAM_EXECUTION)
/* End of FLASH_CODE section */
#pragma section ()
#endif /* _COSMIC_ && RAM_EXECUTION */


第二步:打开宏开关#define RAM_EXECUTION  (1),在stm8s.h中
#if !defined (RAM_EXECUTION)
#define RAM_EXECUTION  (1)
#endif /* RAM_EXECUTION */
第三步:工程设置
设置图.jpg
第四步:在main.c中声明int _fctcpy(char name);在主函数运行前调用_fctcpy('F');具体操作可参考主函数代码
      这几步都配置完成后就可以编译通过了,然后烧录调试完美块编程,包括快擦除等,已经验证!
      借此说下王志杰的例程我实验过,但是写0就挂掉,不知道什么原因,还有两把密钥的顺序不是随便的,解锁eeprom时顺序是0xae,0x56,解锁flash时顺序是0x56,0xae,我见过网上有人说顺序不分的,纠正下,不要误人子弟!
      网上关于stm8s的学习资料很多很泛滥,其实有用的就那点,等我抽时间整理出一套来分享,以便后人学习!
holts 发表于 2012-12-26 10:39 | 显示全部楼层
本帖最后由 holts 于 2012-12-26 10:41 编辑

很好的代码被你贴的, ,你应该象这样贴。


  1. /* MAIN.C file
  2. *
  3. * Copyright (c) 2002-2005 STMicroelectronics
  4. */
  5. #include "stm8s.h"
  6. #include <stdio.h>
  7. int _fctcpy(char name);
  8. main()
  9. {
  10. u8 block_buff[128] ={0};
  11. u8 i = 0;
  12. u8 c = 0;
  13. _fctcpy('F');

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

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

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

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

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

  40. _asm("rim");
  41. while (1)
  42.   {
  43.   GPIO_WriteHigh(GPIOD, GPIO_PIN_LNIB);
  44. }
  45. }
  46. char putchar (char c)    //串口打印重定向,只要有这个函数,然后包含stdio.h就可以直接调用打印函数了,若有不成功时请把参数前强转为(u16)
  47. {
  48.   if (c == '\n')
  49.   {
  50.     /* put '\r' to hardware here */
  51.     /* Wait transmission is completed : otherwise the first data is not sent */
  52.     while (!(UART1->SR & 0x40));
  53.     UART1->DR = ('\r');
  54.     /* Wait transmission is completed */
  55.     while (!(UART1->SR & 0x40));
  56. }
  57.   /* put c to hardware here */
  58.   /* Wait transmission is completed : otherwise the first data is not sent */
  59.   while (!(UART1->SR & 0x80));
  60.   UART1->DR = (c);
  61.   /* Wait transmission is completed */
  62.   while (!(UART1->SR & 0x80));
  63.   return (c);
  64. }
uet_cache 发表于 2012-12-26 10:45 | 显示全部楼层
楼上怎么做到的啊。我也不清楚如何帖。每次复制不到。你还搞了个“复制代码”。教教。。。
幻梦kfc 发表于 2012-12-29 22:38 | 显示全部楼层
看看
 楼主| aaronji 发表于 2013-1-15 16:25 | 显示全部楼层
呵呵   二楼应该教下怎么贴的哦!
lzymcu 发表于 2013-1-22 17:32 | 显示全部楼层
楼主好人啊,一直没搞定块编程,等有空了再试一下
火箭球迷 发表于 2013-1-22 20:33 | 显示全部楼层
LZ写的很好
pkat 发表于 2013-1-22 21:13 | 显示全部楼层
2楼的代码是如何贴的,共享下经验
chenyu988 发表于 2013-1-22 21:19 | 显示全部楼层
我也没有贴过  但是刚才仔细一看 猛然发现。。。
@}%IO)F~G_WPVW8]1]5AD~Q.jpg
chenyu988 发表于 2013-1-22 21:20 | 显示全部楼层
pkat 发表于 2013-1-22 21:13
2楼的代码是如何贴的,共享下经验

看楼上哦
xsgy123 发表于 2013-1-22 21:24 | 显示全部楼层
鼓励经验共享
 楼主| aaronji 发表于 2013-1-23 17:19 | 显示全部楼层
希望每位香主都能分享点小经验,贴上自己亲自做的觉得不错的那块代码,以便共享与进步!
wago2008 发表于 2013-1-24 09:00 | 显示全部楼层
贴得很艺术
lzymcu 发表于 2013-4-2 12:07 | 显示全部楼层
helloword2010 发表于 2013-4-19 14:15 | 显示全部楼层
其实这个说明STM8的库函数就有说大家不去看而已。不过我看到了最终还是没编译过,为啥就是 设置FLASH_CODE选项时少了FLASH_CODE前面那个点号。。。。就没编过。应该是自己粗心了没多想。不过也搞了好几天啊~~~~
cjhk 发表于 2013-4-19 18:58 | 显示全部楼层
原来21ic也是可以直接贴代码的   一直没有留心这个问题   顶一个
liangfengfei 发表于 2014-10-21 10:22 | 显示全部楼层
很好了,学习ing
kandaobangjunsh 发表于 2015-10-20 10:26 | 显示全部楼层

编译出现好多这样的警告,请问怎么解决Warning[Ta005]: Library call (?mul32_l0_l0_l1) from within a __ramfunc function F:\registor\linshi\线切割\xqg-gaopin-code\TCIAR V1.1\FWlib\src\stm8s_flash.c 655
叶与秋风舞 发表于 2015-11-17 14:57 | 显示全部楼层
正需要这样的资料,楼主真是有心人
foxglove 发表于 2015-11-17 15:40 | 显示全部楼层
STM8S EEPROM块编程
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

9

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部