I/O操作:复位时各引脚为高阻态(tri-state),即使此时没有时钟在运行。
1. 引脚配置为输入时DDxn=0,若PORTxn 为"1“,上拉电阻将使能。
引脚配置为输出时DDxn=1,若PORTxn 为"1“,引脚输出高电平("1“),否则输出低电平(“0“)。
2. 在( 高阻态) 三态({DDxn, PORTxn} = 0b00) 输出高电平({DDxn, PORTxn} = 0b11) 两种状态之间进行切换时,上拉电阻使能({DDxn, PORTxn} = 0b01) 或输出低电平({DDxn,PORTxn} = 0b10) 这两种模式必然会有一个发生。(必有一种发生,是因为两个寄存器修改会有先后顺序,所以应当根据实际情况选一种合适的顺序)
3. 上拉电阻使能是完全可以接受的,因为高阻环境不在意是强高电平输出还是上拉输出。如果使用情况不是这样子,可以通过置位SFIOR 寄存器的PUD 来禁止所有端口的上拉电阻。
4 在上拉输入({DDxn,PORTxn} = 0b01) 和输出低电平({DDxn,PORTxn} = 0b10) 之间切换也有同样的问题。用户必须选择
高阻态({DDxn,PORTxn} = 0b00) 或输出高电平({DDxn, PORTxn} = 0b11) 作为中间步骤。
在按键扫描时:端口Px在读取PINxn前,应先将PORTxn置位,否则若在PORTxn=0的情况下,管脚位高阻态(0,0),PINxn寄存器的值将一直为0.
下面是一段扫描程序: (注意上面4点的应用)
/*-----------------------------------------------------------------------------------*/
//KEYA : PA0-PA3 KEYD : PB0-PB3 A/D组成矩阵扫描
// 操作 "X|=0x0F” 是要先将寄存器X的值读出到一个临时寄存器,或操作(将1对应位 置位),然后写回到寄存器X。以上操作经测试不会有问题,读出时也不会出错。 同理,与操作是将0对应位 清0.
int keyA,keyB;
keyA = keyB =0xFF;
//(DDRnx,PORTnx)=(0,0);
//若DDRA(0-3) = 0,则是从 操作前状态(0,x)->(0,1)->(0,1) 若DDRA(0-3) = 1 则是从(1,x)->(1,1)->(0,1)
KEYA_IO_OUTPUT |= 0x0F; //PORT PA0-PA3 1 需要先上拉电阻,这样输入时才能有电流输出,pinA值才会正确
KEYA_IO_DIR &|0xF0; //DDR PA0-PA3 0 输入
//若DDRB(0-3) = 0,则是从(0,x)->(0,0)->(1,0) 若DDRB(0-3) = 1 则是从(1,x)->(1,0)->(1,0)
KEYD_IO_OUTPUT &=0xF0; //PORT PB0-PB3 0
KEYD_IO_DIR |= 0x0F; //DDR PB0-PB3 1 输出
__bulidin_avr_delay_cycles(2); //Emits a sequence of instuctions causing the CPU to spend (_n) cycles on it.
keyA = (KEYA_IO_IN<<4)&0xF0; //PIN PA0-PA3 读 (左移4位是为了后面和PINB读的值'或'时方便)
上面的程序完成从PB0-3输出低电平 PA0-3 输入。
Q:PORTxn = 1 一定要在DDRxn=0前
A:是的,原因见上面第2条。
Q:PORTxn = 0 一定要在DDRxn=1前
A: 是的,原因见上面第4条。
Q:对只读寄存器PINxn 写入逻辑"1“ 将造成数据寄存器(PROTxn)数据发生"0“ 与“1“ 的交替变化?
A:没有在开发板上看到有寄存器的值发生变化。
Q: avrgcc中buildin的延时函数: __builtin_avr_delay_cycles(const int _n);
A: 延迟时间为:Emits a sequence of instuctions causing the CPU to spend (_n) cycles on it.
*注:avr提供的函数_delay_ms(double __ms) _delay_us(double __us)都不能用,编译时报错,__builtin_avr_delay_cycles需要一个const int参数。
Q:avrgcc中提供了另一个延时函数:
void _delay_loop_1(uint8_t __count)
{
__asm__ volatile ( //具体汇编含义 见 AT&T汇编语言格式
"1: dec %0" "/n/t"
"brne 1b"
: "=r" (__count)
: "0" (__count)
);
}
Q:什么是高阻三态?
A: 高阻态这是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。
高阻态的实质: 电路分析时高阻态可做开路理解。你可以把它看作输出(输入)电阻非常大。他的极限可以认为悬空。也就是说理论上高阻态不是悬空,它是对地或对电源电阻极大的状态。而实际应用上与引脚的悬空几乎是一样的。
高阻态的意义: 当门电路的输出上拉管导通而下拉管截止时,输出为高电平;反之就是低电平;如上拉管和下拉管都截止时,输出端就相当于浮空(没有电流流动),其电平随外部电平高低而定,即该门电路放弃对输出端电路的控制 。
典型应用:
1、 在总线连接的结构上。总线上挂有多个设备,设备于总线以高阻的形式连接。这样在设备不占用总线时自动释放总线,以方便其他设备获得总线的使用权。
2、 大部分单片机I/O使用时都可以设置为高阻输入,如凌阳,AVR等等。高阻输入可以认为输入电阻是无穷大的,认为I/O对前级影响极小,而且不产生电流(不衰减),而且在一定程度上也增加了芯片的抗电压冲击能力。
高阻态常用表示方法 高阻态常用字母 Z 表示