1、 ATmega16芯片有芯片有PORTA、PORTB、PORTC、PORTD(简称(简称PA、PB、PC、PD)4组组8位,共位,共32路通用路通用I/O接口,分接口,分别对应于芯片上别对应于芯片上32根根I/O引脚。所有这些引脚。所有这些I/O口都是口都是双(有的为双(有的为3)功能复用的功能复用的。 模拟集成电路的特点模拟集成电路的特点 模拟集成电路的特点模拟集成电路的特点 其中其中第一功能均第一功能均作为数字通用作为数字通用I/OI/O接口使用,接口使用,复用功能复用功能则分别用于中断、时钟则分别用于中断、时钟/ /计数器、计数器、USRATUSRAT、I2CI2C和和SPISPI串行通
2、串行通信、模拟比较、捕捉等应用。信、模拟比较、捕捉等应用。 恭喜你:选择了正确的恭喜你:选择了正确的AVR学习资料学习资料通用通用I/O接口基本结构与输出应用接口基本结构与输出应用 I/O口的基本结构口的基本结构 每组每组I/OI/O口配备三个口配备三个8 8位寄存器,它们分别是方向控制寄存器位寄存器,它们分别是方向控制寄存器DDRxDDRx,数据寄存器,数据寄存器PORTxPORTx,和输入引脚寄存器,和输入引脚寄存器PINxPINx(x=ABCDx=ABCD)。)。I/OI/O口的工作方式和表现特征由这口的工作方式和表现特征由这3 3个个I/OI/O口寄口寄存器控制。存器控制。 方向控制寄
3、存器方向控制寄存器DDRx用于控制用于控制I/O口的输入输出方向,即控制口的输入输出方向,即控制I/O口的工作方式为输出方式还是输入方式。口的工作方式为输出方式还是输入方式。当当DDRx=1时,时,I/O口处于输出工作方式。口处于输出工作方式。 当当PORTx=1时,时,I/O引脚呈现高电平,同时可提供输出引脚呈现高电平,同时可提供输出20mA的电流;而当的电流;而当PORTx=0时,时,I/O引脚呈现低电平,同时可引脚呈现低电平,同时可吸纳吸纳20mA电流。电流。 当当DDRx=0时,时,I/O处于输入工作方式处于输入工作方式 此时引脚寄存器此时引脚寄存器PINx中的数据就是外部引脚的实际电
4、平,中的数据就是外部引脚的实际电平,通过读通过读I/O指令可将物理引脚的真实数据读入指令可将物理引脚的真实数据读入MCU。此外,。此外,当当I/O口定义为输入时(口定义为输入时(DDRx=0),通过),通过PORTx的控制,的控制,可使用或不使用内部的上拉电阻。可使用或不使用内部的上拉电阻。表表6.1是是AVR通用通用I/O端口的引脚配置情况端口的引脚配置情况 表中的表中的PUD为寄存器为寄存器SFIOR中的一位,它的作用相当中的一位,它的作用相当AVR全部全部I/O口内部上拉电阻的总开关。当口内部上拉电阻的总开关。当PUD=1时,时,AVR所有所有I/O内部上拉电阻都不起作用(全局内部上拉无
5、效);而内部上拉电阻都不起作用(全局内部上拉无效);而PUD=0时,时,各个各个I/O口内部上拉电阻取决于口内部上拉电阻取决于DDRXn的设置。的设置。 (1).使用使用AVR的的I/O口,首先要正确设置其工作方式,确定口,首先要正确设置其工作方式,确定其工作在输出方式还是输入方式。其工作在输出方式还是输入方式。 (2)当当I/O工作在输入方式,要读取外部引脚上的电平时,工作在输入方式,要读取外部引脚上的电平时,应读取应读取PINxn的值,而不是的值,而不是PORTxn的值。的值。 (3)当当I/O工作在输入方式,要根据实际情况使用或不使用工作在输入方式,要根据实际情况使用或不使用内部的上拉电
6、阻。内部的上拉电阻。 (4)一旦将一旦将I/O口的工作方式由输出设置成输入方式后,必口的工作方式由输出设置成输入方式后,必须等待一个时钟周期后才能正确的读到外部引脚须等待一个时钟周期后才能正确的读到外部引脚PINxn的值。的值。I/O端口寄存器端口寄存器 PA口寄存器口寄存器PORTA、DDRA、PINA各个位的具体定义各个位的具体定义 位 7 6 5 4 3 2 1 0 $1B($003B) PORTA7 PORTA6 PORTA5 PORTA4 PORTA3 PORTA2 PORTA1 PORTA0 PORTA 读/写 R/W R/W R/W R/W R/W R/W R/W R/W 复位值
7、 0 0 0 0 0 0 0 0 位 7 6 5 4 3 2 1 0 $1A($003A) DDA7 DDA6 DDA5 DDA4 DDA3 DDA2 DDA1 DDA0 DDRA 读/写 R/W R/W R/W R/W R/W R/W R/W R/W 复位值 0 0 0 0 0 0 0 0 位 7 6 5 4 3 2 1 0 $19 ($0039) PINA7 PINA6 PINA5 PINA4 PINA3 PINA2 PINA1 PINA0 PINA 读/写 R R R R R R R R 复位值 N/A N/A N/A N/A N/A N/A N/A N/A 正确使用正确使用AVRAVR
8、的的I/OI/O口要注意:口要注意:(1)(1)先正确设置先正确设置DDRxDDRx方向寄存器,再进行方向寄存器,再进行I/OI/O口的读写操作。口的读写操作。(2)AVR(2)AVR的的I/OI/O口口复位后复位后的初始状态全部为的初始状态全部为输入工作方式输入工作方式,内部上,内部上拉电阻无效。所以,外部引脚呈现三态高阻输入状态。拉电阻无效。所以,外部引脚呈现三态高阻输入状态。(3)(3)用户程序需要首先对要使用的用户程序需要首先对要使用的I/OI/O口进行初始化设置,根据口进行初始化设置,根据实际需要设定使用实际需要设定使用I/OI/O口的工作方式(输出还是输入),当设定口的工作方式(输
9、出还是输入),当设定为输入方式时,为输入方式时,还要考虑是否使用内部的上拉电阻还要考虑是否使用内部的上拉电阻。(4)(4)在硬件电路设计时,如能利用在硬件电路设计时,如能利用AVRAVR内部内部I/OI/O口的上拉电阻,可口的上拉电阻,可以节省外部的上拉电阻。以节省外部的上拉电阻。C语言中的位操作语言中的位操作 AVR通用通用I/O端口的主要特点为:端口的主要特点为:双向可独立位控的双向可独立位控的I/O口口Push-Pull大电流驱动大电流驱动 (最大最大40mA) 可控制的引脚内部上拉电阻可控制的引脚内部上拉电阻每一位引脚内部都有独立的,可通过编程设置的,设定为上每一位引脚内部都有独立的,
10、可通过编程设置的,设定为上拉有效或无效的内部上拉电阻。当拉有效或无效的内部上拉电阻。当I/O口被用于输入状态,且口被用于输入状态,且内部上拉电阻被激活(有效)时,如果外部引脚被拉低,则内部上拉电阻被激活(有效)时,如果外部引脚被拉低,则构成电流源输出电流(构成电流源输出电流(uA量级)。量级)。可控的方向寄存器可控的方向寄存器DDRxC语言中的位操作语言中的位操作 a | b - 按位或按位或 这个表达式指示中这个表达式指示中 a 被表达式中的被表达式中的b 按位进行或运算按位进行或运算 这惯用于打这惯用于打开某些位开某些位 尤其常用尤其常用|=的形式的形式 例如例如 PORTA |= 0 x
11、80; / 打开位打开位 7 (最高位最高位) a & b - 按位与按位与 这个运算在检查某些位是否置这个运算在检查某些位是否置 1 时有用时有用 例如例如 If (PORTA & 0 x81) = 0) / 检查位检查位 7 和位和位 0 注意圆括号需要括在注意圆括号需要括在&运算符的周围运算符的周围 因为它和因为它和= = 相比运算优先相比运算优先级较低级较低 这是这是 C 程序中很多错误的原因之一程序中很多错误的原因之一 a b - 按位异或按位异或 这个运算对一个位取反有用这个运算对一个位取反有用 例如例如 在下面的例子中在下面的例子中 位位 7 是被翻转的是被翻转的 PORTA =
12、 0 x80; / 翻转位翻转位 7 a - 按位取反按位取反 在表达式中这个运算执行一个取反在表达式中这个运算执行一个取反 当用按位与运算关闭某些位当用按位与运算关闭某些位时时 与这个运算组合使用尤其有用与这个运算组合使用尤其有用 如如 PORTA &= 0 x80;/ 关闭位关闭位 7 PORTC | = (1BIT0) |( 1BIT3); 1(BIT0)表示逻辑表示逻辑1左移到左移到PORTC 的0位,结果为位,结果为0b00000001; 1(BIT3) 表示逻辑表示逻辑1左移左移PORTC 的3位,结果为位,结果为0b00001000。0b00000001在同在同0b0000100
13、0相或相或,结果为,结果为0b00001001。 PORTD=BIT(PD7) PORTD口的第口的第7位取反位取反/,取反,取反PD0引脚,引脚,TCCR0|=(1CS01)|(1CS00);TCCR0功能寄存器的功能寄存器的CS01 、CS00位置位置1。通用数字通用数字I/O口的设置与编程口的设置与编程 1. 通用通用I/O输出设计要点输出设计要点 应用应用I/O口输出时,在系统的软硬件设计上应注意的问题有:口输出时,在系统的软硬件设计上应注意的问题有: 输出电平的转换和匹配。输出电平的转换和匹配。 输出电流的驱动能力。输出电流的驱动能力。 I/O口输出为口输出为“1”时,可以提供时,可
14、以提供20mA左右的驱动电流。输左右的驱动电流。输出为出为“0”时,可以吸收时,可以吸收20mA左右的灌电流(最大为左右的灌电流(最大为40mA)。)。 输出电平转换的延时输出电平转换的延时。 应用举例应用举例: LED发光二极管的控制发光二极管的控制 设计一个带有一排设计一个带有一排8个发光二极管的简易彩灯控制系统个发光二极管的简易彩灯控制系统 硬件电路设计硬件电路设计 当电压当电压U1大于大于U2约约1V以上时,二极管导通以上时,二极管导通发光。当导通电流大于发光。当导通电流大于5mA时,人的眼睛时,人的眼睛就可以明显地观察到二极管的发光,导通就可以明显地观察到二极管的发光,导通电流越大,
15、亮度越高。电流越大,亮度越高。 RVledUUI21 AVR的的I/O口输出口输出“0”时,可以吸收时,可以吸收最大最大40mA的的电流,因此采电流,因此采用控制发光二用控制发光二极管负极的设极管负极的设计比较好。计比较好。 #include /包含单片机型号头文件包含单片机型号头文件#include /包含包含位位操作头文件操作头文件#include /包含延时头文件包含延时头文件#define LEDPORTB/LED端口端口 #define Open_LED PORTA|=0 x10 /使能使能LEDvoid En_Led(void) /使能使能LED DDRB=0 xff; /设置输出
16、设置输出PORTB=0 xff;/输出高电平输出高电平Open_LED;/打开打开LED功能功能void main(void) unsigned char i;En_Led();/使能使能LEDwhile(1)for(i=0;i1;i-) LED=0 xff; /LED全部熄灭全部熄灭LED&=BIT(i-2); /点亮相应位点亮相应位LEDdelay_nms(200);/延时大约延时大约100毫秒毫秒应用举例应用举例:继电器控制继电器控制 控制恒温箱的加热的硬控制恒温箱的加热的硬件电路设计件电路设计 恒温箱的加热源采用恒温箱的加热源采用500W电炉,电炉的工作电压电炉,电炉的工作电压220v
17、,电流电流2.3A。选用。选用HG4200继电器,开关负载能力为继电器,开关负载能力为5A/AC220V,继电器吸合线圈的工作电压继电器吸合线圈的工作电压5v,功耗,功耗0.36W,计算得吸合电流,计算得吸合电流为为0.36/5 = 72mA。因此,要能使继电器稳定的吸合,驱动电流。因此,要能使继电器稳定的吸合,驱动电流应该大于应该大于80mA。该电流已经超出。该电流已经超出AVR本身本身 I/O口的驱动能力,口的驱动能力,因此外部需要使用功率驱动元件。因此外部需要使用功率驱动元件。 I/O引脚输出引脚输出“1”时,时,三极管导通,继电器三极管导通,继电器吸合,电炉开始加热。吸合,电炉开始加热
18、。I/O引脚输出引脚输出“0”时,时,三极管截止,继电器三极管截止,继电器释放,加热停止。释放,加热停止。 PORTC | =(1 PORTC0) PORTC 位置位置1。继电器吸合,电炉开始加热。继电器吸合,电炉开始加热。PORTC & = (1 PORTC0)PORTC & = 0 x80 PORTC 位置位置0。继电器释放,加热停止。继电器释放,加热停止。 应用举例应用举例:LED数码显示器的应用数码显示器的应用 0-D7连接连接PB0-PB7,段选信号,段选信号SMGLK11连接连接PA3,位选信,位选信号号BITLK11连接连接PA2,74AC573SJ为锁存器。为锁存器。 #inc
19、lude /包含单片机型号头文件包含单片机型号头文件#include /包含包含位位操作头文件操作头文件#include /包含延时头文件包含延时头文件#include /包含通用函数及宏定义头文件包含通用函数及宏定义头文件/*/* 函数名称函数名称: Display_All_SMG() */* 功功 能能: 显示显示8位数据信息位数据信息 */* 参参 数数: *pdata-显示缓冲数组地址指针显示缓冲数组地址指针 */void Display_All_SMG(unsigned char *pdata) unsigned char i;for(i=0;i8;i+) /循环循环8次,每次显示一
20、位次,每次显示一位 Display_One_SMG(i,pdatai);/*/* 函数名称函数名称: Display_Cycle_SMG() */* 功功 能能: 循环显示循环显示8位数据信息位数据信息 */* 参参 数数: *pdata-显示缓冲数组地址指针显示缓冲数组地址指针 */* 返回值返回值 : 无无 */void Display_Cycle_SMG(unsigned char *pdata) unsigned int i,j; for(i=0;i1;j-)/扫描扫描8个数码管个数码管 Display_One_SMG(j-2,pdata(i/50+9-j)%16);/调用显示调用显示 /*/* 函数名称函数名称: main() */* 功功 能能: 数码管滚动显示数字数码管滚动显示数字 */* 参参 数数: 无无 */* 返回值返回值 : 无无 */*/void main(void)unsigned char SMG_Display16=0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15;/显示缓存显示缓存CPU_Init(); /初始化初始化CPUwhile(1)/无限循环,滚动显示数字无限循环,滚动显示数字Display_Cycle_SMG(SMG_Display);