⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 AVR serial port communication
💻 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 + -