1.N76E003使用双串口串口1无法进入接收中断
N76E003在使能串口中断后,发送串口数据时,必须要先读TI/TI_1寄存器,再进入发送中断,并在中断中清除TI/TI_1寄存器的值。如若不然,则在串口0发送数据后将导致串口1无法进入中断。并且,经过测试发现,在这种情况下代码执行速度慢于正常情况下的速度。可以用一个简单的delay函数测试
一个完整的串口发送流程为:TI/TI_1清零--> SBUF/SBUF_1赋值-->轮询TI/TI_1的值(在发送成功后,会先被当前程序轮询到其值为1,再进入中断程序)-->进入中断-->清楚TI/TI_1
示例代码:
以使用N76E003官方bsp库为例。
void Send_Data_To_UART0(uint8_t c)
{
TI = 0;
SBUF = c;
while(TI==0);
}
void SerialPort0_ISR(void) interrupt 4
{
if (RI==1)
{ /* if reception occur */
clr_RI; /* clear reception flag for next reception */
}
if(TI==1)
{
clr_TI; /* if emission occur */
}
}
void Send_Data_To_UART1(uint8_t c)
{
TI_1 = 0;
SBUF_1 = c;
while(TI_1==0);
}
void SerialPort1_ISR(void) interrupt 15
{
if (RI_1==1)
{ /* if reception occur */
clr_RI_1; /* clear reception flag for next reception */
}
if(TI_1==1)
{
clr_TI_1; /* if emission occur */
}
}
2.使用双串口,波特率异常(115200 bps)
如下图通过数据手册可以看出在16Mhz的时钟下115200会有较大误差,故须将时钟配置为16.6Mhz
使用双串口的情况下串口0使用timer1作为时钟,串口1使用timer3作为时钟,在这种情况下,实际上timer1的时钟是16.588Mhz,需要按16.588Mhz来计算波特率,否则波特率有较大误差。(即便如此,在某些芯片上,波特率仍有固定误差,应和物料有关)
系统时钟16.6Mhz设置代码如下:
void MODIFY_HIRC_16588(void)
{
unsigned char hircmap0,hircmap1;
unsigned int trimvalue16bit;
set_IAPEN;
IAPAL = 0x30;
IAPAH = 0x00;
IAPCN = READ_UID;
set_IAPGO;
hircmap0 = IAPFD;
IAPAL = 0x31;
IAPAH = 0x00;
set_IAPGO;
hircmap1 = IAPFD;
clr_IAPEN;
//hircmap1 = hircmap1&0x01;
trimvalue16bit = ((hircmap0<<1)+(hircmap1&0x01));
trimvalue16bit = trimvalue16bit - 15;
hircmap1 = trimvalue16bit&0x01;
hircmap0 = trimvalue16bit>>1;
BIT_TMP=EA;
EA=0;
TA=0XAA;
TA=0X55;
RCTRIM0 = hircmap0;
TA=0XAA;
TA=0X55;
RCTRIM1 = hircmap1;
EA=BIT_TMP;
}
波特率设置示例代码如下:
void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
{
SCON = 0x52; //UART0 Mode1,REN=1,TI=1
TMOD |= 0x20; //Timer1 Mode1
set_SMOD; //UART0 Double Rate Enable
set_T1M;
clr_BRCK; //Serial port 0 baud rate clock source = Timer1
#ifdef FOSC_160000
//TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
TH1 = 256 - (1036750/u32Baudrate+1); /*16.588 MHz */
//TH1 = 256 - (1037500/u32Baudrate+1); /*16.6 MHz */
#endif
#ifdef FOSC_221184
TH1 = 256 - (1382400/u32Baudrate); /*22.1184 MHz */
#endif
set_TR1;
}
void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
{
P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1
T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1
clr_BRCK;
#ifdef FOSC_160000
//RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
//RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
#endif
#ifdef FOSC_166000
RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
#endif
set_TR3; //Trigger Timer3
}
3.管脚中断触发方式在中断中无法切换
在使用过程中发现如果先使能一个管脚中断为上升沿触发,再在中断中设置为下降沿触发,将会设置失败,下降沿将无法触发。必须退出中断后设置。
4.mcu软件启动方式切换后某些定时器未停止
在使用中发现如果软件从aprom重启并跳转到ldrom,若之前使能了定时器,则在ldrom代码中必须先停止定时器再清除TH0、TL0寄存器,然后再开始定时器(如果需要使用)。否则定时将异常(由于只使用timer 0作为通用定时器,故其他定时未验证)。
初始化定时器前清空TR0,数据手册有如下说明:在模式0或模式1下时,当读/写TH0(TH1)和TL0(TL1)之前,必须清除TR0(TR1)来停止计时。否则将产生不可预料的结果。
示例代码:
void Enter_IAP(void)
{
DEBUG("enter iaprn");
default_config[0] &= ~0x80;
program_config(BYTE_PROGRAM_CONFIG, default_config, 4);
// Delay10us(20);
BIT_TMP=EA;
EA=0;
TA = 0xAA;
TA = 0x55;
CHPCON |= SET_BIT1; // set boot from LP
TA = 0xAA;
TA = 0x55;
CHPCON |= 0x80; // software reset enable
EA=BIT_TMP;
}
void TM0_Init(void)
{
clr_TR0; //stop timer0 (if want reset TH0 or TL0,must clr TR0)
TH0=TL0=0; //interrupt timer 5.92 ms
set_TR0; //Start timer0
IE = 0x92; //EA=1, ES=1,ET0=1
}
5.掉电模式N76E003功耗偏高
可以有效降低掉电模式功耗的措施:
clr_BODEN; //关闭BOD欠压检测(通过代码关闭未验证,但在下载程序时取消该选项功耗降低明显)
clr_HIRCEN ;//关闭高速HIRC时钟(未使用)
clr_CLOEN; //关闭系统时钟输出(未验证)
clr_ADCEN;//关闭adc模块(已验证,有效防止漏电)
正常情况下,N76E003通过设置PCON寄存器的PD位进入待机模式时,mcu功耗只有5~6ua(只关闭欠压检测BOD,其他不动),但经过测试发现,如果进入掉电模式前使能了adc功能,则会导致该I/O管脚漏电,导致功耗达到几百ua,正确做法是在进入掉电模式前关闭adc模块。
示例代码:(以P04为例)
#define CLR_ADC P04_Input_Mode;clr_ADCEN;clr_ADCS
6.掉电模式N76E003的I/O引脚驱动能力不足
经过测试发现,在进入掉电模式后,N76E003的I/O输出电流将大幅降低,在部分应用场景下需要先将I/O引脚设置为推完模式,在进入掉电模式才能驱动部分电路。(包括但不限于某些wifi芯片的使能脚等)。相关文档如下图:
7.看门狗超时复位的最大超时时间过短
有别于其他mcu,N76E003的看门狗最大超时时间只有1.638s。其看门狗使用方式为:看门狗中断产生-->进入中断-->中断中喂狗。只要在看门狗中断触发的512个LIRC时钟周期内喂狗即可。相关文档如下图:
8. ADC采集电压第一次不准
在使用中发现N76E003的adc引脚如果之前的模式配置为准双向模式(其他模式未测试),则若是将改引脚设置为输入模式马上读取adc电压值,则会导致adc读取电压不准的情况(此时连续读取三次均不准),必需要等待一段时间,经测试几十个指令周期后即可。(时间可根据应用场景验证)。该现象的原因可能是外部电路给adc引脚的驱动电流较小,使adc引脚状态转换较慢。
9.mcu区分外部复位和上电复位
N76E003的AUXR1.6寄存器RSTPINF为复位标志位,但是上电复位和外部复位都将使该标志位置位,若只使用这个复位引脚将无法区分这两种复位状态。但可通过PCON的POF(上电复位标志位)标志位来加以判断。该位只在上电复位时置位。即引脚复位的情况为:POF为0,RSTPINF为1.
10. 关于N76E003的Keil编译器优化级别
经过测试发现如下问题:
串口代码,如果优化级别不是8,则存在串口无法正常使用的情况,即使变量定义为volatile类型亦然,且其官方bsp示例代码的工程配置优化级别均为8,若修改其优化级别,同样存在这个问题。
存在函数只声明但不定义但能编
译通过的情况。
存在头文件缺少#endif但能编译通过的情况
存在变量只extern声明未定义但能编译通过的情况
综上,编译器的警告信息一定要去关注!!!
上一篇:MS51替换N76E003注意事项
下一篇:N76E003配置看门狗watchdog
推荐阅读最新更新时间:2024-11-12 18:39
设计资源 培训 开发板 精华推荐
- LTC3631IDD 正负转换器的典型应用电路
- #第六届立创电赛#离线语音开关
- NCP139AFCT110T2GEVB:NCP139 WLCSP-6 评估板 1V1
- 用于 Intel Pentium VRE 处理器的 LT1585CM 4.6A 低压差稳压器的典型应用
- AM1S-0518SZ 1W DC-DC转换器典型应用
- Si9182 微功率 250mA CMOS 低噪声、全功能应用的典型应用具有错误标志/上电复位的 LDO 稳压器
- TDA8932B D 类音频功率放大器的对称电源立体声 SE 配置
- MC34072ADR2G 交流耦合反相放大器的典型应用
- 基于ESP8266的开发板(已验证)
- 使用 LTC2367IMS-18、18 位、500ksps、伪差分单极 SAR ADC 的典型应用