📄 uart.c
字号:
#define ENABLE_BIT_DEFINITIONS
#include <iom88.h>
#include "UART.h"
#define FRAMING_ERROR (1 << FE0)
#define PARITY_ERROR (1 << UPE0)
#define DATA_OVERRUN (1 << DOR0)
#define DATA_REGISTER_EMPTY (1<<UDRE0)
#define RX_COMPLETE (1<<RXC0)
// Declare your global variables here
char rx_buffer_overflow; // 定义缓冲区溢出标志
char rx_buffer[RX_BUFFER_SIZE]; //定义接收缓冲
unsigned char rx_wr_index,rx_rd_index,rx_counter;//定义接收缓冲控制变量
char tx_buffer[TX_BUFFER_SIZE]; //定义发送缓冲
unsigned char tx_wr_index,tx_rd_index,tx_counter;//定义发送缓冲控制变量
void UartInit(void)
{
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
#if SPEED == _high_
UCSR0A=(0<<RXC0)|(0<<TXC0)|(0<<UDRE0)|(0<<FE0)|
(0<<DOR0)|(0<<UPE0)|(1<<U2X0)|(0<<MPCM0); // 高速
#else
UCSR0A=(0<<RXC0)|(0<<TXC0)|(0<<UDRE0)|(0<<FE0)|
(0<<DOR0)|(0<<UPE0)|(0<<U2X0)|(0<<MPCM0); // 普通
#endif
UCSR0B=(1<<RXCIE0)|(1<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|
(1<<TXEN0)|(0<<UCSZ02)|(0<<RXB80)|(0<<TXB80);
UCSR0C=(0<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)|
(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
UBRR0H=(UBRR_COUNT >> 8);
UBRR0L=(UBRR_COUNT & 0x00FF);
}
/**************************************************************************************
* USART0接收中断服务程序
* 功能描述:该程序将接收到的一个字节的数据放入接收缓冲区中。
* 入口参数:无
* 返回数据:无
*************************************************************************************/
#pragma vector = USART_RX_vect //设置中断入口地址
__interrupt void Usart0_Rx_Isr(void)
{
char status,data;
status=UCSR0A; //先读UCSR0A,再读UDR0!
data=UDR0;
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; //溢出标志置1
}
}
}
/************************************************************************************
* 从接收缓冲区中取出数据
* 功能描述:该程序被应用程序调用,从接收循环队列中取出一个字节的数据。
* 入口参数:无
* 返回数据:缓冲区中的一个字节。
*************************************************************************************/
char UartGetChar(void)
{
char data;
data = rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index = 0;//调整接收缓冲读取指针
asm("cli"); //关闭中断,
--rx_counter; //调整接收计数值
asm("sei");
return data;
}
/********************************************************************
* USART0发送中断服务程序
* 功能描述:该程序将发送缓冲区中的一个字节的数据通过串口发送出去。
* 入口参数:无
* 返回数据:无
**********************************************************************/
#pragma vector = USART_TX_vect
__interrupt void usart0_tx_isr(void)
{
if (tx_counter) //如果发送缓冲区仍有待发送的数据,则继续发送;否则,跳出
{
--tx_counter;
UDR0 = tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE)
tx_rd_index=0; //调整发送缓冲的读指针
}
}
/**************************************************************************
* 放入数据到发送缓冲区中
* 功能描述:该程序被应用程序调用,放入一个字节的数据到发送缓冲区。
* 入口参数:'c'
* 返回数据:无
****************************************************************************/
void UartPutChar(char c)
{
while (tx_counter == TX_BUFFER_SIZE); // 若发送缓冲区已满,则等待。
asm("cli");
if (tx_counter || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
{//若发送缓冲区非空,或者串口数据寄存器中数据未发送完成,
tx_buffer[tx_wr_index]=c; //则数据先存入发送缓冲区
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index = 0;//
++tx_counter;
}
else //否则,直接发送
{
UDR0=c;
}
asm("sei");
}
void UartPutString(char* s)
{
while(*s != '\0')
{
UartPutChar(*s);
s++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -