编写了一个简单的程序, 仅有串口,测试串口可否在掉电模式唤醒,中断唤醒后,会进入正常模式,
在主循环while里,执行__WFI();让cpu时钟停掉,发现串口发了6000次数据(aa 01 02 03 04),有18次没有返回,失误率大。求解答??
程序见下
#define UART0_BAUD 2400
#define UART_RX_WORK_BIT 0x01
#define UART_TX_WORK_BIT 0x02
主程序
void Timer3_Init(void)
{
volatile unsigned long delay = 5000;
CLK->CLKSEL2 = (CLK->CLKSEL2 & ~CLK_CLKSEL2_TMR3_MASK)|CLK_CLKSEL2_TMR3_LXT;
CLK->APBCLK |= CLK_APBCLK_TMR3_EN;
TIMER3->CTL = TIMER_CTL_MODESEL_PERIODIC;
TIMER3->PRECNT = 0;
TIMER3->CMPR = (unsigned long)(32768/10 + 0.5);
TIMER3->ISR = TIMER_ISR_TMRIS; //Clear Interrupt Status
// Enable TIMER3 Intettupt
TIMER3->IER = TIMER_IER_TMRIE;
NVIC_EnableIRQ(TMR3_IRQn);
NVIC_SetPriority(TMR3_IRQn,2);
while(delay--);
// Start counting
TIMER3->CTL |= TIMER_CTL_TMREN | TIMER_CTL_WAKEEN;
}
void TMR3_IRQHandler(void)
{
TIMER3->ISR = TIMER3->ISR; //清中断标志位
if(timeout)
{
if(--timeout == 0)
{
timeout= 0;
UART0->CTL |= 0x200;
g_ucUart1WorkFlag &= ~UART_RX_WORK_BIT;
}
}
}
int32_t main(void)
{
do
{
UNLOCKREG();
}while(GCR->RegLockAddr & 0x01 == 0);
CLK->PWRCTL = 0x0e;
while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB)); //等待时钟稳定
CLK->CLKDIV0 = 0x00;
CLK->PWRCTL |= CLK_PWRCTL_LXT_EN; // for LXT
while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_LXT_STB));
/* Select HCLK from HIRC */
CLK->CLKDIV0 &= ~CLK_CLKDIV0_HCLK_MASK; /* divider is 0 */
CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_HCLK_MASK) | CLK_CLKSEL0_HCLK_HIRC; /* HCLK = 12MHz */
uart0_init();
Timer3_Init();
OS_EnInt();
while(1)
{
if(g_ucUart1WorkFlag)
{
if(UART0->FSR & UART_FSR_TE_F)
{
g_ucUart1WorkFlag &= ~UART_TX_WORK_BIT;
}
__WFI(); //休眠
}
else
{
OS_DisInt();
UART0->CTL |= 0x200;
CLK->PWRCTL = 0x5e;
SCB->SCR = 0x04;
OS_EnInt();
if(!g_ucUart1WorkFlag)
__WFI(); //休眠
}
}
}
串口程序
void uart0_init(void)
{
u32 tmp;
/* Select UART Clock Source From 12Mhz*/
CLK->CLKSEL1 = (CLK->CLKSEL1 & ~CLK_CLKSEL1_UART_MASK)|CLK_CLKSEL1_UART_HIRC;
/* Set UART1 Pin */
//GCR->PB_L_MFP &= ~(PB5_MFP_MASK | PB4_MFP_MASK);
//GCR->PB_L_MFP |= PB5_MFP_UART1_TX | PB4_MFP_UART1_RX;
MFP_UART0_TO_PORTA();
/* Reset IP */
GCR->IPRST_CTL2 |= GCR_IPRSTCTL2_UART0;
GCR->IPRST_CTL2 &= ~GCR_IPRSTCTL2_UART0;
/* Enable UART clock */
CLK->APBCLK |= CLK_APBCLK_UART0_EN;
/* Tx FIFO Reset & Rx FIFO Reset & FIFO Mode Enable */
UART0->CTL |= UART_CTL_RX_RST;
UART0->CTL |= UART_CTL_TX_RST;
/* Set Rx Trigger Level, Parity & Data bits & Stop bits */
UART0->TLCTL = ((DRVUART_FIFO_1BYTES << 8) |
(DRVUART_PARITY_EVEN << 3) |
(DRVUART_STOPBITS_1 << 2) |
(DRVUART_DATABITS_8) );
/* Set Time-Out */
// UART0->TMCTL &= ~UART_TMCTL_TOIC;
// UART0->TMCTL |= 20 & UART_TMCTL_TOIC;
/* Set BaudRate */
UART0->BAUD &= ~UART_BAUD_DIV_16_EN;
//波特率计算公式为 UART_CLK / [(BRD+1)]
tmp = CLK->CLKDIV0 & 0x0f00;
UART0->BAUD |= (u32)(12000000.0/((tmp>>8)+1)/UART0_BAUD - 1);
UART0->CTL |= 0x200;
UART0->IER = DRVUART_RDAINT | DRVUART_WAKEUPINT;// | DRVUART_TOUTINT;
NVIC_EnableIRQ(UART0_IRQn);
}
void uart0_send_str(u8 *str, u16 len)
{
g_ucUart1WorkFlag |= UART_TX_WORK_BIT;
while(len--)
{
while(UART0->FSR & UART_FSR_TX_FULL_F);
UART0->THR = *str++;
}
}
void UART0_IRQHandler(void)
{
u32 status;
status = UART0->ISR;
//换醒中断
if(status & DRVUART_WAKEUPINT)
{
UART0->ISR |= DRVUART_WAKEUPINT;
g_ucUart1WorkFlag |= UART_RX_WORK_BIT;
timeout=4;
}
//接收数据中断
else if(status & DRVUART_RDAINT)
{
if(UART0->FSR & 0x0800)
{
g_ucUart1WorkFlag |= UART_RX_WORK_BIT;
bufdata[0]=UART0->RBR;
{
uart0_send_str(&bufdata[0],1);
}
}
}
}
|