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

📄 usart_mega16.c

📁 avr单片机ATMEGA16
💻 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 + -