AVR单片机串口USART与PC通讯实例和中断程序分析Word格式文档下载.docx
- 文档编号:17836266
- 上传时间:2022-12-11
- 格式:DOCX
- 页数:11
- 大小:275.80KB
AVR单片机串口USART与PC通讯实例和中断程序分析Word格式文档下载.docx
《AVR单片机串口USART与PC通讯实例和中断程序分析Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《AVR单片机串口USART与PC通讯实例和中断程序分析Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。
单片机的电压一般是TTL电平,电压0v-5v,PC机串口采用的是RS-232协议,它的的电压范围是-15-+15v,电平不同,无法通讯。
要实现通讯,必须进行电平和逻辑关系的转换,
一般用
MAX232集成芯片进行电平的转换。
ATmega16串口结构:
有一个全双工的串行口,有两条通讯线,TXD:
数据发送线,RXD:
数据接收线,对应的单片机外部引脚为PD1,PD0
相关寄存器:
UDR
串口数据寄存器,
UCSRA
串口控制与状态寄存器A
UCSRB
串口控制与状态寄存器B
UCSRC
串口控制与状态寄存器C
UBRRH,UBRRL波特率寄存器
发生器对波特率发生器的输出时钟进行2、8或16的分频,具体情况取决于工作模式,如下图:
如:
系统时钟频率f=8MHZ,异步正常模式(16分频),波特率9600
则:
UBRR=8000000/16*9600-1=52-1=51;
波特率寄存器赋值:
UBRRH=0;
UBRRL=51;
/*10进制写法*/,
或者UBRRH=0;
UBRRL=0x33;
/*16进制写法*/
操作步骤:
一、设置异步模式:
UCSRC|=(1<
<
URSEL)|(1<
URMEL);
//UCSRC和UBRRH寄存器共用一个地址,写UCSRC时,URSEL应置1
二、设置数据帧格式:
8位数据位,一位停止位,UCSRC|=(1<
UCSZ1)|(1<
UCSZ0);
三、设置波特率寄存器:
四、使能发送接收:
UCSRB|=(1<
TXEN)|(1<
RXEN);
五、中断总使能:
SREG=0X80;
//函数功能:
通过PC串口向单片发送数据,单片机接收数据后,送到PA口显示,再送回到PC机
#include<
iom16v.h>
macros.h>
#definefosc8000000
//晶振8MHZ
#definebaud9600
//波特率定义
/*端口初始化函数*/
void
init(void)
{
PORTA=0xFF;
//PA口输出高电平
DDRA
=0xFF;
//PA口设置为输出
PORTD=0X00;
//USART的发送接收端口分别为PD0和PD1
DDRD|=(1<
PD1);
//PD0为接收端口置为输入;
PD1为发送端口置为输出
}
/*串口初始化函数*/
voiduart_init(void)
UCSRB=0x00;
UCSRA=0x00;
UCSRC|=(1<
URSEL)|(1<
UCSZ1)|(1<
UCSZ0);
//异步,数据格式8,N,1
//UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,写UCSRC时,URSEL应设置为1。
UBRRL=51;
//设置波特率寄存器10进制的写法
UCSRB|=(1<
TXEN)|(1<
RXEN);
//发送接收使能
/*发送数据函数*/
voidsend(unsignedchari)
while(!
(UCSRA&
(1<
UDRE)));
//只有数据寄存器为空时才能发送数据
UDR=i;
/*以下是接收数据函数*/
unsignedchar
receive(void)
RXC)));
//等待接收完成
returnUDR;
/*主函数*/
voidmain(void)
unsignedchartemp;
init();
uart_init();
while
(1)
temp=receive();
//接收数据
PORTA=~temp;
//将接收的数据取反后送PA口显示
send(temp);
//向PC机发送数据
1.范例描述
按下按键0,LED0亮。
直到松手,其他按键才能起作用
按下按键1,LED1亮。
其他按键随时都能起作用
按下按键2,LED0/1都熄灭。
2.电路图设计:
.
4.代码设计与说明:
本程序简单的示范了如何使用ATMEGA16的外部中断
中断的设置
按键的简单延时防抖动
中断的嵌套
变量在中断中的应用---如果变量会在中断服务程序中被修改,须加volatile限定
本范例可直接使出厂状态的新M16芯片,无需对芯片的熔丝位进行配置。
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAGICE硬件仿真器
关于外部中断作唤醒源的条件:
(将会在后面的电源管理和睡眠模式范例中应用)
而INT0和INT1的边沿触发中断只能在空闲模式起作用,即CLKI/O不停止
INT0和INT1的低电平中断,INT2在各种睡眠模式下都可以,因为这几种中断工作
于异步模式,不需要时钟驱动
官方的M16中文手册对外部中断的描叙存在多处错误,请参考英文原版。
*/
#include<
avr/io.h>
avr/delay.h>
avr/signal.h>
avr/interrupt.h>
/*宏INTERRUPT的用法与SIGNAL类似,区别在于
SIGNAL执行时全局中断触发位被清除、其他中断被禁止
INTERRUPT执行时全局中断触发位被置位、其他中断可嵌套执行
中断服务程序的编写具有一定的格式,在不同编译环境下各不相同,在WINAVR(GCC)环境下有两种方式,分别是:
第一种中断服务程序的编写格式:
SIGNAL(中断向量名)
…//中断服务程序内容
}
ISR(中断向量名)
在这两种方式中,需要分别添加头文件:
和#include<
。
另外avr-libc提供两个API函数用于置位和清零全局中断触发位,它们是经常用到的。
分别是:
voidsei(void)和voidcli(void)由interrupt.h定义*/
//注:
内部函数_delay_ms()最高延时262.144mS@1MHz
/*该函数可以实现较精确的定时,但用JTAG仿真时较麻烦---会进入机器码窗口(Disassembeler)
.注意跳开该语段。
一旦JTAG仿真进入该内部函数语句,会变得像"
死机"
一样(其实在运行中),可以先[break],然后
在后面的C语句设[breakpoint],[RUN]跳过*/
//for()/while()语句计算延时时间较麻烦。
//为了使_delay_ms()函数的延时正确,须在makefile中设定F_CPU为实际的系统时钟频
//本范例为1MHz内部RC振荡器即F_CPU=1000000
/*
C:
\WinAVR\avr\include\avr\目录包括所有芯片的定义和其他头文件
其中iom16.h定义ATMEGA16芯片的特性(中断向量,寄存器,位定义...)
包括下面中断服务程序的常量SIG_INTERRUPTx,PORTx,GICR.....
//管脚定义
#defineEXT_INT02//PD2按键0
#defineEXT_INT13//PD3按键1
#defineEXT_INT22//PB2按键2
#defineLED00//PB0
#defineLED11//PB1
#defineLED23//PB3
//宏定义
#defineLED0_ON()PORTB|=(1<
LED0)//输出高电平,灯亮
#defineLED0_OFF()PORTB&
=~(1<
LED0)//输出低电平,灯灭
#defineLED1_ON()PORTB|=(1<
LED1)
#defineLED1_OFF()PORTB&
#defineLED2_ON()PORTB|=(1<
LED2)
#defineLED2_OFF()PORTB&
//51系列的高电平输出能力很弱,低电平也仅能点亮LED.所以常见输出低电平才灯亮的接法。
//AVR芯片的高低驱动能力都很强,甚至能推动8字数码管的公共极,怎么接都没问题。
//全局变量
#definehas_volatile1//这里是条件编译
//可以修改has_volatile=1或0来看程序运行的效果
#ifhas_volatile
volatileunsignedcharFLAG;
//全局变量,会在中断服务程序中被修改,须加volatile限定
#else
unsignedcharFLAG;
//全局变量.
#endif
//仿真时在watch窗口,监控这些变量。
SIGNAL(SIG_INTERRUPT0)//INT0中断服务程序
{
//硬件自动清除INTF0标志位
_delay_ms(10);
//延时
if((PIND&
EXT_INT0))==0)//重复检测,防抖动
LED0_ON();
//点亮LED0
loop_until_bit_is_set(PIND,EXT_INT0);
//等待按键释放(变为高电平)
//延时按键释放时也会抖动。
//即使同时发生其它的中断事件,如果在这里把相应的中断标志位清除,那么该中断将
不能触发进入中断服务
/*注意
读端口用PINx
写端口用PORTx*/
INTERRUPT(SIG_INTERRUPT1)//INT1中断服务程序
//硬件自动清除INTF1标志位
//这里全局中断被打开,将允许其他中断嵌套执行
EXT_INT1))==0)
LED1_ON();
//点亮LED1
loop_until_bit_is_set(PIND,EXT_INT1);
SIGNAL(SIG_INTERRUPT2)//INT2中断服务程序
//硬件自动清除INTF2标志位
if((PINB&
EXT_INT2))==0)
LED0_OFF();
//熄灭LED0
LED1_OFF();
//熄灭LED1
loop_until_bit_is_set(PINB,EXT_INT2);
FLAG=!
FLAG;
//修改全局变量
_delay_ms(100);
intmain(void)
//上电默认DDRx=0x00,PORTx=0x00输入,无上拉电阻
PORTA=0xFF;
//不用的管脚使能内部上拉电阻。
PORTC=0xFF;
PORTD=0xFF;
DDRB=(1<
LED2)|(1<
LED1)|(1<
LED0);
//输出
PORTB=~((1<
LED0));
//低电平,灯灭
//外部中断INT0,1,2做按键输入,使能内部上拉,就可以不用外接电阻了
MCUCR=(1<
ISC11)|(0<
ISC10)|(1<
ISC01)|(0<
ISC00);
//注意该寄存器有多个功能
ISCx1:
0=00INTx引脚为低电平时产生中断请求
0=01INTx引脚上任意的逻辑电平变化都将引发中断
0=10INTx引脚的下降沿产生中断请求
0=11INTx引脚的上升沿产生中断请求
MCUCSR&
ISC2);
/*ISC2=0INT2引脚的下降沿产生异步中断请求
ISC2=1INT2引脚的上升沿产生异步中断请求
GIFR=(1<
INTF1)|(1<
INTF0)|(1<
INTF2);
//写1清除标志位,在使能中断前最好先把对应的标志位清除,以免误触发
GICR=(1<
INT1)|(1<
INT0)|(1<
INT2);
//使能三个外部中断
FLAG=0;
sei();
//使能全局中断
while
(1)
while(FLAG==0);
LED2_ON();
//如果FLAG不加volatile限定(即has_volatile=0),
//程序将永远都运行不到这里。
while(FLAG!
=0);
LED2_OFF();
}
程序运行效果
LED2是根据按键2的顺序来亮灭,松手后变换,前提是FLAG加了volatile限定
*/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AVR 单片机 串口 USART PC 通讯 实例 中断 程序 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)