BoadLoader: 升级程序空间:0XF000-0XFF7F 中断向量地址:0XFF80-0XFFFF 用户程序: 程序空间:0x4400-0xf000 中断向量地址:0xEF80-0XEFFF 本程序是共用同一个串口,上电时,串口用于升级代码,升级完成以后用于用户程序进行数据接收,使用变量UpdateOk进行区分,但现在问题是:升级完用户程序以后,用户程序里面的TimerA进中断出中断均没有问题,但是复用的串口有问题: #pragma vector=USCI_A1_VECTOR __interrupt void USCI_A1_ISR(void) { if(UpdateOk==0) //升级使用 { unsigned char temp; switch(__even_in_range(UCA1IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? Cmd=UCA1RXBUF; CommandHandle(); //这个程序是升级代码用的,只要他存在,在进行用户程序接收数据时,就出问题,出串口中断的时候,出栈错误,进入到boadloader里面的子函数(某一个固定的地址),进而程序跑飞,因此肯定是压栈出问题直接导致出栈出问题 break; case 4:break; // Vector 4 - TXIFG default: break; } }else if(UpdateOk==1) //用户程序接收数据用 { asm("BR &0xEFDC"); //跳转到应用程序的串口中断向量 } } 程序框架: void main(void) { /*** Basic Setting ***/ WDTCTL = WDTPW + WDTHOLD; // Stop WDT UpdateOk=0; //升级变量 /*** Regular Init ***/ IOS_Init(); // IO口初始化 SCI_Init(); // 串口初始化
/*** Prepare Start ***/ EnableInterrupt; delay(5); SCI_TxStr((unsigned char *)Item1); // Send Item1 BootInformation
/*** Main Loop ***/等到2秒钟检测是否有串口数据的到来,如果有就进行升级,如果没有就asm("BR &0xEFFE");跳转到用户程序里的复位向量,进而执行应用程序 while( Waiting<30 ) { P1OUT=0x01; // LED blink delay(50); P1OUT=0x02; // LED blink delay(50); if(FlxSts==UnBoot) // QuitTime Test Waiting++; if(FlxSts==QuitBoot) // Quit Directly Waiting=100; }
SCI_TxStr((unsigned char *)Item6); // Quit Bootloader SCI_Deinit(); UpdateOk=1;// Deinit SCI asm("BR &0xEFFE"); } #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) { // P1OUT ^= BIT3; // Toggle P1.0 asm("BR &0xEFEA"); //跳转到用户程序的定时器中断向量,这个工作完全正常 }
用户程序: void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= BIT3; // P1.0 output TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = 50000; TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR
P4SEL = BIT5+BIT4; // P3.4,5 = USCI_A0 TXD/RXD UCA1CTL1 |= UCSWRST; // **Put state machine in reset** UCA1CTL1 |= UCSSEL_2; // SMCLK UCA1BR0 = 6; // 1MHz 9600 (see User's Guide) UCA1BR1 = 0; // 1MHz 9600 UCA1MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0, // over sampling UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __no_operation(); // For debugger }
// Timer0 A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) { P1OUT ^= BIT3; // Toggle P1.0 } #pragma vector=USCI_A1_VECTOR __interrupt void USCI_A1_ISR(void) { switch(__even_in_range(UCA1IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = UCA1RXBUF; // TX -> RXed character break; case 4:break; // Vector 4 - TXIFG default: break; } }
|