为什么EEPORM 数据读出来都是0啊 各位老师帮忙看下
#include <STC32G.H>#include "intrins.h"
#include "Modbus.h"
#include "stdio.h"
unsigned char xdata EEPORM_Byte; // 数据缓存区
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
//读EEPORM一个字节函数
unsigned char IapRead(unsigned int addr)
{
unsigned char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 40; //设置等待参数40MHz
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功能
return dat;
}
//写EEPORM一个字节函数
void IapProgram(unsigned int addr, unsigned char dat)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 40; //设置等待参数40MHz
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
//擦除EEPORM函数
void IapErase(unsigned int addr)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 40; //设置等待参数40MHz
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
//========================================================================
// 连续读取EEPORM函数
//描述:从指定EEPORM首地址读出N个字节放在指定缓冲区
//参数:EE_addr:读出EEPORM首地址
// *data_addr :缓存区首地址
// len: 读取字节数量
//返回值: 无
//========================================================================
void IAP_ReadString (unsigned int EE_addr,unsigned int len)
{
unsigned int i;
printf("读出EEPORM字节:\r\n");
for(i=0;i<len*2;i++)
{
EEPORM_Byte=IapRead(EE_addr);
EE_addr++;
printf("EEPORM_Byte[%d]:%d\r\n",i,EEPORM_Byte);
}
}
//========================================================================
// 读写EEPORM函数
//描述:从指定EEPORM首地址读出N个字节放在指定缓冲区 然后判断是否和寄存器数据相同 不相同写入
//参数:
// len: 读取字节数量
//返回值: 无
//========================================================================
void EEPORM_writedat (unsigned int len)
{
unsigned int i,j;
unsigned char write =0; // 写入标志位
IAP_ReadString (0x0000,len); //先读出EEPORM数据
printf("判断EEPORM和寄存器是否相等:\r\n");
for (i=0;i<len;i++)
{
if (ModbusReg==(EEPORM_Byte|EEPORM_Byte<<8))//判断modbus寄存器是否和EEPORM数据相同
{
write=0; //相同置0
printf("相等:\r\n");
printf("ModbusReg[%d]:%d\r\n",i,ModbusReg);
printf("EEPORM_Byte[%d]:%d\r\n",i*2,EEPORM_Byte);
printf("EEPORM_Byte[%d]:%d\r\n",1+i*2,EEPORM_Byte);
}else
{
write=1; // 不相同置1
printf("不相等:\r\n");
printf("ModbusReg[%d]:%d\r\n",i,ModbusReg);
printf("EEPORM_Byte[%d]:%d\r\n",i*2,EEPORM_Byte);
printf("EEPORM_Byte[%d]:%d\r\n",1+i*2,EEPORM_Byte);
break;
}
}
if (write==1) //数据不同,把数据写入EEPORM里
{
IapErase(0x0000); //先擦除一个扇区
printf("扇区擦除已完成:\r\n");
printf("寄存器数据写入EEPORM:\r\n");
for (j=0;j<len;j++) // 读取Moubus寄存器数据
{
EEPORM_Byte=ModbusReg; // 低字节在前
EEPORM_Byte=ModbusReg>>8; // 高字节在后
printf("EEPORM_Byte[%d]=:%d\r\n",j*2,EEPORM_Byte);
printf("EEPORM_Byte[%d]=:%d\r\n",1+j*2,EEPORM_Byte);
printf("ModbusReg[%d]=:%d\r\n",j,ModbusReg);
}
for (i=0;i<len*2;i++) //写入数据到EEPORM
{
IapProgram(0x0000,EEPORM_Byte);
printf("EEPORM数据已写入:\r\n");
}
}
}
//========================================================================
// 上电读取EEPORM数据到寄存器函数
//描述:从指定EEPORM首地址读出N个字节放在指定缓冲区 然后传给modbus寄存器
//参数:
// len: 读取字节数量
//返回值: 无
//========================================================================
void EEPORM_writedat_Program(unsigned int len)
{
unsigned char i;
IAP_ReadString (0x0000,len); //先读出EEPORM数据
printf("将EEPORM字节赋给寄存器:\r\n");
for (i=0;i<len;i++) // 将EEPORM数据传给Modbus寄存器
{
ModbusReg=EEPORM_Byte|EEPORM_Byte<<8;
printf("ModbusReg[%d]:%d\r\n",i,ModbusReg);
}
}
#include <STC32G.H>
#include "mcu_led.h"
#include "modbus.h"
#include "uart.h"
#include "int_out.h"
#include "eeporm.h"
#include "stdio.h"
void main ()
{
WTST=0; //设置程序指令延时参数,幅值0可将CPU执行指令的速度设置为最快
EAXSFR(); //扩展SFR(XFR)访问
CKCON=0; //提高访问XRAM速度
Uart2_Init(9600,0); //串口2初始化
EEPORM_writedat_Program(5); //上电读取EEPORM数据到寄存器
LED_GPIO_lnit(); //GOIO初始化
Timer0_Init(); //定时器0初始化
Timer4_Init();
Uart1_Init(9600,1); //串口1初始化
GPIO_inpt();
EA=1; //打开总中断
国芯AI中IAP功能的实现与数据读取机制
在国芯AI中,IAP(IAP-Configurable Address Pages)是系统中一种特殊的内存映射结构,用于实现高带宽、高内存扩展的内存管理。以下是对IAP功能的详细分析和实现,重点介绍数据读取机制。
1. IAP功能的基本概念
IAP功能是一种自适应内存映射结构,允许系统根据需求动态扩展和收缩内存区域。其核心在于通过配置寄存器(如IAPCONTR、IAPTPS等)来控制内存的访问模式和数据读写/存储的地址范围。IAP功能主要用于提高内存访问的带宽和灵活性,同时支持数据缓存的实现。
2. IAP功能的初始化
在国芯AI中,IAP功能的初始化需要配置多个寄存器,以控制内存的访问模式和数据缓存的大小。例如:
IAPCONTR: 用于控制IAP的读写功能。当IAPCONTR设置为0时,表示IAP的功能被禁用;设置为1时,表示IAP功能被启用。
IAPTPS: 用于设置等待参数,控制IAP的读写延迟。
IAPCMD: 用于设置IAP的读写命令。
这些配置寄存器的设置是实现IAP功能的关键,其值需根据实际需求进行配置。
3. IAP读取函数的实现
在国芯AI中,IAP读取函数用于从IAP缓存中读取数据。其基本结构如下:
c
unsigned char IapRead(unsigned int addr) {
unsigned char dat;
IAPCONTR = 0x80; // 设置IAP读写功能
IAPTPS = 40; // 设置等待参数40MHz
IAPCMD = 1; // 设置IAP读写命令
IAPADDRL = addr; // 设置IAP低地址
dat = IAPADDRH; // 读取IAP低地址区域的地址
return dat;
}
4. 数据读取的分析
IAP功能的核心在于数据缓存区的实现。数据缓存区是一个自适应的内存区域,其大小根据需求动态调整。在读取函数中,数据读取是从数据缓存区读取一个字节(1个8位无符号整数)。
在读取函数中,数据缓存区的地址范围由IAPTPS和IAPCONTR控制。IAPTPS决定了IAP的读写延迟,而IAPCONTR控制IAP的功能是否启用。
5. 可能的优化与问题分析
1. IAP功能的性能优化
IAP功能的性能主要取决于IAPTPS的设置。较低的IAPTPS会增加IAP的读写延迟,影响性能。因此,需要在配置时合理设置IAPTPS,以平衡IAP的功能和性能。
2. 数据缓存区的管理
数据缓存区的大小需要根据实际需求动态调整。如果缓存区过小,可能会影响数据读取的效率;如果缓存区过大,可能占用过多内存空间。
3. IAP功能的兼容性
IAP功能的实现需要与其他内存映射结构(如IAP-Memory)兼容。需要确保IAP功能的配置不会与其他功能冲突。
6. 总结
国芯AI中的IAP功能通过配置寄存器实现动态内存映射和数据缓存。IAP功能的核心在于IAPCONTR、IAPTPS和IAPCMD等配置寄存器的设置,以及IAP读写函数的实现。理解IAP功能的实现和数据读取机制是国芯AI系统设计和优化的关键。
[本文内容由国芯人工智能辅助生成,仅供参考] 老师帮忙看下,哪里设置不对吗 为什么要一个字节一个字节处理呢?
先测试实验箱例程18-通过串口2发送命令读写EEPROM测试程序
因为用的modbus协议,不是所以数据都放入eeprom里 ercircle 发表于 2025-5-19 19:04
为什么要一个字节一个字节处理呢?
先测试实验箱例程18-通过串口2发送命令读写EEPROM测试程序
用的modbus协议 qadiosvm 发表于 2025-5-19 19:27
因为用的modbus协议,不是所以数据都放入eeprom里
通讯协议和EEPROM读写不要耦合的,你可以把数据离散的缓存在一个buffer里,将这个buffer一次性更新到EEPROM嘛。 ercircle 发表于 2025-5-19 19:43
通讯协议和EEPROM读写不要耦合的,你可以把数据离散的缓存在一个buffer里,将这个buffer一次性更新到EEPR ...
主要是现在是一上电,读出来的数据都是0,我在烧录的时候把eeprom数据全部改成ff了,但是读出来还是0 qadiosvm 发表于 2025-5-19 19:50
主要是现在是一上电,读出来的数据都是0,我在烧录的时候把eeprom数据全部改成ff了,但是读出来还是0 ...
你用的这个代码和例程差别还是有的,建议更换下再试下。
页:
[1]