被这个代码卡脖子了..有大佬伸出援助之手吗?
本帖最后由 vb2002 于 2024-8-3 14:15 编辑代码 断电换挡 (该部分之前已经实现了),但是只写入一点点东西,需要擦除整个扇区.
现在是先写,写完整个扇区,然后擦除,擦头开始写.
代码和 .c.h文件附上
#include "stc8h.h"
#include "intrins.h"
#include "eeprom.h"
#include <stdio.h>
#define MAIN_Fosc 11059200UL
#define BRT (65536 - MAIN_Fosc / 115200 / 4)
//#define add 0x0E00
typedef unsigned char u8;
typedef unsigned int u16;
u8 state;
u8 show,cnt;
u8 dat;
u16 EEPROMId = 0XE00;
bit key_flag;
//void delayms(u16 ms);
void sys_init();
void PWM_init(void);
//void Timer0_Init(void);
void UartInit()
{
SCON = 0x5a;
T2L = BRT;
T2H = BRT >> 8;
AUXR = 0x15;
}
void UartSend(char dat)
{
while (!TI);
TI = 0;
SBUF = dat;
}
void main()
{
sys_init();
UartInit();
IapIdle();
dat = IapRead(EEPROMId+1);
if(dat == 0XFF)
{
dat = IapRead(EEPROMId);
}
else
{
EEPROMId++;
}
if(EEPROMId >= 0XFFD)//如果当前字节到达EEPROM末尾,擦除扇区所有数据
{
// SetMode(CMD_ERASE); //扇区擦除
IapErase(0x0e00); //擦除扇区
}
UartSend(IapRead(dat));
UartSend(IapRead(EEPROMId));
PWMA_CCR1 = state;
// if(temp != 0xFF) number = temp;
while(1)
{
switch(state)
{
case 0 :IapProgram(EEPROMId+1,state); PWMA_CCR1 = 5; break;
case 1 :IapProgram(EEPROMId+1,state); PWMA_CCR1 = 15; break;
case 2 :IapProgram(EEPROMId+1,state); PWMA_CCR1 = 55; break;
case 3 :IapProgram(EEPROMId+1,state); PWMA_CCR1 = 250; break;
default:break;
}
}
}
void sys_init(void)
{
P_SW2=0x80;
P3M0 = 0x00; P3M1 = 0x00; P1M0 = 0x00; P1M1 = 0x00;
PWM_init();
// Timer0_Init();
IT0=1;EX0=1;
INTCLKO|=0x40; //EX4=1; 允许INT4外部中断
// IP2H=0x00;
IP2=0x10;
EA=1; //打开总中断
}
//// 初始化PWM功能
void PWM_init(void) {
PWMA_CCER1 = 0x00; // 写CCMRx前必须先清零CCERx关闭通道
PWMA_CCMR1 = 0x60; // 设置CC1为PWMA输出模式
PWMA_PS = 0x00; //
PWMA_CCER1 = 0x03; // 使能CC4通道双极
PWMA_CCR1 = 0; // 初始化CCR4计数值为0
PWMA_ARR = 256; // 设置周期时间为12000个计数周期
PWMA_ENO = 0x01; // 使能PWM4P+N端口输出
PWMA_PSCR = 0; // PWM时钟预分频寄存器设置为0
PWMA_BKR = 0x80; // 使能主输出
PWMA_CR1 = 0x01; // 开始计时
}
//void Timer0_Isr(void) interrupt 1
//{
// flag=1;
//}
//void Timer0_Init(void) //1毫秒@11.0592MHz
//{
// AUXR |= 0x80; //定时器时钟1T模式
// TMOD &= 0xF0; //设置定时器模式
// TMOD |= 0x01; //设置定时器模式
// TL0 = 0xCD; //设置定时初始值
// TH0 = 0xD4; //设置定时初始值
// TF0 = 0; //清除TF0标志
// TR0 = 1; //定时器0开始计时
// ET0 = 1; //使能定时器0中断
//}
void INT4_Isr(void) interrupt 16
{
IAP_CONTR=0x60;
}
void INT0_Isr(void) interrupt 0
{
}
void delayms(u16 ms)
{u16 i;
do{
i = MAIN_Fosc /10000;
while(--i);
} while(--ms);
}
wnagming 发表于 2024-8-3 16:54
我刚才看到库函数有EEPROM的操作函数,要是你的EEPROM.c不能用,在官网下载库函数用呗,先把EEPROM的读写擦 ...
库函数跑起来没问题.eeprom均衡写入就不会弄了
wnagming 发表于 2024-8-3 17:10
就这么几行代码你要是还看不明白,我真没办法了
我调用了.但是老是报错,要不你抽两分钟,帮我改一下?
放在我的代码里 {:4_167:} wnagming 发表于 2024-8-3 17:20
报错截图来看看
这个是我的代码,劳您看一眼
库函数的调用 我用的其他文件夹
库文件已经添加只目录内了
wnagming 发表于 2024-8-3 17:29
报错截图,我要看截图
我加你微信了
我重新整理下 wnagming 发表于 2024-8-3 17:34
驾校教练?佩服
是啊,驾校教练.{:4_170:}
现在可以写了.
就是led点不亮了
刚刚把u8 dat 和u16 eepromid,移到全局变量去了.可以点亮,但是又不能换挡了!!
wnagming 发表于 2024-8-3 19:54
好好看视频学习一下吧
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=323
{:4_196:}感谢大佬指点, wnagming 发表于 2024-8-3 20:02
u8 dat 和u16 eepromid这两个尽量放在函数内,全局变量不宜太多,用函数返回值做数据就好 ...
我加了定时器上去,
通电开始计时,3秒内关机再开,就换下一个档,3秒后关机再开就是就是当前档位不变
代码加在定时器中断里面
if (time<3000)
运行switch
else
这后面不会写了 wnagming 发表于 2024-8-4 17:09
后面就不用写了,time
这样没效果.
void Timer0_Isr(void) interrupt 1
{
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
if(time<200)
{
switch(dat)
{
case 254: IapProgram(EEPROMId+1,1);break;
case 1: IapProgram(EEPROMId+1,15);break;
case 15: IapProgram(EEPROMId+1,55);break;
default: IapProgram(EEPROMId+1,254);break;
}
}
else
{
}
if(time<200) time++;
}
{:4_174:}{:4_174:}学习