AVR的IO口详解及正确的熔丝配置Word文档下载推荐.docx
《AVR的IO口详解及正确的熔丝配置Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《AVR的IO口详解及正确的熔丝配置Word文档下载推荐.docx(18页珍藏版)》请在冰点文库上搜索。
上拉电阻使能({DDxn,PORTxn}=0b01)或输出低电平({DDxn,PORTxn}=0b10)这两种模式必然会有一个发生。
通常,上拉电阻使能是完全可以接受的,因为高阻环境不在意是强高电平输出还是上拉输出。
如果使用情况不是这样子,可以通过置位SFIOR寄存器的PUD来禁止所有端口的上拉电阻。
在上拉输入和输出低电平之间切换也有同样的问题。
用户必须选择高阻态({DDxn,PORTxn}=0b00)或输出高电平({DDxn,PORTxn}=0b10)作为中间步骤。
不论如何配置DDxn,都可以通过读取PINxn寄存器来获得引脚电平
PINxn寄存器的各个位与其前面的锁存器组成了一个同步器。
这样就可以避免在内部时钟状态发生改变的短时间范围内由于引脚电平变化而造成的信号不稳定。
其缺点是引入了延迟。
AVRIO具备多种IO模式:
1高阻态,多用于高阻模拟信号输入,例如ADC数模转换器输入,模拟比较器输入
2弱上拉状态(Rup=20K~50K),输入用。
为低电平信号输入作了优化,省去外部上拉电阻,例如按键输入,低电平中断触发信号输入
3推挽强输出状态,驱动能力特强(>
20mA),可直接推动LED,而且高低驱动能力对称.
使用注意事项:
写用PORTx,读取用PINx
实验时,尽量不要把管脚直接接到GND/VCC,当设定不当,IO口将会输出/灌入80mA(Vcc=5V)的大电流,导致器件损坏。
作输入时:
1通常要使能内部上拉电阻,悬空(高阻态)将会很容易受干扰。
(表面看好像是51的抗干扰能力强,是因为51永远有内部电阻上拉,)
2尽量不要让输入悬空或模拟输入电平接近VCC/2,将会消耗太多的电流,特别是低功耗应用场合------CMOS电路的特点
3读取软件赋予的引脚电平时需要在赋值指令out和读取指令in之间有一个时钟周期的间隔,如nop指令。
4功能模块(中断,定时器)的输入可以是低电平触发,也可以是上升沿触发或下降沿触发。
5用于高阻模拟信号输入,切记不要使能内部上拉电阻,影响精确度。
例如ADC数模转换器输入,模拟比较器输入
作输出时:
采用必要的限流措施,例如驱动LED要串入限流电阻
复位时:
复位时内部上拉电阻将被禁用。
如果应用中(例如电机控制)需要严格的电平控制,请使用外接电阻固定电平
休眠时:
作输出的,依然维持状态不变
作输入的,一般无效,但如果使能了第二功能(中断使能),其输入功能有效。
例如外部中断的唤醒功能。
AVR的C语言IO操作:
AVR的C语言基于ANSIC,没有像51那样扩展了位操作(布尔操作),虽然汇编指令里面有SBI/CBI/SBIC/SBIS指令,所以需要采用位逻辑运算来实现,这是必须要掌握的。
IO口和功能寄存器的操作方法一样,但对于部分功能寄存器的读写有特殊要求,请参看手册。
不必考虑代码效率的问题,如果可能,GCCAVR会自动优化为SBI/CBI/SBIC/SBIS指令,跟汇编的效率是一样的。
例如iom16.h里面定义了#definePA77
(这标准头文件定义了MCU的所有官方定义(包括寄存器,位,中断入口等),但管脚的第二功能没有定义)
想PA7为1PORTA|=(1<
<
PA7);
想PA7为0PORTA&
=~(1<
想PA7取反PORTA^=(1<
想检测PA7是否为1if(PINA&
(1<
PA7)){};
想检测PA7是否为0if!
(PINA&
*<
为左移运算符,不懂的就要好好复习C语言基础了。
注意IO操作的顺序:
//上电默认DDRx=0x00,PORTx=0x00输入,无上拉电阻
假设PA口驱动LED的负极,低电平灯亮
初始化方法1:
PORTA=0xFF;
//内部上拉,高电平
DDRA=0xFF;
//输出高电平---------灯一直是灭的
初始化方法2:
//输出低电平--------灯被错误点亮了
//输出高电平--------马上被熄灭了,时间很短(1个指令不到uS时间),灯闪了一下,眼睛无法察觉,但要是这个IO口是控制炸药包的点火信号呢?
工控场合要考虑可靠性的问题
模拟OC结构的IIC总线的技巧:
虽然AVR大多带有硬件IIC接口,但也有需要使用软件模拟IIC的情况,可以通过使用外部上拉电阻+控制DDRx的方法来实现OC结构的IIC总线。
IC的速度跟上拉电阻有关,内部的上拉电阻阻值较大(Rup=20K~50K),只能用于低速的场合
#defineSDA0//PC0
#defineSCL1//PC1
(程序初始化设定SDA和SCL都是PORT=0,DDR=0)
#defineSDA_0()DDRA|=(1<
SDA)//输出低电平
#defineSDA_1()DDRA&
SDA)//输入,外部电阻上拉为高电平
#defineSCL_0()DDRA|=(1<
SCL)//输出低电平
#defineSCL_1()DDRA&
SCL)//输入,外部电阻上拉为高电平
使用上面的SDA_0()/SDA_1()/SCL_0()/SCL_1()宏即可,直观,而且效率跟汇编是一样的
AVR熔丝配置对I/O端口有什么影响
AVR熔丝配置对I/O端口有什么影响?
是不是每次ISP烧录程序都可以更改它的熔丝配置呢?
AVR的熔丝关于端口主要控制引脚的复用功能,比如有些型号的复位脚是可以复用的,时钟输入引脚也可以复用,当作普通的IO口使用,支持JTAG功能的单片机有一个熔丝位JTAG_EN,设置为1的时候就禁用了JTAG,为0的时候原来这些JTAG的IO口就解放出来变成普通的IO口。
说白了就是一些引脚有复用功能,用熔丝来设置是否把它变成普通的IO口。
每次烧录的时候都可以更改熔丝配置,只要你想的话。
另外顺便提示一句,初学者最好尽量少弄熔丝,掌握几个常用的熔丝位就可以了,比如JTAG_EN、时钟设置这些,有些不知道作用的熔丝千万别乱设置,后果很严重,会导致单片机锁死或者永远下载不了程序或者读出程序。
AVR学习笔记之端口操作详解
AVR端口是真正的双向端口,不像51伪双向。
这也是AVR的一项优势,只是操作时大家注意DDRn就可以了。
真正双向端口在模拟时序方面不如伪双向的方便。
DDRnPORTnPINn解释:
n为端口号:
ABCDE
DDRn:
控制端口是输入还是输出,0为输入,1为输出。
个人记忆方法:
一比零大所以往外挤,即1为输出,0为输入。
PORTn:
从引脚输出信号,当DDRn为1时,可以通过PORTn=x等端口操作语句给引脚输出赋值。
PINn:
从引脚读输入信号,无论DDRn为何值,都可以通过x=PINn获得端口n的外部电平。
当引脚配置为输入时,若PORTxn为"
1“,上拉电阻将使能。
内部上拉电阻的使用在键盘扫描的时候还要说到。
端口更详细功能及介绍以及端口第二功能请参考数据手册。
端口引脚配置
DDxnPORTxnPUD(inSFIOR)I/O上拉电阻说明
00X输入No高阻态(Hi-Z)
010输入Yes被外部电路拉低时将输出电流
011输入No高阻态(Hi-Z)
10X输出No输出低电平(漏电流)
11X输出No输出高电平(源电流)
如果有引脚未被使用,建议给这些引脚赋予一个确定电平。
最简单的保证未用引脚具有确定电平的方法是使能内部上拉电阻。
但要注意的是复位时上拉电阻将被禁用。
如果复位时的功耗也有严格要求则建议使用外部上拉或下拉电阻。
不推荐直接将未用引脚与VCC或GND连接,因为这样可能会在引脚偶然作为输出时出现冲击电流。
下面我们来看例子:
voidport_init(void)
{
PORTA=0x03;
DDRA=0x03;
PORTB=0x00;
DDRB=0x01;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
//建议赋值为零
}
这两句使PA口的PA1和PA0处于输出状态,PA7—PA2处于输入状态,因为先定义了PORTA=0x30,PA1和PA0的内部上拉电阻也使能了。
这里的0x03即二进制的00000011,从左到右对应于Pn7--Pn0八个IO口。
通过跑马灯程序来深入理解IO口的操作:
//ICC-AVRapplicationbuilder:
2006-11-219:
20:
57
//Target:
M32
//Crystal:
7.3728Mhz
#include
void_delay(unsignedcharn)//延时函数定义
unsignedchari,j;
for(;
n!
=0;
n--)//n*10ms
for(j=100;
j!
j--)//100us*100=10ms
for(i=147;
i!
i--)//delay100us
;
intmain(void)
unsignedchari,j,k;
//
PORTA=0xFF;
//PA口设为输出高电平,灯灭
DDRA=0xFF;
//PA?
ú
?
aê
3?
£ê
while
(1)
i=1;
for(j=0;
j<
8;
j++)//循环8次,即PA0~~PA7轮流闪亮
{
PORTA=~i;
//反相输出,低电平有效,对应的灯亮
for(k=0;
k<
10;
k++)_delay(100);
//延时100*10=1秒,可自行调节i=i<
1;
//左移一位,I的值将向下面的列表那样变化
//0b00000001PA0
//0b00000010PA1
//0b00000100PA2
//0b00001000PA3
//0b00010000PA4
//0b00100000PA5
//0b01000000PA6
//0bPA7
}
其他IO口操作指令:
voidmain(void)
PORTA=0xff;
DDRA=0xff;
//输出模式,IO口上拉电阻有效,1为输出,0为输入。
PORTA=0xf0;
//等
以下三条指令只对操作符号右边的数字位是一的位操作。
PORTA&
=~0xf0;
//清零0xf0为01110000,即把654三位清零,其余数位不变。
PORTA|=0x77;
//置一0xf0为01110111,即把654210六位清零,其余数位不变。
PORTA^=0x70;
//翻转如果是零变成1,是一变成0。
(P&
0x80)==0x80;
//按位与判断p的第七位是否是一,是则成立
关于1<
ADIF是一个寄存器变量,可以堪称数字4,跟手册中的定义,包含芯片头文件的定义是一样的。
ADCSR=(1<
ADCSR|=(1<
ADCSR&
while(ADCSR&
while(ADCSR&
程序......
Atmega16单片机有32个通用I/O口,有PA~PD四组,每组都是8位。
其主要的寄存器有DDRXn(X=A,B,C,D;
n=0,2,…,7,下同),PORTXn和PINXn。
DDRX是方向寄存器,可读可写。
在写操作时用于制定PX口是作为输入口还是输出口;
在读操作时,从DDRX寄存器读出来的是端口的方向设定值。
DDRX寄存器的初始值为0x00。
PORTX是数据寄存器,可读写。
在写操作时,从PORTX写入的数据存入内部锁存器,以确定端口的工作状态或者将写入的数据送到外部数据总线。
PORTX寄存器的初始值为0x00。
PINX用来访问端口X的逻辑值,且只允许读操作。
从PINX读入的数据只是X口引脚的逻辑状态。
其初始值为高阻态。
引脚配置为输入时,若PORTxn为"
1“,上拉电阻将使能。
如果需要关闭这个上拉电阻,可以将PORTxn清零,或者将这个引脚配置为输出。
复位时各引脚为高阻态,即使此时并没有时钟在运行。
当引脚配置为输出时,若PORTxn为"
1“,引脚输出高电平("
1“),否则输出低电平(“0“)。
在(高阻态)三态({DDxn,PORTxn}=0b00)输出高电平({DDxn,PORTxn}=0b11)两种状态之间进行切换时,上拉电阻使能({DDxn,PORTxn}=0b01)或输出低电平.这两种模式必然会有一个发生。
如果使用情况不是这样子,可以通过置位SFIOR寄存器的PUD来禁止所有端口的上拉电阻.
用户必须选择高阻态({DDxn,PORTxn}=0b00)或输出高电平({DDxn,PORTxn}=0b10)作为中间步骤
*/
voidIO_change(void)
//高阻态
DDxn=0;
PORTxn=0;
//禁止所有端口的上拉电阻
SFIOR|=1<
PUD;
//输出高电平
DDxn=0xff;
PORTxn=0xff;
//使能所有端口的上拉电阻
SFIOR&
PUD);
voidIO_change_A(void)
{//高阻态
//上拉电阻使能({DDxn,PORTxn}=0b01)或输出低电平({DDxn,PORTxn}=0b10)
/*
voidIO_changge_B()
{//上拉输入
//高阻态({DDxn,PORTxn}=0b00)或输出高电平({DDxn,PORTxn}=0b11)
//输出低电平
/******************************************读取引脚的数据***************************************/
voidread_PINX(void)
/*PUD上拉电
DDxnPORTxn(inSFIOR)I/O阻说明
XInputNo高阻态(Hi-Z)
InputYes被外部电路拉低时将输出电流
InputNo高阻态(Hi-Z)
OutputNo输出低电平(吸收电流)
XOutputNo输出高电平(输出电流)
不论如何配置DDxn,都可以通过读取PINxn寄存器来获得引脚电平.PINxn寄存器的各个位与其前面的锁存器组成了一个同步器,这样就可以避免在内部时钟状态发生改变的短时间范围内由于引脚电平变化而造成的信号不稳定.引入了延迟是必然的。
unsignedchari;
/*定义上拉电阻和设置高电平输出*/
/*为端口引脚定义方向*/
PORTB=(1<
PB7)|(1<
PB6)|(1<
PB1)|(1<
PB0);
DDRB=(1<
DDB3)|(1<
DDB2)|(1<
DDB1)|(1<
DDB0);
/*为了同步插入nop指令*/
_NOP();
/*读取端口引脚*/
i=PINB;
/**************************未连接引脚的处理****************************************/
如果有引脚未被使用,建议给这些引脚赋予一个确定电平。
虽然如上文所述,在深层休眠模式下大多数数字输入被禁用,但还是需要避免因引脚没有确定的电平而造成悬空引脚在其它数字输入使能模式(复位、工作模式、空闲模式)消耗电流。
不推荐直接将未用引脚与VCC或GND连接,因为这样可能会在引脚偶然作为输出时出现冲击电流。
AVR熔丝位配置详解
--AVR开发前准备—熔丝位(Fuse)快速入门
AVR熔丝位(Fuse)快速入门熔丝位熔丝的作用
AVR通过熔丝来控制芯片内部的一些功能,比如JTAG,时钟的使用,掉电检测电压,是否允许调试等。
AVRStudio中STK500处理熔丝位有巨大的优势:
它是以功能组合让用户配置。
这种方式与小马(PnoyProg2000,SL-ISP)相比,具有以下的优势(优势是如此明显,可以用“巨大优势”来形容):
1有效避免因不熟悉熔丝位让芯片锁死(这是初学者的恶梦),笔者曾经锁死过三片Atmega16。
2不需要靠记忆与查文档,就能配置熔丝位(这也是初学者的恶梦)
3动手之前:
请你一定弄清楚了,你这样改会有什么后果,除非你有很多钱不在乎多锁死几个芯片。
备份你的熔丝位状态,在点击Program之前再次检查熔丝位设置正确与否,不要误点了某项而没有注意到。
由于ISP下载需要芯片本身提供时钟信号。
一定注意,如果没有接外部晶振,一定不能编程熔丝位使用外部晶振。
一旦那样做,就不能再进入编程了,也就是芯片被锁死。
建议新手不要随意设置芯片的熔丝位,等对熔丝位比较了解了再进行操作。
当芯片锁死已成事实,只要能够为芯片提供相对应的时钟源即可。
如选择了Ext.RCOsc而又没有外部RC(阻容)振荡器时,可参考手册的接一个很简单的RC振荡电路!
再将熔丝位配置改回正确的配置就可搞定!
通过下图的方法打开连接:
使用操作界面如下:
(注意:
下图中,打勾的表示选中,代表0。
没有打勾的表示1)。
上图的资料有很多相关项,你需要认识以下的代码,以理解意思。
英文翻译说明如下:
英文
中文
On-ChipDebugEnabled
片内调试使能
JTAGInterfaceEnabled
JTAG接口使能
Serialprogramdownloading(SPI)enabled
串行编程下载(SPI)使能(ISP下载时该位不能修改)
PreserveEEPROMmemorythroughtheChipErasecycle;
芯片擦除时EEPROM的内容保留
BootFlashsectionsize=xxxxwords
引导(Boot)区大小为xxx个词
Bootstartaddress=$yyyy;
引导(Boot)区开始地址为$yyyy
BootResetvectorEnabled
引导(Boot)、复位向量使能
Brown-outdetectionlevelatVCC="
xxxx"
V;
掉电检测的电平为VCC="
伏
Brown-outdetectionenabled;
掉电检测使能
Start-uptime:
xxxCK+yyms
启动时间xxx个时钟周期+yy毫秒
Ext.Clock;
外部时钟
Int.RCOsc.
内部RC(阻容)振荡器
Ext.RCOsc.
外部RC(阻容)振荡器
Ext.Low-Freq.Crystal;
外部低频晶体
Ext.Crystal/ResonatorLowFreq
外部晶体/陶瓷振荡器低频
Ext.Crystal/ResonatorMediumFreq