Ну почему-же. Просто привык как-то так писать... Понятно всё и удобно.
/*************************************************************************
**
** 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;
}
/*************************************************************************/
-
- А каков сакральный смысл писать на си++, если Oman(217 знак., 05.05.2016 09:18)
- Cpp против макроса #define MY_UART(x) UART3##x - VL(05.05.2016 10:58, )
- Брюзжание: за дефиницию MY_ в определении макросов нужно заставлять зубной щеткой драить плац. - Скрипач(05.05.2016 11:01)
- Полностью солидарен! В оригинале вместо MY название блока. - VL(05.05.2016 14:00, )
- За слово "дефиниция" - пожизненный эцих с гвоздями. - SciFi(05.05.2016 11:05)
- "раскрывающая содержание (смысл) имени посредством описания". Что смущает? - Скрипач(05.05.2016 11:09)
- Брюзжание: за дефиницию MY_ в определении макросов нужно заставлять зубной щеткой драить плац. - Скрипач(05.05.2016 11:01)
- Cpp против макроса #define MY_UART(x) UART3##x - VL(05.05.2016 10:58, )
- А каков сакральный смысл писать на си++, если Oman(217 знак., 05.05.2016 09:18)