打印

STM8S写入Flash为什么超过64K就写不进去?

[复制链接]
4122|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sed2003|  楼主 | 2012-11-14 10:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用RAM来写Flash,结果发现,一旦超过64K(10000H),就无法写入了。
而在64K以内,却可以写。这是怎么回事啊?
/* Copy data bytes from RAM to FLASH memory */
    for (Count = 0; Count < BLOCK_SIZE; Count++)
    {
        *((@far u16*)0x10000 + Count) = ((u8)(Buffer[Count]));
    }
沙发
IJK| | 2012-11-14 11:17 | 只看该作者
看看生成的汇编代码 是否正确。

使用特权

评论回复
板凳
sed2003|  楼主 | 2012-11-14 12:01 | 只看该作者
本帖最后由 sed2003 于 2012-11-14 12:10 编辑

就是这个,但看不明白。
L513:
3608                     ; 128         *((@far u8*)0x10000 + Count) = ((u8 Buffer[Count])); // 这里
3610  0030 1e0d           ldw x,(OFST+9,sp)
3611  0032 72fb03         addw x,(OFST-1,sp)
3612  0035 f6             ld a,(x)
3613  0036 1e03           ldw x,(OFST-1,sp)
3614  0038 a7010000       ldf (65536,x),a
3615                     ; 126     for (Count = 0; Count < BLOCK_SIZE; Count++)
3617  003c 1e03           ldw x,(OFST-1,sp)
3618  003e 1c0001         addw x,#1
3619  0041 1f03           ldw (OFST-1,sp),x
3622  0043 1e03           ldw x,(OFST-1,sp)
3623  0045 a30080         cpw x,#128
3624  0048 25e6           jrult L513

使用特权

评论回复
地板
IJK| | 2012-11-14 15:17 | 只看该作者
汇编代码似乎是对的。前3行是把数读到 a寄存器里,后2行把 a寄存器里的数 写入64K(10000H)后的目标地址

3608                     ; 128         *((@far u8*)0x10000 + Count) = ((u8 Buffer[Count])); // 这里
3610  0030 1e0d           ldw x,(OFST+9,sp)
3611  0032 72fb03         addw x,(OFST-1,sp)
3612  0035 f6             ld a,(x)
3613  0036 1e03           ldw x,(OFST-1,sp)
3614  0038 a7010000       ldf (65536,x),a

使用特权

评论回复
5
sed2003|  楼主 | 2012-11-14 18:15 | 只看该作者
本帖最后由 sed2003 于 2012-11-14 18:19 编辑

IJK,我发一份我的代码给你看看怎么样,请你帮我解疑一下。
我实在搞不明白到底是哪里错了。

int main(void)
{
        SysInit();

        while (1)
        {
                //ClearWatchdog;
                ClockRun( );
                AccProc( );        

                if(bUpdateMCU)
                {
                        bUpdateMCU = 0;        
                        disableInterrupts();               
                        //protocol_init();                        
                        unlock_PROG();
                        unlock_DATA();      
                        _fctcpy('U');                     
                        MCUUpdateCodeProc();
                }        
        }
}
然后是写FLASH的所有代码:
#include "sys.h"


#pragma section (UPDATEFLASH)

static u8 DataBuffer[DatBufSize]={0}; // 55 aa len GR MI PAR1 128PAR2 CS
static u8 *ReceivedData;
static u8 data[10];
static u8 FlashBuf[128];
static u8 FAR* FlhDataAddress;
static u8 FlhDataCount;
static U16 blockcnt = 0;
//static u8 RdData[10]={0};

void  UpdateUartTx(uchar dat)
{
        u8 sr;

        //wait for Tx empty
        sr = UART1->SR;
        while(!(sr & 0x80/*TxNE*/)) sr = UART1->SR;
        //send data0
        UART1->DR = dat;
        //wait for transmission complete
        sr = UART1->SR;
        while(!(sr & 0x40/*TxNE*/)) sr = UART1->SR;
}

void Transmit(uchar *p,U8 len)
{
          uchar i,OutStr[15],CheckSum=0;        
    OutStr[0]=0x55;
          OutStr[1]=0xAA;
          OutStr[2]=len+1;            

        for(i=3;i<len+3;i++)
    {        
              OutStr = *p;
                CheckSum += *p;
                p++;
    }
        CheckSum = CheckSum ^ 0xFF;
        OutStr[len+3] = CheckSum;

        for(i=0;i<len+4;i++)
    {        
       UpdateUartTx(OutStr);        // 发送数据        
    }
}


void Receive(u8* ReceivedData)
{
        u8 sr;                // working copy of SPI_SR register

        //wait for Rx full
        sr = UART1->SR;
        while(!(sr & 0x20 /*RXNE*/)) sr = UART1->SR ;        
        //receive data
        *ReceivedData = UART1->DR;
}//Receive


void Mem_ProgramBlock(u16 BlockNum, FLASH_MemType_TypeDef MemType, u8 *Buffer)
{
    u16 Count = 0;
    u32 StartAddress = 0;
    u16 timeout = (u16)0x6000;

        /* Set Start address wich refers to mem_type */
    if (MemType == FLASH_MEMTYPE_PROG)
    {
        StartAddress = FLASH_START;
    }
    else
    {
        StartAddress = EEPROM_START;
    }

    /* Point to the first block address */
    StartAddress = StartAddress + ((u32)BlockNum * BLOCK_SIZE);

    /* Standard programming mode */
    FLASH->CR2 |= (u8)0x01;
    FLASH->NCR2 &= (u8)~0x01;
   
    /* Copy data bytes from RAM to FLASH memory */
    for (Count = 0; Count < BLOCK_SIZE; Count++)
    {
        *((@far u8*)StartAddress + Count) = ((u8)(Buffer[Count]));
    }

    if (MemType == FLASH_MEMTYPE_DATA)
    {
        /* Waiting until High voltage flag is cleared*/
        while ((FLASH->IAPSR & 0x40) != 0x00 || (timeout == 0x00))
        {
            timeout--;
        }
    }
}


u8 WriteBufferFlash(u8 FAR* DataAddress, u8 * DataPointer, u8 DataCount)
{
  u32 Address = (u32) DataAddress;
//  u8 * DataPointer = FlashBuf;
  u32 Offset;
  FLASH_MemType_TypeDef MemType;
  //set offset according memory type
//  if(MemType == FLASH_MEMTYPE_PROG)
//    Offset = FLASH_START;
//  else
//    Offset = EEPROM_START;
  Offset = FLASH_START;
  MemType = FLASH_MEMTYPE_PROG;
#if 0
  //program beginning bytes before words
  while((Address % 4) && (DataCount))
  {
    *((PointerAttr u8*) Address) = *DataPointer;
        while( (FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) == 0);
                Address++;
    DataPointer++;
    DataCount--;
  }
  //program beginning words before blocks
  while((Address % BLOCK_BYTES) && (DataCount >= 4))
  {
                FLASH->CR2 |= (u8)0x40;
                FLASH->NCR2 &= (u8)~0x40;
                *((PointerAttr u8*)Address) = (u8)*DataPointer  ;          /* Write one byte - from lowest address*/
                *((PointerAttr u8*)(Address + 1)) = *(DataPointer + 1); /* Write one byte*/
                *((PointerAttr u8*)(Address + 2)) = *(DataPointer + 2); /* Write one byte*/
                *((PointerAttr u8*)(Address + 3)) = *(DataPointer + 3); /* Write one byte - from higher address*/
    while( (FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) == 0);
                Address    += 4;
    DataPointer+= 4;
    DataCount  -= 4;
  }
#endif  
  //program blocks
  while(DataCount >= BLOCK_BYTES)
  {
    Mem_ProgramBlock((Address - Offset)/BLOCK_BYTES, MemType, DataPointer);
   // Address    += BLOCK_BYTES;
   // DataPointer+= BLOCK_BYTES;   
    DataCount  -= BLOCK_BYTES;
  }
#if 0
  //program remaining words (after blocks)
  while(DataCount >= 4)
  {
                FLASH->CR2 |= (u8)0x40;
                FLASH->NCR2 &= (u8)~0x40;
                *((PointerAttr u8*)Address) = (u8)*DataPointer  ;                  /* Write one byte - from lowest address*/
                *((PointerAttr u8*)(Address + 1)) = *(DataPointer + 1); /* Write one byte*/
                *((PointerAttr u8*)(Address + 2)) = *(DataPointer + 2); /* Write one byte*/
                *((PointerAttr u8*)(Address + 3)) = *(DataPointer + 3); /* Write one byte - from higher address*/
            while( (FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) == 0);
                Address    += 4;
            DataPointer+= 4;
            DataCount  -= 4;
  }

  //program remaining bytes (after words)
  while(DataCount)
  {
    *((PointerAttr u8*) Address) = *DataPointer;
    while( (FLASH->IAPSR & (FLASH_IAPSR_EOP | FLASH_IAPSR_WR_PG_DIS)) == 0);
                Address++;
    DataPointer++;
    DataCount--;
  }
#endif   
  return 1;
}//WriteBufferFlash


u8 WriteBuffer(u8 FAR* DataAddress, u8 * DataPointer, u8 DataCount)
{
  u8 i;
  
  //for Flash
  if (((u32)DataAddress >= FLASH_START) && (((u32)DataAddress + DataCount - 1) <= FLASH_END))
    return WriteBufferFlash(DataAddress, DataPointer, DataCount);
#if 0   
  //for EEPROM
  if (((u32)DataAddress >= EEPROM_START) && (((u32)DataAddress + DataCount - 1) <= EEPROM_END))
    return WriteBufferFlash(DataAddress, DataCount, FLASH_MEMTYPE_DATA);
   
  //for RAM
  if (((u32)DataAddress >= RAM_START) && (((u32)DataAddress + DataCount - 1) <= RAM_END))
  {
    for(i=0; i<DataCount; i++)
      DataAddress = DataBuffer;
    return 1;
  }
  
  //for Option bytes
  if (((u32)DataAddress >= OPTION_START) && (((u32)DataAddress + DataCount - 1) <= OPTION_END))
  {
    for(i=0; i<DataCount; i++)
    {
       FLASH_ProgramOptionByte((u32)(&DataAddress), DataBuffer);
    }
    return 1;
  }
#endif
  //otherwise fail
  return 0;
}//WriteBuffer

u8 FLASH_ReadByteData(uint32_t Address)
{   
    /* Read byte */
    return(*(FAR uint8_t *) (uint16_t)Address);

}


void MCUUpdateCodeProc(void)
{
        u8 sr,*RevData;                // working copy of SPI_SR register
        u8 cnt;
        u8 i,cs,WrFlashSt;

        
#if 1
        data[0] = _GR_Menu;
        data[1] = _MI_Update_MCU;
        Transmit(data,2);        
                        
        //FlashDataAddr = (u32*)FLASH_START;
        FlhDataAddress = (u8 FAR*)FLASH_START;
        FlhDataCount = BLOCK_SIZE;
        while(1)
        {
/************* get uart data *************/               
                RevData = &DataBuffer[0];
                cnt = 0;
                while(cnt<135)
                {
                        sr = UART1->SR;
                        while(!(sr & 0x20 /*RXNE*/))
                        {
                                sr = UART1->SR ;
                        }
                        *RevData = UART1->DR;
                        RevData++;
                        cnt++;
                }
/************* analyse data *************/               
                cs = 0;
                for(i=3;i<134;i++)
            {   
                        cs += DataBuffer;
            }
                cs = cs ^ 0xFF;
               
                if(DataBuffer[0]!=0x55 || DataBuffer[1]!=0xAA || DataBuffer[2]!=132 || DataBuffer[134]!=cs)
                {
                        //send err ack to host
                        data[0] = _GR_Menu;
                        data[1] = _Update_Code;
                        data[2] = _Fail;
                        Transmit(data,3);                        
                }
                else
                {
                #if 1
/************* write into flash rom *************/               
                        for(i=0;i<128;i++)
                        {
                                FlashBuf = DataBuffer[6+i];
                        }               
                        WriteBuffer(FlhDataAddress,FlashBuf,FlhDataCount);        
                #endif
                        if(blockcnt==256)        while(1);        //41
                        if(DataBuffer[5] == 0x00)
                        {// last frame data
                                /* Lock program memory */
                            //FLASH->IAPSR = ~0x02;
                            /* Lock data memory */
                            //FLASH->IAPSR = ~0x08;
                                data[0] = _GR_Menu;
                                data[1] = _Update_Code;
                                data[2] = _Success;
                                Transmit(data,3);
                        #if 1
                                //reset stack pointer (lower byte - because compiler decreases SP with some bytes)                                 
                                _asm("LDW X,  SP ");
                                _asm("LD  A,  $FF");
                                _asm("LD  XL, A  ");
                                _asm("LDW SP, X  ");
                                _asm("JPF $8000");
                        #endif                                
                                
                        }
                        else
                        {// next frame data
                                FlhDataAddress += FlhDataCount;
                                blockcnt++;
                                data[0] = _GR_Menu;
                                data[1] = _Update_Code;
                                data[2] = _Success;
                                Transmit(data,3);
                        }                  
                }               
        }
#endif        
}        


#pragma section ()


使用特权

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

本版积分规则

0

主题

34

帖子

0

粉丝