|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 晴天不会哭 于 2019-3-24 14:03 编辑
RT,最近在做一个双路PWM,色温亮度独立可调的LED台灯,各种都调试好了,最后加上读写EEPROM,用来保存亮度和色温时出现了问题。因为要做双路PWM,15只有两个定时器,只能一个用来模拟PWM,一个用作计时。T0产生10US的中断,为了提高精度,总计数200次,频率为500HZ。
现在的问题就是如果不关中断,则擦除扇区时会爆闪,关了中断,会熄灭一下,读和写的时候都没问题,只有擦除时候会出现,提高T0定时器中断时间为20US问题依旧。通过屏蔽语句发现只有擦除会导致这个问题。下面贴上相关代码,等全做好了,再把台灯的全部代码放上来。
保存亮度和色温的函数,Brigheness代表亮度,uchar,占用一个字节,保存在0x200处;CCT代表色温,uchar,占用一个字节,保存在0x201处
- if(save_time == 25)
- {
- saved = 1;
- save_time = 0;
- save_flag = 0;
- EA = 0;
- eraseEEP(0x0200);
- // EA = 1;
- // delay(50);
- //EA = 0;
- writeEEP(0x0200,Brightness);
- writeEEP(0x0201,CCT);
- EA = 1;
- }
复制代码
下面是定时器T0的初始化和中断处理函数- /***************** 定时器和外部中断初始化函数*******************/
- void interruptInit(void)
- {
- /*********************定时器0初始化****************************/
- AUXR |= 0x80; //定时器0为1T模式
- TMOD &= 0xf0; //设置定时器0为模式0(16位自动重装载)
- PT0 = 1; //高优先级中断
- TL0 = 0xD4; //设置定时初值10us,作为PWM的时基
- TH0 = 0xFE; //设置定时初值
- TF0 = 0; //清除TF0标志
- ET0 = 1; //使能定时器0中断
-
- /********************定时器2初始化****************************/
- AUXR &= 0xFB; //定时器2时钟12T模式
- T2L = 0xE0; //设置定时初值 20ms
- T2H = 0xB1; //设置定时初值
- IE2 |= 0x04; //使能定时器2中断
- /*******************外部中断1初始化***************************/
- IT0 = 1; //设置INT1中断类型(1:仅下降沿 0:上升沿和下降沿),对应编码器按钮
- EX0 = 1; //使能INT1中断
-
- EA = 1;
- TR0 = 1; //定时器0开始计时
- AUXR |= 0x10; //定时器2开始计时
- }
复制代码
下面是EEPROM的函数- void IAPIDLE()
- {
- IAP_CMD = 0; //关闭令,保护
- IAP_CONTR = 0; //关EEPROM,保护
- IAP_TRIG = 0;
- IAP_ADDRL = 0; //设置读取地址的低字节,地址改变才需要设置
- IAP_ADDRH = 0X80; //设置读取地址的高字节,地址改变才需要设置
- }
- unsigned char readEEP(unsigned int adddata)
- { //读取
- unsigned char eerdata;
- IAP_CONTR=0X83;//设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
- IAP_CMD = 1; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
- IAP_ADDRL = adddata; //设置读取地址的低字节,地址改变才需要设置
- IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
- IAP_TRIG = 0x5A; //先送5A
- IAP_TRIG = 0xA5; //先送5A再送A5立即触发
- _nop_();
- eerdata=IAP_DATA;
- IAPIDLE();
- return eerdata;
- }
- void writeEEP(unsigned int adddata, unsigned char eerdata)
- {//写入
- IAP_CONTR=0X83;//设置等待时间,
- IAP_CMD = 2; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
- IAP_ADDRL = adddata; //设置读取地址的低字节,地址改变才需要设置
- IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
- IAP_DATA= eerdata;//传入数据
- IAP_TRIG = 0x5A; //先送5A
- IAP_TRIG = 0xA5; //先送5A再送A5立即触发
- _nop_();
- IAPIDLE();
- }
- void eraseEEP(unsigned int adddata)
- { //擦除
- IAP_CONTR=0X83;//设置等待时间,
- IAP_CMD = 3; //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
- IAP_ADDRL = adddata; //设置读取地址的低字节,地址改变才需要设置
- IAP_ADDRH = adddata>>8; //设置读取地址的高字节,地址改变才需要设置
- IAP_TRIG = 0x5A; //先送5A
- IAP_TRIG = 0xA5; //先送5A再送A5立即触发
- _nop_();
- IAPIDLE();
- }
复制代码
|
打赏
-
查看全部打赏
|