匿名
未登录
登录
丢石头百科
搜索
查看“AVR USART(UART)发送中断程序 使用缓冲器”的源代码
来自丢石头百科
名字空间
页面
讨论
更多
更多
页面选项
查看
查看源代码
历史
←
AVR USART(UART)发送中断程序 使用缓冲器
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
<table border="0" cellpadding="0" cellspacing="0" width="780"><tr><th class="type_483D8B" scope="col" style="font-size: 12px; line-height: 20px; font-weight: normal; border-top-style: none; color: rgb(72, 61, 139);" valign="top"><div align="left"><table border="0" cellpadding="0" cellspacing="0" width="120"><tr><th bgcolor="#698192" class="white_12px_b" height="20" scope="col" style="font-size: 12px; color: rgb(255, 255, 255); line-height: 20px; font-family: Arial, Helvetica, sans-serif;">系统功能</th></tr></table><br/> 使用USART发送数据,需要一定时间,若是用传统方法,等发送完再处理其它任务(如语句<span class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;"> while(!(UCSRA&0x40));</span>),那么,将大大降低了高速的AVR的执行效率!AVR会等到“花都谢了~”<br/> 那么怎样处理才可以解决低速串口与高速AVR之间的矛盾呢?可以采用开辟发送缓冲区的做法:<br/> 当AVR需要发送数据时,如果USART口不空闲或者发送缓冲区还有待发送的数据,就将数据放入发送缓冲器中(如果缓冲器未满),AVR不必等待,可以转去执行其它任务。而后,等USART的硬件发送完一个数据后产生中断,由中断服务程序负责将发送缓冲器中数据依次送出。 <br/> 发送缓冲器数据结构的设计:循环队列,由读、写2个指针及一个队列计数器控制,用于判断当前写入数据、读出数据在队列中的位置,并判断队列是否为空,是否已满。<br/> 程序设计时需注意,为了防止处理冲突,在对数据缓冲器的读、写过程中,要将中断关闭,避免错误产生,从而提高程序的可靠性。<br/><br/><br/></div></th></tr><tr><th class="type_483D8B" scope="col" style="font-size: 12px; line-height: 20px; font-weight: normal; border-top-style: none; color: rgb(72, 61, 139);" valign="top"><div align="left"><table border="0" cellpadding="0" cellspacing="0" width="120"><tr><th bgcolor="#698192" class="white_12px_b" height="20" scope="col" style="font-size: 12px; color: rgb(255, 255, 255); line-height: 20px; font-family: Arial, Helvetica, sans-serif;">硬件设计</th></tr></table><p align="center">[[File:AVR_USART(UART)发送中断程序_使用缓冲器-0.jpg|400px]]<br/>AVR主控电路原理图(点击图片放大,不需要放大镜![[File:AVR_USART(UART)发送中断程序_使用缓冲器-1.gif|400px]])<br/>[[File:AVR_USART(UART)发送中断程序_使用缓冲器-2.jpg|400px]] <br/>LED控制电路原理图(点击图片放大,不需要放大镜![[File:AVR_USART(UART)发送中断程序_使用缓冲器-1.gif|400px]])<br/><br/><br/><br/></p></div></th></tr><tr><th class="type_483D8B" scope="col" style="font-size: 12px; line-height: 20px; font-weight: normal; border-top-style: none; color: rgb(72, 61, 139);" valign="top"><div align="left"><table border="0" cellpadding="0" cellspacing="0" width="120"><tr><th bgcolor="#698192" class="white_12px_b" height="20" scope="col" style="font-size: 12px; color: rgb(255, 255, 255); line-height: 20px; font-family: Arial, Helvetica, sans-serif;">软件设计</th></tr></table><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">下面部分从TXT拷出,拷到网页,代码部分缺省了很多空格,比较凌乱,请谅解!</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">//目标系统: 基于AVR单片机<br/>//应用软件: ICC AVR</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">/*01010101010101010101010101010101010101010101010101010101010101010101<br/>----------------------------------------------------------------------<br/>实验内容:<br/>使用USART的发送中断功能,并使用缓冲解决高速AVR与低速串口之间的矛盾<br/>----------------------------------------------------------------------<br/>硬件连接: <br/>将PB口的LED指示灯使能开关切换到"ON"状态。<br/>----------------------------------------------------------------------<br/>注意事项:<br/>(1)若有加载库程序,请将光盘根目录下的“库程序”下的“ICC_H”文件夹拷到D盘<br/>(2)请详细阅读:光盘根目录下的“产品资料\开发板实验板\SMK系列\SMK1632\说明资料”<br/>----------------------------------------------------------------------<br/>10101010101010101010101010101010101010101010101010101010101010101010*/</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">#include <iom16v.h><br/>#include "D:\ICC_H\CmmICC.H"</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">#define DISP_PORT PORTB<br/>#define DISP_DDR DDRB</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">#define TX_BUFFER_SIZE 255<br/>#define UDR_EMPTY (1<<UDRE)</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">uint8 tx_buffer[TX_BUFFER_SIZE],tx_wr_index=0,tx_rd_index=0,tx_counter=0;</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">/*--------------------------------------------------------------------<br/>程序名称:UART初始化程序<br/>程序功能:初始化UART为:8位,9.6K,接收中断<br/>注意事项:基于7.3728M晶振<br/>提示说明:晶振不要买到假的,要不然,调不出来还以为电脑有鬼!<br/>输 入:<br/>返 回:<br/>--------------------------------------------------------------------*/<br/>void uart0_init(void)<br/>{<br/> UCSRB = 0x00; //disable while setting baud rate<br/> UCSRA = 0x00; //U2X = 0,不加倍数率<br/> UCSRC = 0x86; //8位<br/> UBRRL = 47; //set baud rate lo,波特率为9.6K<br/> UBRRH = 0x00; //set baud rate hi<br/> UCSRB = 0x58; //发送中断允许,接收缓冲自动清空,接收允许<br/>}<br/>/*--------------------------------------------------------------------<br/>程序名称:UART发送中断服务程序<br/>程序功能:<br/>注意事项:<br/>提示说明:<br/>输 入:<br/>返 回:<br/>--------------------------------------------------------------------*/<br/>#pragma interrupt_handler uart0_tx_isr:14<br/>void uart0_tx_isr(void)<br/>{<br/> if (tx_counter) //如果缓冲区有数据则进入发送程序<br/> {<br/> tx_counter--;<br/> UDR=tx_buffer[tx_rd_index]; <br/> if (++tx_rd_index == TX_BUFFER_SIZE) //如果缓冲区读指针满<br/> tx_rd_index=0; //读指针置0<br/> }<br/>}<br/>/*--------------------------------------------------------------------<br/>程序名称:<br/>程序功能:UART发送程序<br/>注意事项:<br/>提示说明:<br/>输 入:<br/>返 回:<br/>--------------------------------------------------------------------*/<br/>void uart0_putchar(uint8 c) <br/>{ <br/> while (tx_counter == TX_BUFFER_SIZE); //如果缓冲区满则等待<br/> CLI(); <br/> if (tx_counter || ((UCSRA & UDR_EMPTY)==0)) //如果缓冲区有数据或者UDR不空闲<br/> {<br/> tx_buffer[tx_wr_index]=c; //将数据写入缓冲<br/> if (++tx_wr_index == TX_BUFFER_SIZE) //如果已经写满<br/> tx_wr_index=0; //写指针置0<br/> tx_counter++;<br/> } <br/> else //如果缓冲区没有数据且UDR空闲<br/> UDR=c; //没什么事就发了吧<br/> SEI();<br/>} <br/>/*--------------------------------------------------------------------<br/>程序名称:<br/>程序功能:<br/>注意事项:<br/>提示说明:<br/>输 入:<br/>返 回:<br/>--------------------------------------------------------------------*/<br/>void mcu_init(void)<br/>{<br/> CLI();<br/> uart0_init();<br/> MCUCR = 0x00;<br/> GICR = 0x00;<br/> TIMSK = 0x00; //timer interrupt sources<br/> SEI(); //re-enable interrupts<br/>}<br/>/*--------------------------------------------------------------------<br/>程序名称:<br/>程序功能:<br/>注意事项:没什么好说的。。。<br/>提示说明:<br/>输 入:<br/>返 回:<br/>--------------------------------------------------------------------*/<br/>void main()<br/>{<br/> uint8 sendChar=0;</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;"> mcu_init();<br/> DISP_DDR=0xFF;</p><p class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;"> while(1)<br/> {<br/> uart0_putchar(sendChar); //发送数据,数据为变量sendChar<br/> delay50us(20);<br/> DISP_PORT=tx_counter; //显示发送区数据量<br/> }<br/>}</p></div></th></tr><tr><th class="type_483D8B" scope="col" style="font-size: 12px; line-height: 20px; font-weight: normal; border-top-style: none; color: rgb(72, 61, 139);" valign="top"><div align="left"><br style="font-family: Arial, 新宋体, 微软雅黑;"/><table border="0" cellpadding="0" cellspacing="0" style="color: rgb(72, 61, 139); font-family: Arial, 新宋体, 微软雅黑; font-size: 12px; line-height: 20px;" width="120"><tr><th bgcolor="#698192" class="white_12px_b" height="20" scope="col" style="color: rgb(255, 255, 255); font-family: Arial, Helvetica, sans-serif;">系统调试</th></tr></table><p style="font-family: Arial, 新宋体, 微软雅黑;">(1)缓冲区数据量tx_counter的值取决于AVR的发送频率及UART的波特率。假定UART的波特率一定,若是AVR的发送频率过高,低速的UART的发送速度将跟不上,导致缓冲区数据量tx_counter不断增加。用LED指示tx_counter,将可以观察到向上加的现象。<br/><br/>(2)改变UART初始化语句:<span class="type_666666_12px" style="color: rgb(102, 102, 102); border-top-style: none; font-family: Arial, Helvetica, sans-serif;">UBRRL = 47; </span>将“47”改为“40”、“60”、“80”,从而改变UART的波特率。可以看到波特率越高,数据量tx_counter向上加的速度越低;当波特率高到一定程度,发送时间将小于延时时间,UART空闲,程序不将待发送的数据放入缓冲,即缓冲区没有数据,数据量tx_counter一直为“0”;波特率越低,数据量tx_ounter向上加的速度越高。用LED指示tx_counter的数据量,观察现象。</p><div><br/></div></div></th></tr></table>
返回至
AVR USART(UART)发送中断程序 使用缓冲器
。
导航
导航
首页
最近更改
随机页面
MediaWiki帮助
首页
首页
树莓派
主机
配件包
外壳
键鼠
电源
扩展板
显示屏
墨水屏
摄像模块
通信模块
继电器
电机驱动板
游戏机
产品分类
树莓派
Arduino
micro:bit
STM32
Espressif
WiFi模块
蓝牙模块
无线模块
LoRa模块
4G模块
GSM
GPRS
以太网
导航模块
北斗卫星
GPS
LCD
墨水屏
OLED
摄像头
USB模块
串口模块
RS232
RS485
CAN
传感器
温度模块
湿度模块
气压模块
继电器
电机模块
指纹模块
电平转换
音频模块
编程器
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志