打印

求教STC15W4K32S4内部dataflash读写问题

[复制链接]
824|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Afei1106|  楼主 | 2020-6-10 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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_IAP  0x82            //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的时候,务必要关掉中断,我之前做的一个小东西,给你参考一下 program - 副本.zip (57.4 KB)

使用特权

评论回复
板凳
Afei1106|  楼主 | 2020-6-11 12:00 | 只看该作者
chen217 发表于 2020-6-11 09:06
操作内部flash的时候,务必要关掉中断,我之前做的一个小东西,给你参考一下 ...

谢谢你的解答,问题已解决了,是打印的问题!

使用特权

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

本版积分规则

3

主题

20

帖子

1

粉丝