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