ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
5 мая
672326 Топик полностью
Звероящер (04.05.2016 15:57, просмотров: 471) ответил SciFi на Он ведь взял на себя повышенное обязательство - писАть на Цэ++. Теперь голый си даже десятиместровой палкой трогать противно :-)
Ну почему-же. Просто привык как-то так писать... Понятно всё и удобно.  /************************************************************************* ** ** File: usart.h ** Summary: USART class and constants ** Version: 1.0 ** Date: 06.08.2009 ** ************************************************************************** ** ** Functions: ** ** ** Compiler: IAR AVR 3.20c ** Remarks: ** **************************************************************************/ #ifndef _USART_H #define _USART_H /*************************************************************************/ #include "mcu_cfg.h" #include <types.h> /*************************************************************************/ // see USART configuration in mcu_cfg.h /*************************************************************************/ // YOU MUST PLACE USART PINS DEFINITIONS BELOW TO mcu_cfg.h IN ROOT DIR // IT IS EXAMPLE. DO NOT UNCOMMENTED HERE. JUST COPY TO mcu_cfg.h /* #define USART_TX 1 #define USART_RX 0 */ /*************************************************************************/ #define usart_Rx_buffer_size 128 //1,2,4,8,16,32,64,128 or 256 bytes #define usart_Rx_buffer_mask (usart_Rx_buffer_size-1) #define usart_Tx_buffer_size 128 //1,2,4,8,16,32,64,128 or 256 bytes #define usart_Tx_buffer_mask (usart_Tx_buffer_size-1) #if (usart_Rx_buffer_size&usart_Rx_buffer_mask)//просто проверка #error Rx buffer size is not a power of 2 #endif #if (usart_Tx_buffer_size&usart_Tx_buffer_mask) #error Tx buffer size is not a power of 2 #endif /*************************************************************************/ class CUsart { public: static void Init(); static u8 receive_byte(u8 *); static void transmit_byte(u8); static void transmit_buffer(u8 *, u8); private: static u8 usart_RxHead; static u8 usart_RxTail; static u8 usart_TxHead; static u8 usart_TxTail; static i8 usart_RxBuf[usart_Rx_buffer_size]; static i8 usart_TxBuf[usart_Tx_buffer_size]; #pragma type_attribute=__interrupt #pragma vector=USART_RX_vect static void usart_Rx_interrupt(); #pragma type_attribute=__interrupt #pragma vector=USART_UDRE_vect static void usart_Tx_interrupt(); }; #endif /************************************************************************* ** ** File: usart.cpp ** Summary: USART procedures ** Version: 1.0 ** Date: 06.08.2009 ** ************************************************************************** ** ** Functions: ** ** ** Compiler: IAR AVR 3.20c ** History: ** **************************************************************************/ #include "usart.h" #include "types.h" /*************************************************************************/ u8 CUsart::usart_RxHead; u8 CUsart::usart_RxTail; u8 CUsart::usart_TxHead; u8 CUsart::usart_TxTail; i8 CUsart::usart_RxBuf[usart_Rx_buffer_size]; i8 CUsart::usart_TxBuf[usart_Tx_buffer_size]; /*************************************************************************/ void CUsart::Init() { UBRR0=UBRR0_GFG; // Set baudrate UCSR0C=UCSR0C_CFG; // Set USART mode UCSR0A=UCSR0A_CFG; UCSR0B=UCSR0B_CFG; // Enable USART usart_RxHead=0; usart_RxTail=0; usart_TxHead=0; usart_TxTail=0; } /*************************************************************************/ u8 CUsart::receive_byte(u8 *buf) { u8 cnt=0; while(usart_RxHead!=usart_RxTail) //wait for incomming data { usart_RxTail=(usart_RxTail+1)&usart_Rx_buffer_mask;//store new index *buf=usart_RxBuf[usart_RxTail]; cnt++; } return cnt; //return data } /*************************************************************************/ void CUsart::transmit_byte(u8 data) { u8 tmphead; tmphead=(usart_TxHead+1)&usart_Tx_buffer_mask;//calculate buffer index while(tmphead==usart_TxTail) ; //wait for free space in buffer usart_TxBuf[tmphead]=data; //store data in buffer usart_TxHead=tmphead; //store new index UCSR0B|=(1<<UDRIE0); //enable UDRE interrupt } /*************************************************************************/ void CUsart::transmit_buffer(u8 *buf, u8 size) { for(u8 i=0;i<size;i++) { transmit_byte(*buf++); } } /*************************************************************************/ #pragma type_attribute=__interrupt #pragma vector=USART_RX_vect void CUsart::usart_Rx_interrupt() { u8 status; u8 data; u8 sreg = SREG; status=UCSR0A; data=UDR0; usart_RxHead=(usart_RxHead+1)&usart_Rx_buffer_mask;//store new index if(status & ( (1<<FE0)|(1<<DOR0)|(1<<UPE0) ) ) { usart_RxBuf[usart_RxHead]=0xff;//ошибка return; } if(usart_RxHead==usart_RxTail)//если переполнение буфера { usart_RxBuf[usart_RxHead]=0xff;//ошибка usart_RxBuf[++usart_RxHead]=0xff;//ошибка return; } usart_RxBuf[usart_RxHead]=data; SREG = sreg; } /*************************************************************************/ #pragma type_attribute=__interrupt #pragma vector=USART_UDRE_vect void CUsart::usart_Tx_interrupt() { u8 sreg = SREG; if(usart_TxHead!=usart_TxTail) //check if all date is transmitted { usart_TxTail=(usart_TxTail+1)&usart_Tx_buffer_mask;//store new index UDR0=usart_TxBuf[usart_TxTail]; //start transmition } else { UCSR0B&=~(1<<UDRIE0); //disable UDRE interrupt } // R_LED_PIN = 1<<R_LED; SREG = sreg; } /*************************************************************************/