AVR学习笔记二十基于模数转换的AD键盘实验.docx

上传人:b****2 文档编号:405562 上传时间:2022-10-09 格式:DOCX 页数:13 大小:152.02KB
下载 相关 举报
AVR学习笔记二十基于模数转换的AD键盘实验.docx_第1页
第1页 / 共13页
AVR学习笔记二十基于模数转换的AD键盘实验.docx_第2页
第2页 / 共13页
AVR学习笔记二十基于模数转换的AD键盘实验.docx_第3页
第3页 / 共13页
AVR学习笔记二十基于模数转换的AD键盘实验.docx_第4页
第4页 / 共13页
AVR学习笔记二十基于模数转换的AD键盘实验.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

AVR学习笔记二十基于模数转换的AD键盘实验.docx

《AVR学习笔记二十基于模数转换的AD键盘实验.docx》由会员分享,可在线阅读,更多相关《AVR学习笔记二十基于模数转换的AD键盘实验.docx(13页珍藏版)》请在冰豆网上搜索。

AVR学习笔记二十基于模数转换的AD键盘实验.docx

AVR学习笔记二十基于模数转换的AD键盘实验

AVR学习笔记二十、基于模数转换的AD键盘实验

20.1实例功能

在前面的实例中我们已经学习了在单片机系统中检测矩阵按键的接口电路和程序设计。

但是矩阵式键盘仍然要占用不少I/O口资源,4X4键盘就占用了8根I/O口线,那么有没有更简单的办法,使用更少的I/O口资源检测更多的按键呢?

通过前面的学习,我们知道按键检测实际上是检测连接按键的端口的高低电平值,而我们在前面的实例中只是简单的判断连接按键的端口的电平是高电平(+5V)还是低电平(0V)。

那么是否可以通过电平的微小变化来检测按键是否被按下呢?

在这个实验中,我们采用模数转换(AD)的方法来实现1个I/O口识别16个按键的实验,本实例分为三个功能模块,分别描述如下:

●单片机系统:

利用ATmega16单片机与AD键盘电路实现1个I/O口的多按键识别。

●外围电路:

AD键盘电路、串口电平转换电路。

●软件程序:

编写软件,实现AD键盘识别16个按键的程序。

通过本实例的学习,掌握以下内容:

●AD键盘的电路设计和程序实现。

20.2器件和原理

20.2.1AD键盘的工作原理

我们知道AVR单片机自带有内部模数转换(AD)电路,那么我们就利用AVR的这一特性来实现利用一个I/O口检测16个按键的实验。

图1为一个A/D键盘的原理图,从图中可以看出,当不同的按键被按下时,ADC端点处的电压不同,通过判断不同的电压值就可以判断出是那个按键被按下。

AVR单片机的A/D转换位数为10位,实际应用中我们只取高8位的值就可以分辨出16个按键。

我们设定AD转换的参考电压为VCC,这样A/D键盘识别准确度最高,并且能够识别更多的按键。

图1A/D键盘电路

20.2.2A/D键盘的缺陷

在实际应用中,我们是不可能得到准确的A/D转换值的,这是因为存在以下几种误差:

1)、对于同一点处的电压值,A/D多次采样的结果不可能完全相同。

2)、电阻的误差。

电阻值由于电阻的精度和环境温度的原因,误差较大,所以A/D键盘各个按键点的分压不准确。

3)、为尽量减少误差,可以采取增加电阻精度、增加温度补偿等方法,另外在软件处理时候要注意消除按键抖动等因素,还要对实际转换值和标准值给出误差补偿。

4)、如果按键按下,经过A/D转换,若实际转换值在允许误差范围之内(需要实际测量各点电压,并计算各点电压平均值),则认为按键按下,否则程序不响应。

5)、实际试验过程中,还要考虑电阻的累积误差,选用精度越高的电阻,可分辨的按键数目越多。

20.3电路和连接

本实验主要有两部分电路模块组成:

串口电平转换电路,A/D键盘电路。

串口电平转换电路在前面的实例中我们已经做过介绍,在此不再重复。

这里我们重点介绍一下A/D键盘电路。

实际试验中我们将图1中的ADC接点连接到单片机的PA1口,也就是A/D转换的AD1通道。

20.4程序设计

1、程序功能

在本实例中,我们利用串口将A/D键盘中按下的按键的键码值发送到计算机,通过串口助手观察实验结果。

2、函数说明

本实例主要有串口数据发送程序和A/D键盘识别程序,串口数据发送程序我们前面例子中已经介绍过,本实例的程序中不再详细说明。

3、编程说明

使用WINAVR开发环境,使用的是外部12M的晶振,所以需要将makefile文件中的时钟频率修改为12M。

另外在程序烧录到单片机的时候,熔丝位也要选择为外部12M晶振(注意是晶振,不是外部振荡器,一定不要选择错了,否则会导致单片机不能再烧写程序)。

4、程序代码

/***********************************************

****AVRA/D键盘范例***

****MCU:

ATmega16***

****作者:

maweili***

****编译器:

WINAVR***

*******

****2009.4.3***

***********************************************/

#include

#include

#include//中断函数头文件

//常量声明

#defineBAUD9600//波特率设置值

//全局变量声明

unsignedintADData;//AD转换获得的数据

//函数声明

voidPort_Init(void);//端口初始化配置

voidUsart_Init(void);//USART寄存器设置

voidAD_Init(void);//AD初始化

voidUsart_PutChar(unsignedcharcTXData);//字节发送函数

voidUsart_PutString(unsignedchar*pcString);//字符串发送数据

unsignedintAD_GetData(void);//AD转换函数

voidGetKey(void);//显示按键值

intmain(void)

{

unsignedcharDelay3s;

Port_Init();

Usart_Init();

AD_Init();

Usart_PutString("AD键盘测试程序");

//Usart_PutString("你按下的按键序号为:

");

sei();//使能全局中断

while

(1)

{

ADData=AD_GetData();//获得的AD值

if(ADData>5)//判断是否有按键按下

{

_delay_ms(50);//按键消抖

if(ADData>5)

{

GetKey();//获取按键值

}

_delay_ms(200);

}

for(Delay3s=0;Delay3s<10;Delay3s++)//延时3S

{

_delay_ms(90);

}

}

}

//端口状态初始化设置函数

voidPort_Init()

{

PORTA=0X00;

DDRA=0x00;//ADC通道设置为输入口,高阻态

}

//USART寄存器配置函数

voidUsart_Init()

{

UCSRA=0X00;

UCSRC|=(1<

//UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,写UCSRC时,URSEL应设置为1。

UBRRL=(F_CPU/BAUD/16-1)%256;//波特率设置

UBRRH=(F_CPU/BAUD/16-1)/256;

UCSRB|=(1<

}

//字节发送函数

voidUsart_PutChar(unsignedcharcTXData)

{

while(!

(UCSRA&(1<

UDR=cTXData;//发送数据送USARTI/O数据寄存器-UDR

}

//接收中断函数

ISR(USART_RXC_vect)

{

unsignedcharRev;

Rev=UDR;//从USARTI/O数据寄存器-UDR中读出数据

Usart_PutChar(Rev);//将接收到的数据发送

}

 

voidUsart_PutString(unsignedchar*pcString)

{

while(*pcString)

{

Usart_PutChar(*pcString++);

}

Usart_PutChar(0x0D);

Usart_PutChar(0x0A);//结尾发送回车换行

}

//AD转换初始化函数

voidAD_Init()

{

ADMUX|=(1<

//ADC参考电压为AVcc,ADC结果左对齐,选择通道ADC1

ADCSRA|=(1<

}

//AD转换函数

unsignedintAD_GetData()

{

ADCSRA|=(1<

while(!

(ADCSRA&(1<

ADCSRA|=(1<

returnADCH;//返回ADCH值,只取高8位

}

voidGetKey(void)

{

if((ADData>226)&&(ADData<234))

{

Usart_PutString("你按下的按键序号为:

");

Usart_PutChar(0x31);

Usart_PutChar(0x0d);//

Usart_PutChar(0x0a);//AD值发送结束,回车换行

_delay_ms(200);

}

elseif((ADData>186)&&(ADData<194))

{

Usart_PutString("你按下的按键序号为:

");

Usart_PutChar(0x32);

Usart_PutChar(0x0d);//

Usart_PutChar(0x0a);//AD值发送结束,回车换行

_delay_ms(200);

}

elseif((ADData>157)&&(ADData<165))

{

Usart_PutString("你按下的按键序号为:

");

Usart_PutChar(0x33);

Usart_PutChar(0x0d);//

Usart_PutChar(0x0a);//AD值发送结束,回车换行

_delay_ms(200);

}

elseif((ADData>135)&&(ADData<143))

{

Usart_PutString("你按下的按键序号为:

");

Usart_PutChar(0x34);

Usart_PutChar(0x0d);//

Usart_PutChar(0x0a);//AD值发送结束,回车换行

_delay_ms(200);

}

elseif((ADData>117)&&(ADData<125))

{

Usart_PutString("你按下的按键序号为:

");

Usart_PutChar(0x35);

Usart_PutChar(0x0d);//

Usart_Put

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1