#include "msp430x12x2.h" ;****************************************************************************** ; MSP430F1232 Education System 1.3 - USART0 UART 19200 Ultra-low Echo ISR, 32kHz ACLK+DCO ; ; Description; Echo a received character, USART0 RX ISR at high-speed used ; with ultra-low power techniques. Normal operation in LPM3, Set_DCO ; subroutine needs to be called to stabalizes DCO used for UART baud ; generation. On valid RX character, character echoed back. Use start-bit ; edge detect - URXSE - to automatically (re)enable DCO and trigger ISR. ISR ; must insure a clock source (DCO remains enabled for the UART to receive ; full character. Software needs to insure character has been completely ; TX'ed before entering LPM3, which disables DCO. ; ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = UCLK0 = DCOCLK = 1048576 ; Baud rate divider with 1048576hz = 1048576Hz/19200 ~ 55 (0036h) ; //*An external 32kHz watch crystal on XIN XOUT is required for ACLK*// ; ; Dieses Programm realisiert ein UART Echo. Ein empfangenes Byte wird an den Sender ; zurueckgesendet. Der interne DCO kann mit Hilfe des externen 32kHz Quarz so ; kalibriert werden, dass auf Grundlage des DCO eine Bitgeschwindigkeit von 19200bit/s ; erreicht werden. Das Hauptprogramm befindet sich nach der Initialisierung im ; Low-Power-Mode. Das Senden, des empfangenen Bytes erfolgt in der RX Interrupt Routine. ; Delta equ 256 ; Delta = (target DCO)/(4096) = 1048576 ; ; MSP430F123(2) ; ----------------- ; /|\| XIN|- ; | | | 32768Hz ; --|RST XOUT|- ; | | ; | P3.4|------------> ; | | 19200 - 8N1 ; | P3.5|<------------ ; ; W.Lutsch, T.Wengemuth ; FTZ Leipzig e.V. ; September 2003 ; ;****************************************************************************** ;------------------------------------------------------------------------------ ORG 0E000h ; Program Start ;------------------------------------------------------------------------------ RESET mov.w #0300h,SP ; Initialize stackpointer call #Init_Sys ; ; Mainloop bit.b #TXEPT,&UTCTL0 ; Confirm no TXing before --> LPM3 jz Mainloop ; bis.b #LPM3,SR ; Enter LPM3 jmp Mainloop ; ; ;------------------------------------------------------------------------------ Init_Sys; Initalize MSP430 system ;------------------------------------------------------------------------------ StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Stop WDT SetupBC bis.b #DIVA1+DIVA0,&BCSCTL1 ; ACLK = LFXT1CLK/8 call #Set_DCO ; Calibrate DCOCLK SetupUART0 mov.b #CHAR,&UCTL0 ; 8-bit char mov.b #SSEL1+URXSE,&UTCTL0 ; UCLK = SMCLK, start edge detect mov.b #036h,&UBR00 ; 1MHz 19200 mov.b #000h,&UBR10 ; 1MHz 19200 mov.b #000h,&UMCTL0 ; 1MHz 19200 modulation bis.b #UTXE0+URXE0,&ME2 ; Enable USART0 TXD/RXD bis.b #URXIE0,&IE2 ; Enable USART0 RX interrupt SetupP3 bis.b #030h,&P3SEL ; P3.4,5 = USART0 TXD/RXD bis.b #010h,&P3DIR ; P3.4 = output direction eint ; General enable interrupts ret ; Return from subroutine ; ;----------------------------------------------------------------------------- Set_DCO; Subroutine: Sets DCO to selected frequency based on Delta. ; R14 and R15 are used, ACLK= 32768/8 Timer_A clocked by DCOCLK ;----------------------------------------------------------------------------- clr.w R15 ; Setup_TA mov.w #TASSEL1+TACLR+MC1,&TACTL ; SMCLK, clear, cont. mode Setup_CC2 mov.w #CCIS0+CM0+CAP,&CCTL2 ; Define CCR2,CAP,ACLK Test_DCO bit.w #CCIFG,&CCTL2 ; Test capture flag jz Test_DCO ; bic.w #CCIFG,&CCTL2 ; Clear capture flag ; AdjDCO mov.w &CCR2,R14 ; R14 = captured SMCLK sub.w R15,R14 ; R14 = capture difference mov.w &CCR2,R15 ; R15 = captured SMCLK cmp.w #Delta,R14 ; Delta = SMCLK/(32768/4) jlo IncDCO ; jeq DoneDCO ; DecDCO dec.b &DCOCTL ; Slow DCO with DCO and MOD jnz Test_DCO ; Slower? bit.b #07h,&BCSCTL1 ; Can RSEL.x be decremented? jz DoneDCO ; jmp>DCO at slowest setting dec.b &BCSCTL1 ; Decrement RSEL.x jmp Test_DCO ; IncDCO inc.b &DCOCTL ; Speed DCO with DCO and MOD jnc Test_DCO ; Faster? cmp.b #07h,&BCSCTL1 ; Can RSEL.x be increased? jz DoneDCO ; jmp> DCO at fastest settting inc.b &BCSCTL1 ; Increment RSEL.x jmp Test_DCO ; DoneDCO clr.w &CCTL2 ; Stop CCR2 clr.w &TACTL ; Stop timer_A ret ; Return from subroutine ; ;------------------------------------------------------------------------------ USART0RX_ISR; Echo back RXed character, confirm TX buffer is ready first ;------------------------------------------------------------------------------ bit.b #URXIFG0,&IFG2 ; Interrupt from complete char? jc TX1 ; Jump--> interrupt from char bic.b #SCG1+SCG0,0(SP) ; Enter LPM0 on reti reti ; ; TX1 bit.b #UTXIFG0,&IFG2 ; USART0 TX buffer ready? jz TX1 ; Jump is TX buffer not ready mov.b &RXBUF0,&TXBUF0 ; TX -> RXed character bic.b #LPM3,0(SP) ; Exit LPM3 on reti reti ; ; ;------------------------------------------------------------------------------ ; Interrupt Vectors Used MSP430x12x ;------------------------------------------------------------------------------ ORG 0FFFEh ; DW RESET ; POR, ext. Reset, Watchdog ORG 0FFEEh ; DW USART0RX_ISR ; USART0 receive end