Afei1106 发表于 2020-6-10 17:21

求教STC15W4K32S4内部dataflash读写问题

本帖最后由 Afei1106 于 2020-6-10 17:24 编辑

求教,在读出写入到STC15W4K32S4内部dataflash的数据时,为什么定义成unsigned char和unsigned long型变量的数据会出错?unsigned int变量读出的数据是正确的,如下图:


代码如下:
//main.c
//=====================================================================================
#include "main.h"
#include <stdio.h>

type_status status_test;
void muc_init();
void delay1s(void);
void UART_init(void);

/*****************************************************************************
函数名称 : main()
功能描述 : 主函数
输入参数 : 无
返回参数 : 无
使用说明 : 无
*****************************************************************************/
void main()
{
      muc_init();
      Read_Flash(Flash_ADDR,(u8*)&status_test,sizeof(status_test));
      printf("读取flash十六进制a:0x%x\n",status_test.a);
      printf("读取flash十进制a:%d\n",status_test.a);
      printf("读取flash十六进制b:0x%x\n",status_test.b);
      printf("读取flash十进制b:%d\n",status_test.b);
      printf("读取flash十六进制c:0x%x\n",status_test.c);
      printf("读取flash十进制c:%d\n",status_test.c);      
      Earse_Flash(Flash_ADDR);
      while(1)
      {
                status_test.a = 2;
                status_test.b = 3;
                status_test.c = 4;
                Write_Flash(Flash_ADDR,(u8*)&status_test, sizeof(status_test));
                while(1);

      }
}

/*****************************************************************************
函数名称 : gpio()
功能描述 : IO口初始化
输入参数 : 无
返回参数 : 无
使用说明 : 无
*****************************************************************************/
void gpio()
{
      P0M1 = 0x00;
      P0M0 = 0x00;
      
P3M1 = 0x00;
P3M0 = 0x00;

P1M1 = 0x00;
P1M0 = 0x00;

P5M1 = 0x00;
P5M0 = 0x00;
}

/*****************************************************************************
函数名称 : muc_init
功能描述 : mcu初始化
输入参数 : 无
返回参数 : 无
使用说明 : 无
*****************************************************************************/
void muc_init()
{
      gpio();
      UART_init();
}

/*****************************************************************************
函数名称 : UART_init
功能描述 : UART初始化
输入参数 : 无
返回参数 : 无
使用说明 : 无
*****************************************************************************/
void UART_init(void)
{                  
      //下面代码设置定时器1
      TMOD = 0x20;      // 0010 0000 定时器1工作于方式2(8位自动重装方式)
      TH1= 0xFD;      // 波特率:9600 /11.0592MHZ
      TL1= 0xFD;      // 波特率:9600 /11.0592MHZ
      TR1= 1;
      //下面代码设置定串口
      AUXR = 0x00;             // 很关键,使用定时器1作为波特率发生器,S1ST2=0
      SCON = 0x50;         // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允许接受)
      TI=1;                        // 很关键,使用printf函数时必须有此命令
}
//==========================================================================================
//main.h
//==========================================================================================
#ifndef __MAIN_H__
#define __MAIN_H__

//==============================================================================
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;

//==============================================================================

#include "STC15W4K.H"
#include "flash.h"
//==============================================================================
//管脚定义
//==============================================================================

sbit led1 = P1^2; //open指示灯
sbit led2 = P1^3; //stop指示灯
sbit led3 = P1^4; //close指示灯

sbit rs_signal = P1^5; //雨滴传感器信号

sbit ocp = P1^6; //过流保护

sbit in1 = P1^7;
sbit in2 = P5^4; //马达正反转控制

sbit sw_open = P3^5;
sbit sw_stop = P3^4;
sbit sw_close= P3^3;

sbit rx_out = P3^2; //433MHz解码

sbit p06 = P0^6;
sbit p07 = P0^7;

//==============================================================================
//变量定义
//==============================================================================

typedef struct
{
      u8 a;
      u16 b;
      u32 c;
} type_status;

extern type_status status_test;

#endif
//==============================================================================
//flash.c
//==============================================================================
#include "flash.h"

/*****************************************************************************
函数名称 : IapIdle
功能描述 : 关闭IAP
输入参数 : 无
返回参数 : 无
*****************************************************************************/
static void IapIdle(void)
{
      IAP_CONTR = 0x00;                  //关闭IAP功能
      IAP_CMD = 0x00;                  //清除命令寄存器
      IAP_TRIG = 0x00;                   //清除触发寄存器
      IAP_ADDRH = 0xff;               //将地址设置到非IAP区域
      IAP_ADDRL = 0xff;
}
/*****************************************************************************
函数名称 : IapReadByte
功能描述 : 从ISP/IAP/EEPROM区域读取一字节
输入参数 : addr:起始地址
返回参数 : 无
*****************************************************************************/
static u8 IapReadByte(u16 addr)
{
      u8 dat;                     //数据缓冲区

      IAP_CONTR = ENABLE_IAP;         //使能IAP
      IAP_CMD = CMD_READ;             //设置IAP命令
      IAP_ADDRL = addr;               //设置IAP低地址
      IAP_ADDRH = addr >> 8;          //设置IAP高地址
      IAP_TRIG = 0x5a;                //写触发命令(0x5a)
      IAP_TRIG = 0xa5;                //写触发命令(0xa5)
      _nop_();                        //等待ISP/IAP/EEPROM操作完成
      _nop_();
      _nop_();
      _nop_();
      dat = IAP_DATA;               //读ISP/IAP/EEPROM数据
      IapIdle();                      //关闭IAP功能

      return dat;                     //返回
}
/*****************************************************************************
函数名称 : IapProgramByte
功能描述 : 写一字节数据到ISP/IAP/EEPROM区域
输入参数 : addr:起始地址/dat:待写入数据
返回参数 : 无
*****************************************************************************/
static void IapProgramByte(u16 addr, u8 dat)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat;               //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
                _nop_();
                _nop_();
                _nop_();
    IapIdle();
}
/*****************************************************************************
函数名称 : IapEraseSector
功能描述 : 扇区擦除
输入参数 : addr:起始地址
返回参数 : 无
*****************************************************************************/
static void IapEraseSector(u16 addr)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_ERASE;            //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
                _nop_();
                _nop_();
                _nop_();
    IapIdle();
}
/*****************************************************************************
函数名称 : Write_Flash
功能描述 : 对Flash进行字节编程
输入参数 : Addr_Obj:FLASH的目标起始地址
         Addr_Sour:写入的源数据
         Length:写入的字节数
返回参数 : SUCCESS:写入成功
            ERROR:写入失败
使用说明 : 无
*****************************************************************************/
u8 Write_Flash(u16 Addr_Obj,u8 *Addr_Sour,u16 Length)
{
      u16 i;
      for(i = 0; i < Length; i ++)
      {
                IapProgramByte(Addr_Obj,*Addr_Sour);
                Addr_Obj ++;
                Addr_Sour ++;
      }
      return SUCCESS;
}
/*****************************************************************************
函数名称 : Earse_Flash
功能描述 : 对Flash擦除
输入参数 : Addr_Obj:FLASH的目标起始地址
返回参数 : SUCCESS:擦除成功
            ERROR:擦除失败
使用说明 : 无
*****************************************************************************/
u8 Earse_Flash(u16 Addr_Obj)
{
      IapEraseSector(Addr_Obj);
      
      return SUCCESS;
}
/*****************************************************************************
函数名称 : Read_Flash
功能描述 : 读取FLASH的数据
输入参数 : ulAddress:FLASH的起始地址
                                       pulData:源数据
         Length:读取的字节数
返回参数 : true:读取成功
         false:读取失败
*****************************************************************************/
u8 Read_Flash(u16 ulAddress,u8 *pulData,u16 Length)
{
      u16 i;
      for(i = 0; i < Length; i ++)
      {
                *pulData = IapReadByte(ulAddress);
                ulAddress ++;
                pulData ++;
      }
               
      return SUCCESS;
}
//==============================================================================
//flash.h
//==============================================================================
#ifndef __USER_FLASH_H__
#define __USER_FLASH_H__

//==============================================================================
//头文件包含
//==============================================================================
#include "main.h"
#include <intrins.h>
//==============================================================================
//常量定义
//==============================================================================
#define CMD_IDLE    0               //空闲模式
#define CMD_READ    1               //IAP字节读命令
#define CMD_PROGRAM 2               //IAP字节编程命令
#define CMD_ERASE   3               //IAP扇区擦除命令
#define ENABLE_IAP0x82            //if SYSCLK<20MHz

#define         Flash_ADDR                                       0x0000

#define                SUCCESS                                                      1
#define                ERROR                                                                0


/*****************************************************************************
函数名称 : write_flash
功能描述 : 对Flash进行字节编程
输入参数 : Addr_Sour:写入的源数据
         Addr_Obj:FLASH的目标起始地址
         Length:写入的字节数
返回参数 : SUCCESS:写入成功
            ERROR:写入失败
使用说明 : 无
*****************************************************************************/
u8 Write_Flash(u16 Addr_Obj,u8 *Addr_Sour,u16 Length);

/*****************************************************************************
函数名称 : Earse_Flash
功能描述 : 对Flash擦除
输入参数 : Addr_Obj:FLASH的目标起始地址
返回参数 : SUCCESS:擦除成功
            ERROR:擦除失败
使用说明 : 无
*****************************************************************************/
u8 Earse_Flash(u16 Addr_Obj);

/*****************************************************************************
函数名称 : Read_Flash
功能描述 : 读取FLASH的数据
输入参数 : pulData:源数据
         ulAddress:FLASH的起始地址
         Length:读取的字节数
返回参数 : true:读取成功
         false:读取失败
*****************************************************************************/
u8 Read_Flash(u16 ulAddress,u8 *pulData,u16 Length);

#endif
//==============================================================================
希望各位帮忙指导,感谢!!!!!!!!!!!!!!!!!!!!!!!


chen217 发表于 2020-6-11 09:06

操作内部flash的时候,务必要关掉中断,我之前做的一个小东西,给你参考一下

Afei1106 发表于 2020-6-11 12:00

chen217 发表于 2020-6-11 09:06
操作内部flash的时候,务必要关掉中断,我之前做的一个小东西,给你参考一下 ...

谢谢你的解答,问题已解决了,是打印的问题!
页: [1]
查看完整版本: 求教STC15W4K32S4内部dataflash读写问题