1、(一)、spi接口用途及认识 53(二)、非中断方式使用spi接口 53(三)、中断方式使用spi接口 53十四、液晶模块使用 53十五、SD卡使用 53十六、红外遥控 54(一)、红外遥控接收识别 54(二)、红外遥控发射 54ATMega16嵌入式应用部分 54一、电池充电器设计 54二、示波器设计 54三、便携收录机设计 54附录:知识点索引 54参考文献 55ATMage16基础编程部分一、认识ATMega16ATmega16是基于增强的AVR RISC结构的低功耗8位CMOS微控制器。由于其先进的指令集以及单时钟周期指令执行时间,ATmega16的数据吞吐率高达1 MIPS/MHz,
2、从而可以缓减系统在功耗和处理速度之间的矛盾。ATmega16 AVR内核具有丰富的指令集和32个通用工作寄存器。所有的寄存器都直接与算逻单元(ALU)相连接,使得一条指令可以在一个时钟周期内同时访问两个独立的寄存器。这种结构大大提高了代码效率,并且具有比普通的CISC微控制器最高至10倍的数据吞吐率。ATmega16有如下特点:16K字节的系统内可编程Flash(具有同时读写的能力,即RWW),512字节EEPROM,1K字节SRAM,32个通用I/O口线,32个通用工作寄存器,用于边界扫描的JTAG接口,支持片内调试与编程,三个具有比较模式的灵活的定时器/计数器(T/C),片内/外中断,可编
3、程串行USART,有起始条件检测器的通用串行接口,8路10位具有可选差分输入级可编程增益的ADC,具有片内振荡器的可编程看门狗定时器,一个SPI串行端口,以及六个可以通过软件进行选择的省电模式。工作于空闲模式时CPU停止工作,而USART、两线接口、A/D 转换器、SRAM、T/C、SPI 端口以及中断系统继续工作;掉电模式时晶体振荡器停止振荡,所有功能除了中断和硬件复位之外都停止工作;在省电模式下,异步定时器继续运行,允许用户保持一个时间基准,而其余功能模块处于休眠状态;ADC噪声抑制模式时终止CPU和除了异步定时器与ADC以外所有I/O模块的工作,以降低ADC转换时的开关噪声;Standb
4、y模式下只有晶体或谐振振荡器运行,其余功能模块处于休眠状态,使得器件只消耗极少的电流,同时具有快速启动能力;扩展Standby模式下则允许振荡器和异步定时器继续工作。(一)、ATmega16 引脚功能ATmega16有4个8位的双向I/O端口PA、PB、PC、PD,他们对外对应32个I/O引脚,每一位都可以独立地用于逻辑信号的输入和输出。在5V工作电压下,输出高点平时,每个引脚可输出达20mA的驱动电流;而输出低电平时,每个引脚可吸收最大为40mA的电流,可以直接驱动发光二极管(一般的发光二极管的驱动电流为10mA)和小型继电器等小功率器件。AVR大部分的I/O端口都具备双重功能(有的还有第三
5、功能)。其中第一功能是作为数字通用I/O接口使用,而复用的功能可分别与片内的各种不同功能的外围接口电路组合成一些可以完成特殊功能的I/O口,如定时器、计数器、串行接口、模拟比较器、捕捉器、USART、SPI等。引脚名称引脚功能说明VCC电源正GND电源地端口A(PA7.PA0)端口A做为A/D转换器的模拟输入端。端口A为8位双向I/O口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口A处于高阻状态。端口B(PB7.PB0)端口B为8位双向I/O口,具有可
6、编程的内部上拉电阻。在复位过程中,即使系统时钟还未起振,端口B处于高阻状态。如果ISP接口使能,引脚PB5至PB7输入输出功能失效。端口C(PC7.PC0)端口C为8位双向I/O口,具有可编程的内部上拉电阻。在复位过程中,即使系统时钟还未起振,端口C处于高阻状态。如果JTAG接口使能,引脚PC5(TDI)、PC3(TMS) 、PC2(TCK) 与PC3(TDO)做调试使用,输入输出功能失效。端口D(PD7.PD0)端口D为8位双向I/O口,具有可编程的内部上拉电阻。作为输入使用时,若内部上拉电阻使能,则端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口D处于高阻状态。端口
7、D也可以用做其他不同的特殊功能RESET复位输入引脚。持续时间超过最小门限时间的低电平将引起系统复位。XTAL1反向振荡放大器与片内时钟信号电路的输入端。XTAL2反向振荡放大器与片内时钟信号电路的输出端。AVCCAVCC是A/D转换器的电源。不使用ADC时,该引脚应直接与VCC连接。使用ADC时应通过一个低通滤波器与VCC连接。AREFA/D 的基准电压输入引脚二、AVR开发工具AVR开发工具由开发软件系统、硬件开发板、Jtag调试工具、和ISP下载工具四部分组成。(一)、开发软件系统开发软件系统常用有ICCAVR和AVRGCC两类,ICCAVR是付费软件,而AVRGCC是免费软件,在版权意
8、识日益增加的今天,我们使用AVRGCC。AVRGCC同AVR Studio配合可以进行软件在线调试、下载,是AVR开发工具由开发软件系统的首选。AVR Studio是AVR生产商ATmel公司免费提供的开发环境,可以进行下载和在线调试,缺点是只支持汇编不支持C语言,而AVRGCC支持C语言,两者配合,可以用C语言开发AVR。依次缺省安装AVR Studio及AVRGCC后就可以进行AVR的学习和开发。(二)、硬件开发板(三)、ISP下载(四)、Jtag调试工具第一部:硬件连接。第二步:使用AVRstudio打开*.cof文件如果你没有自己写AVR程序,你可以使用本站的新手入门第一个程序。AVR
9、_first,实现红绿灯不断闪烁的例子。程序启动时候的样子如下图:程序启动界面:打开main.cof文件工程文件存为main_cof.aps方便下次打开选择相关硬件配置(端口的选择参见下图) 使用JTAG&SIP默认会是COM3。端口的选择(说明:这个画面可以在:右击我的电脑-管理-设备管理器里面找到。)端口频率设置 运行程序 直接运行你可以看到红绿灯闪动的效果。点击看大图你还可以通过Debug里面的命令进行在线调试。 好了,现在你已经进入AVR的精彩世界了。 三、调试命令的使用调试快捷键,具体可以通过DEBUG菜单项查看,按照相应的指令就可以进行调试操作了。观察窗口的说明:使用以下窗口可以即
10、时查看寄存器,变量,以及数据地址的值,更多内容大家自己摸索吧。三、I/O 引脚使用(一)、I/O 口引脚配置AVR单片机的每组I/O口都配备有三个8为寄存器,分别是:方向控制寄存器DDRx、数据寄存器PORTx、输入引脚寄存器PINx(x=A/B/C/D).I/O口的工作方式和表现特征由这三个I/O寄存器控制。方向控制寄存器DDRx用于控制I/O口的输入输出方向,及控制I/O口的工作方式为输出方式还是输入方式。DDRx=1时,I/O口处于输出工作方式;此时数据寄存器PORTx中的数据输出到外部引脚。DDRx=0时,I/O口处于输入工作方式;此时输入引脚寄存器PINx中的数据就是外部引脚的实际电
11、平,通过读I/O指令可将物理引脚的真实数据读入MCU。此外,当I/O口定义为输入时(DDRx=0),通过PORTx的控制,可使用或不使用内部的上拉电阻。I/O 口引脚配置表AVR I/O 口引脚配置表DDRXn PORTXn PUD I/O 方式 内部上拉电阻 引脚状态说明 0 X 输入 无效 三态(高阻) 1 有效 外部引脚拉低时输出电流 (uA) 输出 推挽 0 输出,吸收电流 (20mA) 推挽 1 输出,输出电流 (20mA) (二)、I/O 口的输出操作让发光二极管闪动任务:通过AVR端口,控制发光二极管,在制定时间内进行亮、灭状态转换。知识点:AVR端口的输出设置、延时库函数使用(
12、一)、电路SIP8接I/O 口,输出高电平时,发光二极管处于灭状态;输出低电平时,发光二极管处于亮状态。在每个状态之间,插入延时,可以轻松实现让发光二极管闪动的效果。虽然AVR的I/O口单独输出“1”时,可输出较大电流足已点亮一LED,但AVR总的I/O输出毕竟是有限的,所以,可将AVR的I/O口设计为输出“0”时点灯,输出“1”时熄灯。这种接法亦叫“灌电流接法”。 (二)、程序#includeutil/delay.hint main()DDRD=0xff;PORTD=0xff;while(1) PORTD=0x00; _delay_ms(500.0); PORTD=0xff;io.h完成端口
13、的定义,delay.h实现延时。DDRD=0xff设置PORTD为输出口,在死循环while(1)内,PORTD=0x00,点亮二极管,_delay_ms(500.0)延时半秒;再熄灭二极管,延时半秒,如此循环,实现发光二极管闪动的效果。(三)、引脚的输出操作让发光二极管流动通过AVR引脚操作,控制发光二极管,在制定时间内进行亮、灭状态转换。AV引脚的输出设置,与、或运算的应用让发光二极管流动,一般称为流水灯,电路同前一个试验采用同一个电路。实现方法可以在前一个程序基础上进行简单的改进,将循环体内容改为: PORTD=0x7f; PORTD=0xbf; PORTD=0xdf; PORTD=0x
14、ef; PORTD=0xf7; PORTD=0xfb; PORTD=0xfd; PORTD=0xfe;(二)、程序本例采用引脚操作的方法,利用逻辑操作每次只改变一个引脚的输出值,我们看下面两个操作:PORTD|=(1i); (1)PORTD&=(1 (2)式(1)的操作结果仅使PORTD的第i位为1;式(2)的操作结果仅使PORTD的第i位为0。如果改变i值就可以任意改变某位的使。实现流水灯的程序如下:unsigned char i; for(i=0;i=7;i+) PORTD& /点亮第i个二极管 PORTD|=(1 /熄灭第i个二极管 在死循环while(1)内,i值从0变化为7,每次变化
15、时,PORTD&i);点亮第i个二极管,后演示半秒,保持二极管点亮;熄灭第i个二极管,结束本次循环。(四)、引脚的输入操作按键控制发光二极管的亮灭通过AVR引脚接按钮,控制发光二极管的亮、灭状态转换。按下时亮,不按时灭。AV引脚的输入设置,与运算的应用,按键去抖。按键是基本方便的输入手段,在本例中,通过介绍利用按键开关控制发光二极管的亮灭来了解AVR单片机的端口检测外部信号的功能和方法。1、单按键的电路典型的单按键的电路如图71所示,在按键没有按下时,PA5引脚信号为高电平,当按键按下时PA5引脚信号为低电平。通过检测引脚的电平会方便的知道按键的状态。图71 按键电路我们日常所说的按键,外观如
16、图72所示,有四个脚。按键两侧的脚是连通的,之所以做成四个脚,是为了安装牢固。图72 按键开关2、按键的响应过程理想的按键的闭合和断开时,接触点的电压应该立即变高或者变低,但是由于机械触点的弹性以及按键按动时电压突变等原因,在触点闭合或断开的瞬间会出现电压抖动现象,如图72所示。在发生抖动的时间一般在5-10ms。一次按键处理过程如下:当按键按下之后,相应的按键接触点的电压以高低电平的方式输入到单片机的I/O口。按键的闭合与断开是有一定时间的,一般为0.1-1S。而AVR单片机的机器周期一般为1us甚至更短,在0.1-1S的时间段内,程序会检测很多次按键的输入电平,这样单片机可能会认为按键被按
17、下了多次,从而出现误判。 图73 按键闭合断开时的电压波动示意图3、按键去抖动的方法和原理为了去除按键的抖动,保证单片机对按键的一次输入只响应一次,可以采用硬件和软件两种方法:硬件电路去抖动是在外围电路中加入去抖动电路(如R-S触发器);软件去抖动是在程序中加入延时程序以跳过抖动时间,等待信号稳定后再次判断按键的输入电平,如果信号电平保持不变,则可以确认一次按键按下。硬件去抖动电路的原理用R-S触发器形成去抖电路是单片机外围电路设计中常用的方法,这种方法可以减少单片机软件对按键动作的延时和计算。典型的硬件去抖动电路如图74,74LS02构成一个R-S触发器电路实现按键的消抖电路。 图74 74
18、LS02实现的硬件消抖电路软件消抖的原理和实现软件消抖的基本原理是在软件中对按键进行两次检测确认,记载第一次检测到按键按下后,间隔10ms左右再次检测按键是否按下,只有在两次都检测到按键按下时才最终确认有键按下,这样就避开了按键的抖动时间,从而消除了抖动的影响。 在按键接口软件的设计中,除了要考虑按键消抖外,一般还要判别按键的释放,只有检测到按键释放后,才能确定为一次完整的按键动作。通用的案件检测程序如下:1. Keyscan()2. 3. if(PINA&0X20)=0) /判断按键是否按下,等于0表示按键按下4. 5. delayms(20); /延时20ms。避开按键抖动时间6. if(
19、PINA&0X20)=0) /再次判断按键是否按下,7. 8. /按键按下的处理程序9. 10. 11. While(PINA&0X20)=0); /判断按键是否放开,不等于表示按键释放,退出处理函数12. 程序通过检测连接在PA5引脚上按键状态,控制连接PD口的八个二极管的亮灭。按键按下时二极管处于亮的状态,按键抬起,二极管处于熄灭的状态。1. #include2. #include3. int main()5. DDRD=0xff;6. PORTD=0xff;7. DDRA=0x00;8. PORTA=0x0;9. unsigned char i;10. while(1)11. 12. i
20、f(PINA&13. 14. _delay_ms(20);15. if(PINA&16. 17. PORTD=0X0;18. while(PINA& /判断按键是否放开,不等于表示按键释放,退出处理函数19. 20. 21. PORTD=0Xff;22. 23. 四、键盘(一)、矩阵键盘1波峰法构造矩阵键盘,识别按键,并将按键值在数码管上显示。非运算的应用,按键去抖,矩阵键盘结构及识别程序演变。矩阵键盘是输入数字的最简介的方式,4X4矩阵键盘有16个键,满足10个数字和其他字符输入的需要。电路结果如下图。电路下方的数码管是为学习方便而放置的,输入BCD码给数码管就会看到对应的数字,使用起来很方
21、便,但这种数码管没有实际的产品和实物,仅是为仿真方便而构造的理想数码管。这两个数码管负责显示各种输出。1、某行按键的识别 下面程序仅可以识别第一行的四个键的按下,并分别显示0、1、2、3。程序执行PORTA =0x7f后,PA7为低电平,其他为高电平,如果第一个键按下,PINA的电平是0X77,执行temp = PINA&0X0f后,temp等于0X7。如果第二个键按下,temp等于0Xb。如果第一个键按下,temp等于0Xd。如果第一个键按下,temp等于0Xe。具体代码如下:3. unsigned char keyscan();4. int main()5. 6. unsigned cha
22、r keyv;7. DDRB=0xff;8. PORTB=0x00;9. while(1)10. 11. keyv=keyscan();12. PORTB=keyv;13. 14. 15. unsigned char keyscan()17. unsigned char keycode,temp;18. DDRA=0xf0;/高四位输出,低四位输入19. PORTA=0x00;20. keycode=0x10;21. PORTA=0x7f;/第一行为低电平,其他为高电平22. temp=PINA&0X0f;/只看低四位值23. if(temp!=0x0f) /判断按键是否按下,等于0表示按键按
23、下24. 25. _delay_ms(20);26. temp=PINA&27. if(temp!=0x0f)28. 29. switch(temp)30. 31. case 0x0e: keycode=3;break;32. case 0x0d: keycode=2;33. case 0x0b: keycode=1;34. case 0x07: keycode=0;35. 36. 37. 38. return keycode;39. 程序中语句PORTA=0x7f负责选择识别那行的按键,如果将0x7f改为0xbf、0xdf或0xef。高四位为零十对应的行,就是要识别那行的按键,试试对吗?2、
24、全部按键的识别在上面程序基础上进行简单修改,可以得到识别全部按键的程序。将2137行重复三次,每次将21行赋值修改对应的0xbf、0xdf或0xef,再将3134指定为想要的键值。采用此方案最大的缺点是程序太长。为了进行优化要对子程序keyscan()做部分修改,具体如下:1. unsigned char keyscan()3. unsigned char keycode,temp,line;4. DDRA=0xf0;5. PORTA=0x00;6. keycode=0x10;7. line=0x80;8. PORTA=line;9. temp=PINA&10. if(temp!12. _delay_ms(20);13. temp=PINA&14. if(temp!15. 16. switch(temp)17. 18. case 0x0e:19. case 0x0d:20. case 0x0b:21. case 0x07:24. 25. return keycode;26. 第7行取0X40、0X20、0X10可以识别其他行按键。上面子程序仍很长,可以再进行优化,代码如下:3. unsigned char keycode,temp,line,lcode;4
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1