Xmega 시리즈로 USART를 인터럽트를 통한 송수신을 하는 경우, 동시에 타이머 인터럽트도 사용하려 할때에....


USART 인터럽트 송수신이 안될수도 있다. 아직 정확한 이유는 모름...ㅠㅠ 좀 더 파봐야 하는데 굳이 파고 싶지는.....흐...


그러나, 타이머의 prescaler와 무관하게 Polling방식의 USART통신에는 아무런 문제가 없다.


해결방법은 타이머의 Clock Selection을 CLK/64 보다 큰 값으로 해야 만 한다.


참고로, 내가 확인한 컨디션은 ATXMega32A4U / 내부클럭 32MHz / 타이머 인터럽트 1개 / USART 4개 이다.



USART 통신을 하기위한 관련 레지스터 설정은


1. 해당포트의 Direction 설정


2. 통신 포맷 설정


3. 인터럽트 레벨 설정


4. 보드레이트 설정


5. Rx 및 Tx Enable 이다.


사용 되어진 함수는 usart_driver.c 에 있는 함수 들이다. ( https://github.com/Synapseware/xmega-intro/tree/master/avr1522-usart/code )



 cli();


   /* PC3 PC7 (TXD0,1) as output. */
 PORTC_OUTSET = PIN3_bm | PIN7_bm; 
 PORTC.DIRSET = PIN3_bm | PIN7_bm;
 /* PC2 PC6 (RXD0,1) as input. */
 PORTC_OUTCLR = PIN2_bm | PIN6_bm;
 PORTC.DIRCLR   = PIN2_bm | PIN6_bm;


   /* PD3 PD7 (TXD0,1) as output. */
 PORTD_OUTSET = PIN3_bm | PIN7_bm;
 PORTD.DIRSET = PIN3_bm | PIN7_bm;
 /* PD2 PD6 (RXD0,1) as input. */
 PORTD_OUTCLR = PIN2_bm | PIN6_bm;
 PORTD.DIRCLR   = PIN2_bm | PIN6_bm;


 USART_InterruptDriver_Initialize(&COM0_data, &COM0, USART_DREINTLVL_LO_gc);
 USART_Format_Set(COM0_data.usart, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
 USART_RxdInterruptLevel_Set( COM0_data.usart, USART_RXCINTLVL_LO_gc);
 USART_Baudrate_Set( &COM0, 832 , 0);  // CLK2X = 0, bsel = 832, bscale = 0  ==>> 2400
 USART_Rx_Enable( COM0_data.usart );  
 USART_Tx_Enable( COM0_data.usart );


 USART_InterruptDriver_Initialize(&COM1_data, &COM1, USART_DREINTLVL_LO_gc);
 USART_Format_Set(COM1_data.usart, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
 USART_RxdInterruptLevel_Set( COM1_data.usart, USART_RXCINTLVL_LO_gc);
 USART_Baudrate_Set( &COM1, 832 , 0);  // CLK2X = 0, bsel = 832, bscale = 0  ==>> 2400
 USART_Rx_Enable( COM1_data.usart );  
 USART_Tx_Enable( COM1_data.usart );


 USART_InterruptDriver_Initialize(&COM2_data, &COM2, USART_DREINTLVL_LO_gc);
 USART_Format_Set(COM2_data.usart, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
 USART_RxdInterruptLevel_Set( COM2_data.usart, USART_RXCINTLVL_LO_gc);
 USART_Baudrate_Set( &COM2, 832 , 0);  // CLK2X = 0, bsel = 832, bscale = 0  ==>> 2400
 USART_Rx_Enable( COM2_data.usart );  
 USART_Tx_Enable( COM2_data.usart );


 USART_InterruptDriver_Initialize(&COM3_data, &COM3, USART_DREINTLVL_LO_gc);
 USART_Format_Set(COM3_data.usart, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
 USART_RxdInterruptLevel_Set( COM3_data.usart, USART_RXCINTLVL_LO_gc);
 USART_Baudrate_Set( &COM3, 832 , 0);  // CLK2X = 0, bsel = 832, bscale = 0  ==>> 2400
 USART_Rx_Enable( COM3_data.usart );  
 USART_Tx_Enable( COM3_data.usart );


 /* Enable PMIC interrupt level low. */
 PMIC.CTRL |= PMIC_LOLVLEX_bm;


 /* Enable global interrupts. */
 sei();





-------------------------------------------------------------<< 참고 사항 >>-------------------------------------------------------------------


데이터 시트

http://www.ue.eti.pg.gda.pl/~bpa/kolo_chip/warsztaty2017/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf


USART 관련 소스

https://github.com/Synapseware/xmega-intro/tree/master/avr1522-usart


xmega 관련소스

https://github.com/Synapseware/xmega-intro