找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 2758|回复: 4
打印 上一主题 下一主题
收起左侧

求教STC15W4K32S4内部dataflash读写问题

[复制链接]
跳转到指定楼层
楼主
求教,在读出写入到STC15W4K32S4内部dataflash的数据时,为什么定义成unsigned char和unsigned long型变量的数据会出错?unsigned int变量读出的数据是正确的,如下图:

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

  5. type_status status_test;
  6. void muc_init();
  7. void delay1s(void);
  8. void UART_init(void);

  9. /*****************************************************************************
  10. 函数名称 : main()
  11. 功能描述 : 主函数
  12. 输入参数 : 无
  13. 返回参数 : 无
  14. 使用说明 : 无
  15. *****************************************************************************/
  16. void main()
  17. {
  18.         muc_init();
  19.         Read_Flash(Flash_ADDR,(u8*)&status_test,sizeof(status_test));
  20.         printf("读取flash十六进制a:0x%x\n",status_test.a);
  21.         printf("读取flash十进制a:%d\n",status_test.a);
  22.         printf("读取flash十六进制b:0x%x\n",status_test.b);
  23.         printf("读取flash十进制b:%d\n",status_test.b);
  24.         printf("读取flash十六进制c:0x%x\n",status_test.c);
  25.         printf("读取flash十进制c:%d\n",status_test.c);        
  26.         Earse_Flash(Flash_ADDR);
  27.         while(1)
  28.         {
  29.                 status_test.a = 2;
  30.                 status_test.b = 3;
  31.                 status_test.c = 4;
  32.                 Write_Flash(Flash_ADDR,(u8*)&status_test, sizeof(status_test));
  33.                 while(1);

  34.         }
  35. }

  36. /*****************************************************************************
  37. 函数名称 : gpio()
  38. 功能描述 : IO口初始化
  39. 输入参数 : 无
  40. 返回参数 : 无
  41. 使用说明 : 无
  42. *****************************************************************************/
  43. void gpio()
  44. {
  45.         P0M1 = 0x00;
  46.         P0M0 = 0x00;
  47.         
  48.   P3M1 = 0x00;
  49.   P3M0 = 0x00;

  50.   P1M1 = 0x00;
  51.   P1M0 = 0x00;

  52.   P5M1 = 0x00;
  53.   P5M0 = 0x00;
  54. }

  55. /*****************************************************************************
  56. 函数名称 : muc_init
  57. 功能描述 : mcu初始化
  58. 输入参数 : 无
  59. 返回参数 : 无
  60. 使用说明 : 无
  61. *****************************************************************************/
  62. void muc_init()
  63. {
  64.         gpio();
  65.         UART_init();
  66. }

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

  91. //==============================================================================
  92. typedef unsigned char u8;
  93. typedef unsigned int u16;
  94. typedef unsigned long u32;

  95. //==============================================================================

  96. #include "STC15W4K.H"
  97. #include "flash.h"
  98. //==============================================================================
  99. //管脚定义
  100. //==============================================================================

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

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

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

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

  108. sbit sw_open = P3^5;
  109. sbit sw_stop = P3^4;
  110. sbit sw_close  = P3^3;

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

  112. sbit p06 = P0^6;
  113. sbit p07 = P0^7;

  114. //==============================================================================
  115. //变量定义
  116. //==============================================================================

  117. typedef struct
  118. {
  119.         u8 a;  
  120.         u16 b;
  121.         u32 c;
  122. } type_status;

  123. extern type_status status_test;

  124. #endif
  125. //==============================================================================
  126. //flash.c
  127. //==============================================================================
  128. #include "flash.h"

  129. /*****************************************************************************
  130. 函数名称 : IapIdle
  131. 功能描述 : 关闭IAP
  132. 输入参数 : 无
  133. 返回参数 : 无
  134. *****************************************************************************/
  135. static void IapIdle(void)
  136. {
  137.         IAP_CONTR = 0x00;                  //关闭IAP功能
  138.         IAP_CMD = 0x00;                    //清除命令寄存器
  139.         IAP_TRIG = 0x00;                   //清除触发寄存器
  140.         IAP_ADDRH = 0xff;               //将地址设置到非IAP区域
  141.         IAP_ADDRL = 0xff;
  142. }
  143. /*****************************************************************************
  144. 函数名称 : IapReadByte
  145. 功能描述 : 从ISP/IAP/EEPROM区域读取一字节
  146. 输入参数 : addr:起始地址
  147. 返回参数 : 无
  148. *****************************************************************************/
  149. static u8 IapReadByte(u16 addr)
  150. {
  151.         u8 dat;                       //数据缓冲区

  152.         IAP_CONTR = ENABLE_IAP;         //使能IAP
  153.         IAP_CMD = CMD_READ;             //设置IAP命令
  154.         IAP_ADDRL = addr;               //设置IAP低地址
  155.         IAP_ADDRH = addr >> 8;          //设置IAP高地址
  156.         IAP_TRIG = 0x5a;                //写触发命令(0x5a)
  157.         IAP_TRIG = 0xa5;                //写触发命令(0xa5)
  158.         _nop_();                        //等待ISP/IAP/EEPROM操作完成
  159.         _nop_();
  160.         _nop_();
  161.         _nop_();
  162.         dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
  163.         IapIdle();                      //关闭IAP功能

  164.         return dat;                     //返回
  165. }
  166. /*****************************************************************************
  167. 函数名称 : IapProgramByte
  168. 功能描述 : 写一字节数据到ISP/IAP/EEPROM区域
  169. 输入参数 : addr:起始地址/dat:待写入数据
  170. 返回参数 : 无
  171. *****************************************************************************/
  172. static void IapProgramByte(u16 addr, u8 dat)
  173. {
  174.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  175.     IAP_CMD = CMD_PROGRAM;          //设置IAP命令
  176.     IAP_ADDRL = addr;               //设置IAP低地址
  177.     IAP_ADDRH = addr >> 8;          //设置IAP高地址
  178.     IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
  179.     IAP_TRIG = 0x5a;                //写触发命令(0x5a)
  180.     IAP_TRIG = 0xa5;                //写触发命令(0xa5)
  181.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  182.                 _nop_();
  183.                 _nop_();
  184.                 _nop_();
  185.     IapIdle();
  186. }
  187. /*****************************************************************************
  188. 函数名称 : IapEraseSector
  189. 功能描述 : 扇区擦除
  190. 输入参数 : addr:起始地址
  191. 返回参数 : 无
  192. *****************************************************************************/
  193. static void IapEraseSector(u16 addr)
  194. {
  195.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  196.     IAP_CMD = CMD_ERASE;            //设置IAP命令
  197.     IAP_ADDRL = addr;               //设置IAP低地址
  198.     IAP_ADDRH = addr >> 8;          //设置IAP高地址
  199.     IAP_TRIG = 0x5a;                //写触发命令(0x5a)
  200.     IAP_TRIG = 0xa5;                //写触发命令(0xa5)
  201.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  202.                 _nop_();
  203.                 _nop_();
  204.                 _nop_();
  205.     IapIdle();
  206. }
  207. /*****************************************************************************
  208. 函数名称 : Write_Flash
  209. 功能描述 : 对Flash进行字节编程
  210. 输入参数 : Addr_Obj:FLASH的目标起始地址
  211.            Addr_Sour:写入的源数据
  212.            Length:写入的字节数
  213. 返回参数 : SUCCESS:写入成功
  214.             ERROR:写入失败
  215. 使用说明 : 无
  216. *****************************************************************************/
  217. u8 Write_Flash(u16 Addr_Obj,u8 *Addr_Sour,u16 Length)
  218. {
  219.         u16 i;
  220.         for(i = 0; i < Length; i ++)
  221.         {
  222.                 IapProgramByte(Addr_Obj,*Addr_Sour);
  223.                 Addr_Obj ++;
  224.                 Addr_Sour ++;
  225.         }
  226.         return SUCCESS;
  227. }
  228. /*****************************************************************************
  229. 函数名称 : Earse_Flash
  230. 功能描述 : 对Flash擦除
  231. 输入参数 : Addr_Obj:FLASH的目标起始地址
  232. 返回参数 : SUCCESS:擦除成功
  233.             ERROR:擦除失败
  234. 使用说明 : 无
  235. *****************************************************************************/
  236. u8 Earse_Flash(u16 Addr_Obj)
  237. {
  238.         IapEraseSector(Addr_Obj);
  239.         
  240.         return SUCCESS;
  241. }
  242. /*****************************************************************************
  243. 函数名称 : Read_Flash
  244. 功能描述 : 读取FLASH的数据
  245. 输入参数 : ulAddress:FLASH的起始地址
  246.                                          pulData:源数据
  247.            Length:读取的字节数
  248. 返回参数 : true:读取成功
  249.            false:读取失败
  250. *****************************************************************************/
  251. u8 Read_Flash(u16 ulAddress,u8 *pulData,u16 Length)
  252. {
  253.         u16 i;
  254.         for(i = 0; i < Length; i ++)
  255.         {
  256.                 *pulData = IapReadByte(ulAddress);
  257.                 ulAddress ++;
  258.                 pulData ++;
  259.         }
  260.                
  261.         return SUCCESS;
  262. }
  263. //==============================================================================
  264. //flash.h
  265. //==============================================================================
  266. #ifndef __USER_FLASH_H__
  267. #define __USER_FLASH_H__

  268. //==============================================================================
  269. //头文件包含
  270. //==============================================================================
  271. #include "main.h"
  272. #include <intrins.h>
  273. //==============================================================================
  274. //常量定义
  275. //==============================================================================
  276. #define CMD_IDLE    0               //空闲模式
  277. #define CMD_READ    1               //IAP字节读命令
  278. #define CMD_PROGRAM 2               //IAP字节编程命令
  279. #define CMD_ERASE   3               //IAP扇区擦除命令
  280. #define ENABLE_IAP  0x82            //if SYSCLK<20MHz

  281. #define         Flash_ADDR                                         0x0000

  282. #define                SUCCESS                                                        1
  283. #define                ERROR                                                                0


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

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

  304. /*****************************************************************************
  305. 函数名称 : Read_Flash
  306. 功能描述 : 读取FLASH的数据
  307. 输入参数 : pulData:源数据
  308.            ulAddress:FLASH的起始地址
  309.            Length:读取的字节数
  310. 返回参数 : true:读取成功
  311.            false:读取失败
  312. *****************************************************************************/
  313. u8 Read_Flash(u16 ulAddress,u8 *pulData,u16 Length);

  314. #endif
  315. //==============================================================================
复制代码
望各位高人帮忙指导一下,感谢!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

举报

沙发
ID:213173 发表于 2020-6-11 10:16 | 只看该作者
不是很明白楼主的问题。STC单片机的内置EEPROM是按扇区划分的,每个扇区容量512字节,写数据之前要把整个扇区擦除,哪怕只写一个字节。多字节数据只能按字节逐一写入。int型和long型数据得事先分解后才能正确写入。一次最多只能写512字节。读取EEPROM中数据也是按字节逐一读出,再将原int型和long型数据按写入时分解方式逆操作还原。
回复

举报

板凳
ID:155507 发表于 2020-6-11 10:50 | 只看该作者
不是内部dataflash读写问题

是printf()函数的问题




回复

举报

地板
ID:125243 发表于 2020-6-11 11:51 | 只看该作者
angmall 发表于 2020-6-11 10:50
不是内部dataflash读写问题

是printf()函数的问题

确实是打印的问题,非常感谢!!!!!!
回复

举报

5#
ID:125243 发表于 2020-6-11 11:57 | 只看该作者
wulin 发表于 2020-6-11 10:16
不是很明白楼主的问题。STC单片机的内置EEPROM是按扇区划分的,每个扇区容量512字节,写数据之前要把整个扇 ...

学习了,谢谢你的指导!
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表