大家好!
我有一个具有 CC2510F32芯片的定制器件。 我有外部26MHz 示波器、并使用内部低 RC。
当我有一个器件并且写入 FW 都正常时、程序工作正常。
在生产阶段、我们遇到了一些器件的问题。 大多数设备工作正常、但有些设备在几次试验后、几次重启后挂起。 几天后还有一些其他的事情要做。 很少有人会"持续重启"。
我想、器件有相同的问题、但由于硬件原因、它以不同的方式表现出来。
我在启动后、打开外部振荡器之前添加了延迟。 有些设备开始工作、有些则不工作。
我试图在设备中发现问题、该设备已"持续重启"。 我关闭了除 UART 之外的所有外设、发现它在进入/退出睡眠(PM2)期间挂起。 我阅读了勘误表、但它对我没有帮助、我从一开始就使用了所有这些例外情况。 以下是进入睡眠模式的代码(我使用内部振荡器):
函数 hsinit();和 sleep_timer_setup()
void bsp_HAL_GotoSleep (无符号整型超时)
{
volatile char storedDescHigh、storedDescLow;
hsinit();
SLEEP_TIMER_setup((超时&0x00FF),(超时&0xFF00)>>8);
//SLEEP_TIMER_INIT
stie = 1;
//使用正确的源更新描述符。
storedDescHigh = DMA0CFGH;
storedDescLow = DMA0CFGL;
DMAARM |= 0x81;
dmaDesc[0]=(无符号整型)&PM2_BUF >> 8;
dmaDesc[1]=(无符号整型)&PM2_BUF;
//将描述符与 DMA 通道0关联并 ARM DMA 通道
DMA0CFGH =(无符号整型)&dmaDesc >> 8;
DMA0CFGL =(无符号整型)&dmaDesc;
DMAARM=1;
//注意! 此时、请确保所有不会被使用的中断
//从 PM 唤醒被禁用、如数据表的第13.1.3章所述。
RFIF=0;
//RFIM=0;
//TCON=0x05;//CPU INT
//S0CON=0;
//S1CON=0;
//与13.8.2章中描述的正32kHz 时钟边沿对齐
数据表的//。
char temp = WORTIME0;
while (temp == WORTIME0);
WORCTL |= 0x04;//需要????? //重置睡眠定时器
MEMCTR |= 0x02;//闪存缓存被禁用。
SLEEP = 0x06;//(SLEEP & 0xFC)| 2);//选择电源模式3 //注意调试器停止程序继续--
//如果希望它与调试器一起工作,请将模式更改为0
asm ("NOP");
asm ("NOP");
asm ("NOP");
//进入电源模式
IF (睡眠和0x03)
{
//asm ("MOV 0xD7、#0x01");// DMAREQ = 0x01;
//asm ("NOP");
//PCON |= 1;
//asm ("NOP");
asm ("MOV 0xD7、#0x01");// DMAREQ = 0x01;
asm ("NOP");//需要完全对齐 DMA 传输
asm ("ORL 0x87、#0x01");//asm ("ORL 0xD7、#0x01");// PCON |= 0x01;
asm ("NOP");
}
MEMTR &=~2;//启用闪存。
DMA0CFGH = storedDescHigh;//<-在这里、它从睡眠中退出
DMA0CFGL = storedDescLow;
DMAARM=1;
}
void xtalinit (void)
{
while (((SLEEP & 0x40)&&(SLEEP & 0x20))=0);//等待高速晶振稳定
SLEEP &=~0x04;//OSC_PD = 0 -所有示波器加电
CLKCON &=~0x07;//clk = 0
while (CLKCON & 0x07);
CLKCON &=~0x38;//tck = 0
while (CLKCON & 0x38);
CLKCON &=~0x40;//打开外部示波器
while (CLKCON & 0x40);
CLKCON=0x80;
while (CLKCON!= 0x80);
SLEEP |= 0x04;//关闭未选择的振荡器、即 RC 振荡器
}
void hsinit (void)
{
while (((SLEEP & 0x40)&&(SLEEP & 0x20))=0);//等待高速晶振稳定
SLEEP &=~0x04;//OSC_PD = 0 -所有示波器加电
CLKCON |= 0x40;//打开内部振荡器
while (!(CLKCON & 0x40));
CLKCON = 0x40 | 0x01;//on rc32、rcosc、tk/2、clk/2
while (CLKCON!= 0x40 | 0x01);
CLKCON |= 0x08;//tck 不能高于 clk
while (CLKCON!= 0x40 | 0x08 | 0x01);
CLKCON |= 0x80;
while (CLKCON!= 0x80 | 0x40 | 0x08 | 0x01);
SLEEP |= 0x04;//关闭未选择的振荡器、即 RC 振荡器
}
void sleep_timer_setup (char time1、char time2)
{
WORCTL =(WORCTL & 0xFC)| 0x01;//设置[WORCTL.WOR_RES = 1] 0 = 1、1 = 2^5、2 = 2^10
WORCTL |= WORCTL_WOR_RESET;//重置睡眠定时器
char temp = WORTIME0;
while (temp = WORTIME0);//等待一个正32kHz 边沿
temp = WORTIME0;
while (temp = WORTIME0);//等待一个正32kHz 边沿
WOREVT0 = TIME1;//使用12 (0x0C)作为最小 EVENT0值=11.72ms 每个位为0.9766ms Xtal32和0.923ms rc34.666K
WOREVT1 = TIME2;// EVENT1值= 11.72ms 每个位为0.9766ms Xtal32和0.923ms rc34.666K
}