📄 usart_mega16.c
字号:
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\pgmspace.h>
#include "USART_mega16.h"
#define BAUDRATE 38400 //波特率采用115200bps
volatile unsigned char USART_FLAG;
//#define RXB8 1
//#define TXB8 0
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<PE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
//*******************************************************************
// USART Receiver buffer
char rx_buffer[RX_BUFFER_SIZE];
/*
rx_wr_index 接收缓存写入计数指针,循环+1
rx_rd_index 接收缓存读出计数指针,循环+1
rx_counter 接收数据计数值,超过最大值清零并置溢出标志
*/
#if RX_BUFFER_SIZE<256
volatile unsigned char rx_wr_index=0,rx_rd_index=0,rx_counter=0;
#else
volatile unsigned int rx_wr_index=0,rx_rd_index=0,rx_counter=0;
#endif
// This flag is set on USART Receiver buffer overflow
unsigned char rx_buffer_overflow;
// USART Transmitter buffer
char tx_buffer[TX_BUFFER_SIZE];
/*
tx_wr_index 发送缓存写入计数指针,循环+1
tx_rd_index 发送缓存读出计数指针,循环+1
tx_counter 发送数据计数值,超过最大值等待
*/
#if TX_BUFFER_SIZE<256
volatile unsigned char tx_wr_index=0,tx_rd_index=0,tx_counter=0;
#else
volatile unsigned int tx_wr_index=0,tx_rd_index=0,tx_counter=0;
#endif
//******************************************************************
// USART Receiver interrupt service routine
void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
USART_FLAG = 1;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0){
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE){
rx_counter=0;
rx_buffer_overflow=1;
}
}
}
SIGNAL(USART_RXC_vect)
{
usart_rx_isr();
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
//#pragma used+
unsigned char get_c(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
cli();
if (0 == --rx_counter)
USART_FLAG = 0;
sei();
return data;
}
//#pragma used-
#endif
// USART Transmitter interrupt service routine
void usart_tx_isr(void)
{
if (tx_counter){
--tx_counter;
UDR = tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
}
}
SIGNAL(USART_TXC_vect)
{
usart_tx_isr();
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
//#pragma used+
void put_c(unsigned char c)
{
while (TX_BUFFER_SIZE == tx_counter);
cli();
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0)){
tx_buffer[tx_wr_index]=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
}
else
UDR=c;
sei();
}
//#pragma used-
#endif
void put_hex(unsigned char num)
{
unsigned char tmp;
tmp = num>>4 & 0x0F;
if(tmp<=9)
tmp += 0x30;
else
tmp += 0x37;
put_c(tmp);
tmp = num & 0x0F;
if(tmp<=9)
tmp += 0x30;
else
tmp += 0x37;
put_c(tmp);
put_c('H');
put_c(' ');
}
void put_s(unsigned char *s)
{
while (*s) {
put_c(*s);
s++;
}
}
void put_s_P(unsigned char *P)
{
while (pgm_read_byte(P)) {
put_c(pgm_read_byte(P));
P++;
}
}
void put_sp(unsigned char i)
{
while (i--) {
put_c(' ');
}
}
void put_ok(void)
{
put_c(' ');
put_c('O');
put_c('K');
}
void put_cr(void)
{
put_c(0x0D);
put_c(0x0A);
}
// USART initialization
void init_USART(void)
{
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //异步,8位数据,无奇偶校验,一个停止位,无倍速
UBRRL = (F_CPU/BAUDRATE/16-1)%256; //设定波特率
UBRRH = (F_CPU/BAUDRATE/16-1)/256;
}
/*
#define RXB8 1
#define TXB8 0
#define UPE 2
#define DOR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
void put_c(unsigned char c) //发送采用查询方式
{
while( !(UCSRA & (1<<UDRE)) );
UDR=c;
}
// USART0 Receiver buffer
#define RX_BUFFER_SIZE0 8
char rx_buffer0[RX_BUFFER_SIZE0];
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
// This flag is set on USART0 Receiver buffer overflow
unsigned char rx_buffer_overflow0;
// USART0 Receiver interrupt service routine
#pragma savereg-
SIGNAL(USART_RXC_vect)// void uart0_rx_isr(void)
{
char status,data;
asm volatile(
"push r26\n\t"
"push r27\n\t"
"push r30\n\t"
"push r31\n\t"
"in r26,_SREG_\n\t"
"push r26\n\t"
:
:
);
status = UCSRA;
data = UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
if (++rx_counter0 == RX_BUFFER_SIZE0) {
rx_counter0=0;
rx_buffer_overflow0=1;
}
}
asm volatile(
"pop r26\n\t"
"out _sreg_,r26\n\t"
"pop r31\n\t"
"pop r30\n\t"
"pop r27\n\t"
"pop r26\n\t"
:
:
);
}
#pragma savereg+
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif
// USART0 Transmitter buffer
#define TX_BUFFER_SIZE0 8
char tx_buffer0[TX_BUFFER_SIZE0];
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
// USART0 Transmitter interrupt service routine
#pragma savereg-
interrupt (USART_TXC_vect) //void uart0_tx_isr(void)
{
asm volatile(
"push r26\n\t"
"push r27\n\t"
"push r30\n\t"
"push r31\n\t"
"in r26,sreg\n\t"
"push r26\n\t"
:
:
);
if (tx_counter0)
{
--tx_counter0;
UDR=tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
};
asm volatile(
"pop r26\n\t"
"out sreg,r26\n\t"
"pop r31 \n\t"
"pop r30 \n\t"
"pop r27 \n\t"
"pop r26 \n\t"
:
:
);
}
#pragma savereg+
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART0 Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
#asm("cli")
if (tx_counter0 || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer0[tx_wr_index0]=c;
if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
++tx_counter0;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -