没有合适的资源?快使用搜索试试~ 我知道了~
UART收发的程序[参照].pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 134 浏览量
2021-10-12
01:03:01
上传
评论
收藏 210KB PDF 举报
温馨提示
试读
21页
UART收发的程序[参照].pdf
资源推荐
资源详情
资源评论
一般教科书上提供的 UART 收发的程序往往是一段采用轮循
(Polling )方式完成收发的简单代码。但对于高速的 AVR 来讲,采
用这种方式大大降低了 MUC 的效率。在使用 AVR 时,应根据芯片
本身的特点(片内大容量数据存储器 RAM ,更适合采用高级语言编
写系统程序),编写高效可靠的 UART 收发接口(低层)程序。下
面是一个典型的 USART 的接口程序。 (下面是 CodeVisionAVR 修改
成 WINAVR 后的程序 ,原来的程序请看底下给出的链界 ,在
http://www.ouravr.com/ 的论坛里 )
//usart.h
// 常量定义
#define BAUDRATE 9600 // 波特率
//#define F_CPU 4000000 // 晶振频率 4.0MHz
#define RXB8 1
#define TXB8 0
#define PE 2 //M16
//#define UPE 2 //M128
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
// 宏定义
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<PE) //M16
//#define PARITY_ERROR (1<<UPE) //M128
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
// 全局变量 , 会在中断服务程序中被修改,须加 volatile 限定,不要
就会出错啦
#define RX_BUFFER_SIZE 16 // 接收缓冲区大小, 可根据
需要修改
volatile char rx_buffer[RX_BUFFER_SIZE]; // 接收缓冲区,
为 char 型变量组成的数组,该数组构成环形队列,个数为 RX_BUFFER
_SIZE
volatile unsigned char rx_wr_index,rx_rd_index,rx_cou
nter;
// This flag is set on USART Receiver buffer overflow
volatile char rx_buffer_overflow; // 接收缓冲区溢出标志
// USART Transmitter buffer
#define TX_BUFFER_SIZE 16
volatile char tx_buffer[TX_BUFFER_SIZE];
volatile unsigned char tx_wr_index,tx_rd_index,tx_cou
nter;
// 函数声明
char get_c( void );
void put_c( char c);
void put_s( char *ptr);
void init_USART( void );
//usart.c
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "usart.h"
/* 接收中断 */
ISR(USART_RXC_vect)
{
char status,data;
status=UCSRA; // 读取接收状态标志位,必须先读,当读了
UDR后, UCSRA便自动清零了
data=UDR; // 读取 USART数据寄存器,这句与上句位置
不能颠倒的
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA
_OVERRUN))== 0) // 判断本接收到的数据是否有数据帧、 校验或数
据溢出错误(此处指 USART 的硬件接收溢出)
{
rx_buffer[rx_wr_index]=data; // 将数据填充到
接收缓冲队列中
if (++rx_wr_index == RX_BUFFER_SIZE) // 写
指针指向下一个单元, 并判断是否到了队列的尾部, (不表示接受缓冲区
是否满!)
rx_wr_index= 0; // 到了尾部,则指向头部(构成环
状)
if (++rx_counter == RX_BUFFER_SIZE) // 队
列中收到字符加 1,并判断是否队列已满
{
rx_counter= 0; // 队列满了,队列中收到字符个数
为 0,表示队列中所有以前的数据作废,因为最后的数据已经把最前边的
数据覆盖了
rx_buffer_overflow= 1; // 置缓冲区溢出
标志。在主程序中必要的地方需要判断该标志, 以证明读到数据的完整性
};
};
}
/* 接收单个字符 */
char get_c( void )
{
char data;
while (rx_counter== 0); // 接收数据队列中没
有数据可以读取,等待 ...... (注 2)
data=rx_buffer[rx_rd_index]; // 读取缓冲队列中的
数据
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index= 0;
// 读取指针指向下一个未读的数据,如果指到了队列尾部,则指回
到队列头步
cli(); // 关中断!非常重要
--rx_counter; // 队列中未读数据个数减 1。因为该变量在接收
中断中要改变的, 为了防止冲突, 所以改动前临时关闭中断。 程序相当可
靠了。
sei(); // 开中断
return data;
}
// 发送中断
ISR(USART_TXC_vect)
{
if (tx_counter)
{
--tx_counter;
剩余20页未读,继续阅读
资源评论
czq131452007
- 粉丝: 2
- 资源: 12万+
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功