📄 uart.c
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/pgmspace.h> // used for the string printing feature
#include <uart.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
/* USART Buffer Defines */
#define USART_RX_BUFFER_SIZE 16 /* 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 16 /* 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
/* Static Variables */
static uint8_t USART_RxBuf[USART_RX_BUFFER_SIZE];
static volatile uint8_t USART_RxHead;
static volatile uint8_t USART_RxTail;
static uint8_t USART_TxBuf[USART_TX_BUFFER_SIZE];
static volatile uint8_t USART_TxHead;
static volatile uint8_t USART_TxTail;
void USART_Init(void){
// Enable the USART Recieve Complete interrupt (USART_RXC) receive int
// Turn on the transmission and reception circuitry
UCSRB = (1 << RXEN) | (1 << TXEN)| (1 << RXCIE);
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
//Flush buffers
USART_RxTail = 0;
USART_RxHead = 0;
USART_TxTail = 0;
USART_TxHead = 0;
}
//RX Interrupt handler
ISR(USART_RXC_vect){
uint8_t data;
uint8_t tmphead;
data = UDR; // read the received data
tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK; // calculate buffer index
USART_RxHead = tmphead; // store new index
if(tmphead == USART_RxTail){
return;// ERROR! Receive buffer overflow, you can use flux cortorl
}
USART_RxBuf[tmphead] = data; // store received data in buffer
}
//TX Interrupt handler
ISR(USART_TXC_vect){
uint8_t tmptail;
// check if all data is transmitted
if(USART_TxHead != USART_TxTail ){
tmptail = (USART_TxTail + 1) & USART_TX_BUFFER_MASK;// calculate buffer index
USART_TxTail = tmptail; // store new index
UDR = USART_TxBuf[tmptail]; // start transmition
}
else{
UCSRB &= ~(1<<UDRIE); // disable UDRE interrupt
}
}
//RX function
uint8_t USART_Receive(void){
uint8_t tmptail;
while(USART_RxHead == USART_RxTail); // wait for incomming data
tmptail = (USART_RxTail + 1) & USART_RX_BUFFER_MASK;// calculate buffer index
USART_RxTail = tmptail; // store new index
return USART_RxBuf[tmptail]; // return data
}
//TX function
void USART_Transmit(uint8_t data){
uint8_t tmphead; // Calculate buffer index
tmphead = (USART_TxHead + 1) & USART_TX_BUFFER_MASK; // Wait for free space in buffer
while ( tmphead == USART_TxTail );
USART_TxBuf[tmphead] = data; // store data in buffer
USART_TxHead = tmphead; // store new index
UCSRB |= (1<<UDRIE); // enable UDRE interrupt
}
//Test any data in the buffer
uint8_t DataInReceiveBuffer(void){
return (USART_RxHead != USART_RxTail); // return 0 (FALSE) if the receive buffer is empty
}
// write a string to the usart from the program memory
void uart_puts_p(const char *progmem_s )
{
register char c;
while ( (c = pgm_read_byte(progmem_s++)) )
USART_Transmit(c);
}
// write a string to the usart from the program memory and add char 13 and 10
void uart_putsl_p(const char *progmem_s )
{
register char c;
while ( (c = pgm_read_byte(progmem_s++)) )
USART_Transmit(c);
// new line
USART_Transmit(0x0d);
USART_Transmit(0x0a);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -