求助代码设置频率iap代码失效问题

分类: best365网页版登录官网 发布时间: 2025-07-25 23:56:08 作者: admin 阅读: 1864

aer***

aer***

当前离线

积分104

打卡等级:初来乍到

打卡总天数:4

最近打卡:2025-06-27 09:09:32

已绑定手机2

主题25

回帖104

积分

注册会员

注册会员, 积分 104, 距离下一级还需 96 积分

注册会员, 积分 104, 距离下一级还需 96 积分

积分104

电梯直达

楼主

发表于 2025-6-27 09:09:32

来自手机

|

只看该作者

|倒序浏览

|阅读模式

你好,我遇到一个问题, 就是我打算请人帮我烧录固件, 但是irc的频率是在烧写的时候指定的,我计划使用代码来指定这个irc的频率,以免烧写的时候对方没沟通烧录是配错了频率。

我已经完成了代码编写,同时看到代码生效的,即无论烧录是频率如何指定, 代码都可以以设计的24mhz工作。绝大部分的代码都工作的非常完美,但是iap去读写eprom这个功能会失效, 且仅当烧录频率不是24m时失效,即 同样的iap代码,烧录时指定24m是正常的。

具体测试:

1. 在isp的时候专门把IRC设为11mhz,

2.示波器测试发现timer1的时间工作频率是正常的,即是24MHz确认代码是可以把工作频率改为24Mhz的。

3. 发现有一个副作用,就是iap无效。 即发现无法保存iap数据 或者是读取iap数据. loadConfigFromIap和 saveConfigToIap

4. 同样的固件,重新在isp指定为24mhz, 设置时钟为24Mhz, loadConfigFromIap和 saveConfigToIap 代码读写正常。

请问为什么会这样? 需要更长的时候等时钟稳定吗?还是其它原因?

以下是我的代码:

P3M1=0x03; // 将P3M1寄存器设置为0x00 (二进制 0000 0011)。这通常用于设置P3端口的模式。根据您提供的模式表 (P3M1位, P3M0位):

P3M0=0x0C; // 0000 1100 P3.2 P3.3 推挽输出 (强上拉), P3.0 , P3.1 高阻输入

P5M1=0x0F; // 将P5M1寄存器设置为0x00 (二进制 0000 0000)。这通常用于设置P5端口的模式。根据您提供的模式表 (P5M1位, P5M0位)://(0, 0): 准双向口 (弱上拉)

P5M0=0xF0; //11 0000 -- P5.5 P5.4 推挽输出 (强上拉)

P3=0; // 上电时将P3端口设置为0xF0 (二进制 1111 0000)。

// 这通常用于设置端口的初始电平状态。

// 具体哪些引脚被设置为高电平或低电平取决于微控制器的硬件连接。

P5=0;

//设置时钟为24Mhz

P_SW2 =0x80;

CLKDIV = 0x04;

IRTRIM = T24M_ROMADDR;

VRTRIM = VRT20M_ROMADDR;

IRCBAND = 0x00;

CLKDIV = 0;

//等一下时钟稳定

delay_ms(500);

//从iap读配置

loadConfigFromIap();

Timer1_Init();

//写iap

saveConfigToIap();

其它引有到的代码如下:

void IapIdle()

{

IAP_CONTR = 0; //关闭IAP功能

IAP_CMD = 0; //清除命令寄存器

IAP_TRIG = 0; //清除触发寄存器

IAP_ADDRH = 0x80; //将地址设置到非IAP区域

IAP_ADDRL = 0;

}

char IapRead(int addr)

{

char dat;

IAP_CONTR = 0x80; //使能IAP

IAP_TPS = 24; //设置等待参数12MHz

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;

}

void IapProgram(int addr, char dat)

{

IAP_CONTR = 0x80; //使能IAP

IAP_TPS = 24; //设置等待参数12MHz

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功能

}

void IapErase(int addr)

{

IAP_CONTR = 0x80; //使能IAP

IAP_TPS = 24; //设置等待参数12MHz

IAP_CMD = 3; //设置IAP擦除命令

IAP_ADDRL = addr; //设置IAP低地址

IAP_ADDRH = addr >> 8; //设置IAP高地址

IAP_TRIG = 0x5a; //写触发命令(0x5a)

IAP_TRIG = 0xa5; //写触发命令(0xa5)

NOP(); //

IapIdle(); //关闭IAP功能

}

// IAP地址定义

#define CONFIG_IAP_ADDR 0x200 // 配置参数的IAP起始地址

// 从IAP读取配置参数

void loadConfigFromIap(void)

{

u8 tmp;

// 读取settings_mix

tmp = IapRead(CONFIG_IAP_ADDR);

settings_mix = (tmp == 0xFF || tmp == 0 || tmp > PARAM_MIX_ENABLE) ? PARAM_MIX_DISABLE : tmp;

}

// 保存配置参数到IAP

void saveConfigToIap(void)

{

// 先擦除IAP区域

IapErase(CONFIG_IAP_ADDR);

// 写入settings_mix

IapProgram(CONFIG_IAP_ADDR, settings_mix);

}

本主题由 管理团队 于 2025-6-27 09:17 移动