打印
[STM8]

STM8S103F使用EEPROM死机问题

[复制链接]
6713|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
berry56|  楼主 | 2014-12-2 14:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用芯片内部自带的EEPROM,STVD,Cosmic的Toolset,不管是用函数库中的FLASH_ProgramBlock,FLASH_WaitForLastOperation还是使用寄存器地址直接赋值,都会死机,如果是使用FLASH_WaitForLastOperation,则会死在该语句,如果是使用寄存器,则会死在 while(!(FLASH_IAPSR&0x04)); ,已经按照函数中说的那样,一、在Stm8s.h中定义了#define RAM_EXECUTION  (1) ,并在input设置中,在RAM的SECTION中加了FLASH_CODE,仍然当机,求高手解决,谢谢~~~
沙发
berry56|  楼主 | 2014-12-2 16:00 | 只看该作者
没有人用过103的EEPROM吗?

使用特权

评论回复
板凳
berry56|  楼主 | 2014-12-2 16:05 | 只看该作者
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "stm8s.h"
#include "stm8s_flash.h"
#include "stm8s_gpio.h"
#include "stm8s_clk.h"
@eeprom unsigned char  EePromData[10]={0,1,2,3,4,5,6,7,8,9};

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

#ifdef _RAISONANCE_
/* needed by memcpy for raisonance */
#include <string.h>
extern int __address__FLASH_EraseBlock;
extern int __size__FLASH_EraseBlock;
extern int __address__FLASH_ProgramBlock;
extern int __size__FLASH_ProgramBlock;
#endif /*_RAISONANCE_*/

/* Private function prototypes -----------------------------------------------*/
/* Declare _fctcpy function prototype as it is packaged by default in the Cosmic
   machine library */
#ifdef _COSMIC_
int _fctcpy(char name);
#endif /*_COSMIC_*/
void Delay (uint16_t nCount);
static void CLK_Config(void);
static void GPIO_Config(void);
static void FLASH_Config(void);


typedef struct
{
  unsigned char ODR0        : 1;
  unsigned char ODR1        : 1;
  unsigned char ODR2        : 1;
  unsigned char ODR3        : 1;
  unsigned char ODR4        : 1;
  unsigned char ODR5        : 1;
  unsigned char ODR6        : 1;
  unsigned char ODR7        : 1;
} __BITS_ODR;
#define PB_ODR ((__BITS_ODR *) 0x5005)
#define LED                PB_ODR->ODR5

void delayms(unsigned int t)
{
        unsigned int tloop,ttloop;
        for(tloop=0;tloop<t;tloop++)
        {
                for(ttloop=0;ttloop<200;ttloop++)
                        {
                _asm("nop");
                        }
        }
}
#define u8        unsigned char
#define U16 unsigned int
#define U8         unsigned char
#define         EEPMASS1     0xAE                   //密码钥匙1
#define         EEPMASS2     0x56                   //密码钥匙2
#define         EEPADDR      0x4000                  //eep地址起始
#define FLASH_DUKR        FLASH->DUKR               
#define FLASH_IAPSR        FLASH->IAPSR               
#define FLASH_CR1        FLASH->CR1               
#define FLASH_CR2        FLASH->CR2               
#define FLASH_NCR2        FLASH->NCR2               
#define FLASH_PUKR        FLASH->PUKR               
#define FLASH_NFPR        FLASH->NFPR               

void eep_word_write(U16 u16Addr, U8 *pdatas, U8 len)
{
  U8 *eep=(U8*)u16Addr;
  U8 j;

  FLASH_DUKR=EEPMASS1;                //锁1密钥  
  FLASH_DUKR=EEPMASS2;                //锁2密钥
  while(!(FLASH_IAPSR&0x08));         //等待解密就绪

//  DISABLE_MAC_INTERRUPTS();
  FLASH_CR2 |= 0x40;     //               
  FLASH_NCR2 &= ~0x40;   //设置字编程
  for(j=0; j<len; j++)
  {
    eep[j] = pdatas[j];
  }
        delayms(100);
// while(!(FLASH_IAPSR&0x04));
// FLASH_IAPSR &=0xf7;    // off the eeprom program
//  ENABLE_MAC_INTERRUPTS();      
}



void eeprom_read(U16 u16Addr, U8 *pdatas, U8 len)
{
  U8 *eep=(U8 *)u16Addr;
  U8 j;

  for(j=0; j<len; j++)
  {
    pdatas[j]=eep[j];         
  }
}




main()
{
        u8        tval;
        u8 *p=(u8 *)0x4000;
        u8 buff[128];
        GPIOB->CR1=0xF0;
        GPIOB->CR2=0xF0;
        GPIOB->DDR=0xF0;
        //eep_word_write(0x4000,buff,3);
        //eeprom_read(0x4000,buff,3);
        buff[0]=0x33;buff[1]=0x33;buff[2]=0x33;buff[3]=0x33;buff[4]=0x33;
FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);

  FLASH_Unlock(FLASH_MEMTYPE_PROG);
  /* Wait until Flash Program area unlocked flag is set*/
  while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET)
  {}
        FLASH_ProgramByte(0x4005,0x55);
        //EePromData[0]=9;
        //eep_word_write(0x4000,buff,2);
        delayms(500);
        tval=EePromData[4];
       
        tval=p[4];
       
                while (1)
                {
                        delayms(500);
                        LED=1;
                        delayms(500);
                        LED=0;
                }
}
#if 0
main()
{

  uint32_t add = 0, startadd = 0, stopadd = 0;
  uint8_t newval = 0xAA;
  uint8_t i = 0;

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

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


  /* Clock configuration -----------------------------------------*/
  CLK_Config();

  /* GPIO Configuration ------------------------------------------*/
  GPIO_Config();

  /* FLASH Configuration ------------------------------------------*/
  FLASH_Config();

  /* Fill the buffer in RAM */
  for (i = 0; i < FLASH_BLOCK_SIZE; i++)
  {
    GBuffer = newval;
  }
  /* This function is executed from RAM */
  FLASH_ProgramBlock(BLOCK_OPERATION, FLASH_MEMTYPE_DATA, FLASH_PROGRAMMODE_STANDARD, GBuffer);
  
  /* Wait until End of high voltage flag is set*/
// while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET)
  
  while (FLASH_GetFlagStatus(FLASH_FLAG_EOP) == RESET)
          {}
  /* Check the programmed block */
  startadd = FLASH_DATA_START_PHYSICAL_ADDRESS + ((uint16_t)BLOCK_OPERATION * (uint16_t)FLASH_BLOCK_SIZE);
  stopadd = startadd + (uint16_t)FLASH_BLOCK_SIZE;
  for (add = startadd; add < stopadd; add++)
      {
        if (FLASH_ReadByte(add) != newval)
        {
          /* Error */
          OperationStatus = FAILED;
          /* OperationStatus = PASSED, if the data written/read to/from Flash program memory is correct */
          /* OperationStatus = FAILED, if the data written/read to/from Flash program memory is corrupted */
          while (1)
          {
            Delay(0xFFFF);
          }
        }
      }
  /* Erase block 0 and verify it */
  /* This function is executed from RAM */
  FLASH_EraseBlock(BLOCK_OPERATION, FLASH_MEMTYPE_DATA);

  /* Wait until End of high voltage flag is set*/
  while (FLASH_GetFlagStatus(FLASH_FLAG_EOP) == RESET)
  {}

  for (add = startadd; add < stopadd; add++)
      {
        if (FLASH_ReadByte(add) != 0x00)
        {
          /* Error */
          OperationStatus = FAILED;
          /* OperationStatus = PASSED, if the data written/read to/from Flash program memory is correct */
          /* OperationStatus = FAILED, if the data written/read to/from Flash program memory is corrupted */
          while (1)
          {
            Delay(0xFFFF);
          }
        }
      }

  /* Pass */
  OperationStatus = PASSED;
  /* OperationStatus = PASSED, if the data written/read to/from Flash program memory is correct */
  /* OperationStatus = FAILED, if the data written/read to/from Flash program memory is corrupted */
  while (1)
  {
    Delay(0xFFFF);
  }




GPIOB->CR1=0xF0;
GPIOB->CR2=0xF0;
GPIOB->DDR=0xF0;






        while (1)
        {
                delayms(500);
                LED=1;
                delayms(500);
                LED=0;
        }
}
#endif


/**
  * @brief  Configure system clock to run at 16Mhz
  * @param  None
  * @retval None
  */
void CLK_Config(void)
{
    /* Initialization of the clock */
    /* Clock divider to HSI/1 */
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
}

/**
  * @brief  Configure GPIO for LEDs available on the evaluation board
  * @param  None
  * @retval None
  */
void GPIO_Config(void)
{
    /* Initialize LEDs mounted on STM8-128 EVAL board */
}

/**
  * @brief  Configure the FLASH for block programming
  * @param  None
  * @retval None
  */
void FLASH_Config(void)
{
/* Define flash programming Time*/
  FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);

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

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

/**
  * @brief  Delay.
  * @param  nCount
  * @retval None
  */
void Delay(uint16_t nCount)
{
    /* Decrement nCount value */
    while (nCount != 0)
    {
        nCount--;
    }
}

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

  /* Infinite loop */
  while (1)
  {}
}
#endif

使用特权

评论回复
地板
berry56|  楼主 | 2014-12-2 16:06 | 只看该作者
各种尝试各种等。。。

使用特权

评论回复
5
hopewise| | 2014-12-2 17:39 | 只看该作者
uchar   ledStateInEEPROM @0X4000; //设定温度值存放地址在0X4000
//判断是否为首次上电,如果不是,则读取上次设定的温度值
if(ledStateInEEPROM != 0X00)
{
         set_temp = ledStateInEEPROM;  
}
else               //否则,是第1次上电,故要初始化为31度
{
          set_temp=31;
}       

/***********************************
* 名称:     UnlockEEPROM()
* 功能:     解锁EEPROM
* 入口参数: 无
* 出口参数: 无
* 说明:                                            
************************************/
void  UnlockEEPROM(void)
{
     do
     {
          FLASH_DUKR = 0xae;               // 写入第一个密钥
          FLASH_DUKR = 0x56;               // 写入第二个密钥
     } while((FLASH_IAPSR & 0x08) == 0);   // 若解锁未成功,则重新再来
}

if(set_temp>34) set_temp=20;                  //最大设定温度是34度
                                        UnlockEEPROM();                   //解锁EEPROM
                                        ledStateInEEPROM = set_temp;      //往EEPROM写入led灯状态
                                        while((FLASH_IAPSR & 0x04) == 0); //等待写操作成功       

使用特权

评论回复
6
hopewise| | 2014-12-2 17:45 | 只看该作者
if(set_temp>34) set_temp=20;          //最大设定温度是34度
UnlockEEPROM();                   //解锁EEPROM
ledStateInEEPROM = set_temp;      //往EEPROM写入led灯状态
while((FLASH_IAPSR & 0x04) == 0); //等待写操作成功
以上是我用在产品上的(103的EEPROM)

使用特权

评论回复
7
Xflyan| | 2014-12-2 17:46 | 只看该作者
库里整理出来的寄存器代码,还未死过....环境:EWSTM8
/*===============================================
*        EEPROM Configuration
*        640 Bytes for STM8S103 & STM8S903
*=============================================*/
#define EEPROM_START_ADDR       ((u32)0x004000)
#define EEPROM_END_ADDR         ((u32)0x00427F)
#define OPERATION_TIMEOUT           ((u16)0x1000)

void halEEWriteByte(u32 addr, u8 dat)
{
        u16 timeout = OPERATION_TIMEOUT;
       
        /* Warning: keys are reversed on data memory !!! */
    FLASH->DUKR = FLASH_RASS_KEY2;
    FLASH->DUKR = FLASH_RASS_KEY1;
       
        while ((addr < EEPROM_START_ADDR) || (addr > EEPROM_END_ADDR));
    *((__far u8*) addr) = dat;
       
        while ((FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) && (--timeout));
       
        FLASH->IAPSR = (u8)(~FLASH_IAPSR_DUL);
}

void halEEWriteWord(u32 addr, u8 * dat)
{
        u16 timeout = OPERATION_TIMEOUT;
       
        /* Warning: keys are reversed on data memory !!! */
    FLASH->DUKR = FLASH_RASS_KEY2;
    FLASH->DUKR = FLASH_RASS_KEY1;
       
        /* Enable Word Write Once */
    FLASH->CR2  |= FLASH_CR2_WPRG;
    FLASH->NCR2 &= (u8)(~FLASH_NCR2_NWPRG);
       
        while ((addr < EEPROM_START_ADDR) || (addr > EEPROM_END_ADDR));
    *((__far u8*) addr) = dat[0];
        *((__far u8*) (addr + 1)) = dat[1];
        *((__far u8*) (addr + 2)) = dat[2];
        *((__far u8*) (addr + 3)) = dat[3];
       
        while ((FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) && (--timeout));
       
        FLASH->IAPSR = (u8)(~FLASH_IAPSR_DUL);
}

u8 halEEReadByte(u32 addr)
{
        return (*((__far u8 *) addr));
}

使用特权

评论回复
8
airwill| | 2014-12-2 21:15 | 只看该作者
我觉得你应该找例程对照着,让调试器来帮你,看看跑到什么地方过不去了。
应该很好找问题吧

使用特权

评论回复
9
jhp3909553| | 2014-12-3 10:25 | 只看该作者
以前我也是,有使用莫名其妙的飞了。现在也不知道为什么

使用特权

评论回复
10
lysfht123| | 2014-12-3 15:20 | 只看该作者
8楼是正解。调试,

使用特权

评论回复
11
Hecat| | 2017-2-17 15:28 | 只看该作者
EEPROM写入不会引起死机。
引起死机的原因估计是串口接收过载。

EEPROM写入比较耗时间,在写入期间,CPU是暂停操作的,串口如果有数据进来,非常容易引起过载。
如果接收过载,串口状态寄存器UART_SR的位OR被置位。
OR位置位会引起串口接收中断。正常的读UART_DR不会清除这个状态,于是引起串口RX反复中断,近似死机。

清除OR标志的方法是,先读取UART_SR,再读取UART_DR。

在原代码的UARTx_ReceiveDatax()函数前加一句(uint8_t)UART1->SR即可

(uint8_t)UART1->SR;                 //Clear OR flag
*rx_wp = UART1_ReceiveData8();

使用特权

评论回复
12
yiyigirl2014| | 2017-2-17 21:05 | 只看该作者
死机会不会硬件的问题?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

12

帖子

1

粉丝