接自制模型遥控器8CH(5)---kalrry
*****自制模型遥控器8CH文档下载地址:http://yunpan.cn/cZMPq2iRS9LtM 访问密码 03d3
五、10分钟学会ADC
首先大家一定要知道ADC到底是干什么的。如果还有人不知道ADC是干什么的,请翻回我的教程的单片机基本概念的章节,对ADC是干什么的有比较仔细的描述。
在遥控器程序中,操纵ADC是一个比较重要的环节,所有比例通道的摇杆所在的位置,均是由ADC检测电压来得到的。我们都知道,遥控器的比例通道实际上就是摇杆控制旋转电位器的位置来实现的。遥控器所用的旋转电位器有三只脚,左面和右面的脚的阻值是一个定值,中间的脚与左面的脚(或右面的脚)的阻值随着电位器的位置而变化,因此,如果两边的脚分别接GND和VCC,则中间的脚的电压会随着电位器的位置变化而改变,然后通过ADC转换成数字信号,单片机就知道现在摇杆所在的位置了。
本想再照两张实例图的,但相机被别人拿走了,手机照相效果太差。只有等春节后别人还给我再补上了。
要熟练操作Atmega8单片机的ADC,要熟悉四个寄存器:
ADMUX、ADCSRA、ADCL及ADCH。让我们依次来了解它们。
ADC 多工选择寄存器- ADMUX
ADMUX寄存器依次从高到底位如下:
第7位第6位第5位第4位第3位第2位第1位第0位
REFS1 REFS0 ADLAR – MUX3 MUX2 MUX1 MUX0
REFS1:0: 参考电压选择,通过这几位可以选择参考电压。如果在单片机的AREF 引脚上施加了外部参考电压,内部参考电压就不能被选用了。不知道什么是ADC参考电压的,请翻回我的教程的单片机基本概念的章节。
REFS1 REFS0 参考电压选择
0 0 AREF脚施加的电压
0 1 AVCC
1 0 保留
1 1 2.56V的片内基准电压源,需要在AREF 引脚外加滤波电容
第5位ADLAR影响ADC转换结果在ADC数据寄存器中的存放形式。ADLAR置位(设置为1)时转换结果为左对齐,否则为右对齐。一般情况下,我们不去动ADLAR的值,直接使用右对齐的方式,也是我们习惯的方式。
MUX3:0: 模拟通道选择位
ATMEGA8单片机一共有8个ADC输入引脚,但它每次只能处理一个ADC引脚,具体处理哪一个引脚,就由MUX3:0这四位来确定。
MUX3..0 单端输入
0000 ADC0
0001 ADC1
0010 ADC2
0011 ADC3
0100 ADC4
0101 ADC5
0110 ADC6
0111 ADC7
ADC 控制和状态寄存器A - ADCSRA
ADCSRA寄存器依次从高到底位如下:
第7位第6位第5位第4位第3位第2位第1位第0位
ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
• 第7位ADEN: 启动ADC
ADEN置位即启动ADC,否则ADC功能关闭。
• 第6位ADSC: ADC开始转换
在单次转换模式下,ADSC 置位将启动一次ADC 转换。在连续转换模式下,ADSC 置位将启动首次转换。
•第5位ADFR: ADC 连续转换选择
该位置位时,运行在连续转换模式。该模式下,ADC 不断对数据寄存器ADCH和ADCL进行采样与更新。该位清零,终止连续转换模式。
•第4位ADIF: ADC中断标志
•第3位ADIE: ADC 中断使能
若ADIE 及SREG 的位I 置位, ADC 转换结束中断即发生ADC中断。
•ADPS2:0: ADC 预分频器选择位
由这几位来确定XTAL 与ADC 输入时钟之间的分频因子。一般情况下我们可以不去动这个参数。
数据寄存器ADCH和ADCL
ADC 转换结束后,转换结果存于这两个寄存器之中。ADCL中为低8位,ADCH中为高两位(10位ADC),读取ADCL 之后,ADC 数据寄存器一直要等到ADCH 也被读出才可以进行数据更新。必须先读出ADCL 再读ADCH。
我们可以采取如下语句来读写和合并ADCH和ADCL中的数据:
l=ADCL;
h=ADCH;
h<<=8;
h|=l;
注意其中的l和h均需为int型变量,最后的ADC数据存在h中。
ADC的寄存器的功能讲完了,让我们看看如下的程序示例:
void adc_init(void)
{
DDRC = DDRC &0x0f; //设置引脚PC4,5,6,7为输入引脚
PORTC = PORTC &0x0f; //关闭引脚PC4,5,6,7上拉电阻。
ADCSRA = 0x00; //关闭ADC
ADMUX = 0x44; //选择AVCC为参考电压,输入引脚选择为ADC4(引脚PC4)
ACSR=1<<ACD; //关闭模拟比较器
ADCSRA = 0x84; // 启动ADC,单次,16分频
}
unsigned int adc_read(unsigned char ADCChannel)
{
unsigned int data,h,l;
unsigned char i;
unsigned long int p;
ADMUX = (ADMUX &0xf0)+(ADCChannel & 0x0f); //将选取的通道值设置进ADMUX中
for (i=0;i<4;i++) //连续测量4次取平均值
{
ADCSRA|=0x40; //开始转换
while((ADCSRA&0x10)==0); //等待转换结束
ADCSRA|=0x10; //清标志位
l=ADCL; //读取ADCL值
h=ADCH; //读取ADCH值
h<<=8; //后面两句为合并数据值
h|=l;
data+=h; //求4次测量数据的总和
}
data/=4; //除以4得出4次测量平均值
return data;
}
程序adc_init是一个比较典型的ADC初始化程序,在ADC初始化中,一般先设置要使用ADC的几个引脚为输入引脚,并关闭其上拉电阻。然后关闭ADC,关闭模拟比较器,选择参考电压和输入引脚,最后设置启动ADC的基本参数。
程序adc_read则是一个比较典型的读取ADC的程序。它有一个输入参数,即当前要读取哪一个ADC通道。其返回的值即为读取的ADC数值。为增加数据的稳定性,我们对同一个通道读取4次取平均值。当然,这不是必须的。
有了这两个程序,就可以编制读写ADC的程序了。为了增加实际可操作性,我们下面将给出一个读取ADC值并在LCD1602液晶下显示的一个示例程序。这个程序将用到LCD1602显示相关的文件,我们把它打包在lcd1602.h和lcd1602.c两个文件中,构成lcd1602的驱动。Lcd1602的驱动程序较为复杂,如果大家有兴趣,我在最后可以予以讲解,现在暂时只需了解该驱动程序有哪些函数可以直接用就行了。本示例程序给出的lcd1602驱动程序是基于硬件接线为4位数据线驱动方式,只适用于atmega8。其硬件接线如下图所示:

今天让我们来学习一个读取ADC值并在LCD1602液晶下显示的一个示例程序。LCD1602的接线法如上节课的图所示。电位器的接法是两个固定端一端接VCC,一端接地,可变端接ADC6(PC6)。
LCD1602的驱动程序打包在lcd1602.h和lcd1602.c两个文件中,我先介绍一下可以直接用的主要函数。
void lcd_init(void) //以四位数据线(四线制)方式初始化lcd1602
SetCursor(y, x) //将当前光标设置到Y行X字符处
void lcd_data(unsigned chartemp1) //向当前的光标处写入一个字符
void lcd_string(char *data) //向当前的光标处写入一个字符串
void lcd_clear(void) //清除lcd1602的所有显示内容
下面我们看看具体的程序:
#include "Lcd1602.c"
#include "adc.c"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
void adc_display(void)
{
unsigned int a[4];
unsigned char i;
unsigned int r;
adc_init(); //初始化ADC
while (1)
{
_delay_ms(300); //每次采集间隔300ms
SetCursor(1,1); //光标定位在第1行第1字符
r=adc_read(6); //读取ADC6
a[0]=r/1000; //下面把读取的ADC6按四位数转化成字符,并显示在LCD1602上
a[1]=(r%1000)/100;
a[2]=(r%100)/10;
a[3]=r%10;
for(i=0;i<4;i++)
{
lcd_data(a+0x30); //1+0x30=0x31,等于字符“1”的值,2+0x30=0x32,等于字符“2”的值,依次类推。
}
}
}
int main(void)
{
lcd_init(); // 初始化lcd1602
SetCursor(1,2); //下面四条语句为显示欢迎词,同时也验证lcd1602显示正常
lcd_string("Good Morning");
SetCursor(2,3);
lcd_string("Nice day!");
_delay_ms(1000); //延时1秒
lcd_clear(); //清屏
adc_display(); //循环显示ADC采集值。
}
头文件ADC.C中只有我们在上一节课讲过的两个函数,即adc_init和adc_read。所有的文件我均打包在ADC.rar 文件中,在AVR Studio 4中编译通过。
源程序打包http://yunpan.cn/cZMJr4v3gGiRW 访问密码 fbae
接自制模型遥控器8CH(7)---kalrry
*****自制模型遥控器8CH文档下载地址:http://yunpan.cn/cZMPq2iRS9LtM 访问密码 03d3
五、10分钟学会ADC
首先大家一定要知道ADC到底是干什么的。如果还有人不知道ADC是干什么的,请翻回我的教程的单片机基本概念的章节,对ADC是干什么的有比较仔细的描述。
在遥控器程序中,操纵ADC是一个比较重要的环节,所有比例通道的摇杆所在的位置,均是由ADC检测电压来得到的。我们都知道,遥控器的比例通道实际上就是摇杆控制旋转电位器的位置来实现的。遥控器所用的旋转电位器有三只脚,左面和右面的脚的阻值是一个定值,中间的脚与左面的脚(或右面的脚)的阻值随着电位器的位置而变化,因此,如果两边的脚分别接GND和VCC,则中间的脚的电压会随着电位器的位置变化而改变,然后通过ADC转换成数字信号,单片机就知道现在摇杆所在的位置了。
本想再照两张实例图的,但相机被别人拿走了,手机照相效果太差。只有等春节后别人还给我再补上了。
要熟练操作Atmega8单片机的ADC,要熟悉四个寄存器:
ADMUX、ADCSRA、ADCL及ADCH。让我们依次来了解它们。
ADC 多工选择寄存器- ADMUX
ADMUX寄存器依次从高到底位如下:
第7位第6位第5位第4位第3位第2位第1位第0位
REFS1 REFS0 ADLAR – MUX3 MUX2 MUX1 MUX0
REFS1:0: 参考电压选择,通过这几位可以选择参考电压。如果在单片机的AREF 引脚上施加了外部参考电压,内部参考电压就不能被选用了。不知道什么是ADC参考电压的,请翻回我的教程的单片机基本概念的章节。
REFS1 REFS0 参考电压选择
0 0 AREF脚施加的电压
0 1 AVCC
1 0 保留
1 1 2.56V的片内基准电压源,需要在AREF 引脚外加滤波电容
第5位ADLAR影响ADC转换结果在ADC数据寄存器中的存放形式。ADLAR置位(设置为1)时转换结果为左对齐,否则为右对齐。一般情况下,我们不去动ADLAR的值,直接使用右对齐的方式,也是我们习惯的方式。
MUX3:0: 模拟通道选择位
ATMEGA8单片机一共有8个ADC输入引脚,但它每次只能处理一个ADC引脚,具体处理哪一个引脚,就由MUX3:0这四位来确定。
MUX3..0 单端输入
0000 ADC0
0001 ADC1
0010 ADC2
0011 ADC3
0100 ADC4
0101 ADC5
0110 ADC6
0111 ADC7
ADC 控制和状态寄存器A - ADCSRA
ADCSRA寄存器依次从高到底位如下:
第7位第6位第5位第4位第3位第2位第1位第0位
ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
• 第7位ADEN: 启动ADC
ADEN置位即启动ADC,否则ADC功能关闭。
• 第6位ADSC: ADC开始转换
在单次转换模式下,ADSC 置位将启动一次ADC 转换。在连续转换模式下,ADSC 置位将启动首次转换。
•第5位ADFR: ADC 连续转换选择
该位置位时,运行在连续转换模式。该模式下,ADC 不断对数据寄存器ADCH和ADCL进行采样与更新。该位清零,终止连续转换模式。
•第4位ADIF: ADC中断标志
•第3位ADIE: ADC 中断使能
若ADIE 及SREG 的位I 置位, ADC 转换结束中断即发生ADC中断。
•ADPS2:0: ADC 预分频器选择位
由这几位来确定XTAL 与ADC 输入时钟之间的分频因子。一般情况下我们可以不去动这个参数。
数据寄存器ADCH和ADCL
ADC 转换结束后,转换结果存于这两个寄存器之中。ADCL中为低8位,ADCH中为高两位(10位ADC),读取ADCL 之后,ADC 数据寄存器一直要等到ADCH 也被读出才可以进行数据更新。必须先读出ADCL 再读ADCH。
我们可以采取如下语句来读写和合并ADCH和ADCL中的数据:
l=ADCL;
h=ADCH;
h<<=8;
h|=l;
注意其中的l和h均需为int型变量,最后的ADC数据存在h中。
ADC的寄存器的功能讲完了,让我们看看如下的程序示例:
void adc_init(void)
{
DDRC = DDRC &0x0f; //设置引脚PC4,5,6,7为输入引脚
PORTC = PORTC &0x0f; //关闭引脚PC4,5,6,7上拉电阻。
ADCSRA = 0x00; //关闭ADC
ADMUX = 0x44; //选择AVCC为参考电压,输入引脚选择为ADC4(引脚PC4)
ACSR=1<<ACD; //关闭模拟比较器
ADCSRA = 0x84; // 启动ADC,单次,16分频
}
unsigned int adc_read(unsigned char ADCChannel)
{
unsigned int data,h,l;
unsigned char i;
unsigned long int p;
ADMUX = (ADMUX &0xf0)+(ADCChannel & 0x0f); //将选取的通道值设置进ADMUX中
for (i=0;i<4;i++) //连续测量4次取平均值
{
ADCSRA|=0x40; //开始转换
while((ADCSRA&0x10)==0); //等待转换结束
ADCSRA|=0x10; //清标志位
l=ADCL; //读取ADCL值
h=ADCH; //读取ADCH值
h<<=8; //后面两句为合并数据值
h|=l;
data+=h; //求4次测量数据的总和
}
data/=4; //除以4得出4次测量平均值
return data;
}
程序adc_init是一个比较典型的ADC初始化程序,在ADC初始化中,一般先设置要使用ADC的几个引脚为输入引脚,并关闭其上拉电阻。然后关闭ADC,关闭模拟比较器,选择参考电压和输入引脚,最后设置启动ADC的基本参数。
程序adc_read则是一个比较典型的读取ADC的程序。它有一个输入参数,即当前要读取哪一个ADC通道。其返回的值即为读取的ADC数值。为增加数据的稳定性,我们对同一个通道读取4次取平均值。当然,这不是必须的。
有了这两个程序,就可以编制读写ADC的程序了。为了增加实际可操作性,我们下面将给出一个读取ADC值并在LCD1602液晶下显示的一个示例程序。这个程序将用到LCD1602显示相关的文件,我们把它打包在lcd1602.h和lcd1602.c两个文件中,构成lcd1602的驱动。Lcd1602的驱动程序较为复杂,如果大家有兴趣,我在最后可以予以讲解,现在暂时只需了解该驱动程序有哪些函数可以直接用就行了。本示例程序给出的lcd1602驱动程序是基于硬件接线为4位数据线驱动方式,只适用于atmega8。其硬件接线如下图所示:

今天让我们来学习一个读取ADC值并在LCD1602液晶下显示的一个示例程序。LCD1602的接线法如上节课的图所示。电位器的接法是两个固定端一端接VCC,一端接地,可变端接ADC6(PC6)。
LCD1602的驱动程序打包在lcd1602.h和lcd1602.c两个文件中,我先介绍一下可以直接用的主要函数。
void lcd_init(void) //以四位数据线(四线制)方式初始化lcd1602
SetCursor(y, x) //将当前光标设置到Y行X字符处
void lcd_data(unsigned chartemp1) //向当前的光标处写入一个字符
void lcd_string(char *data) //向当前的光标处写入一个字符串
void lcd_clear(void) //清除lcd1602的所有显示内容
下面我们看看具体的程序:
#include "Lcd1602.c"
#include "adc.c"
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
void adc_display(void)
{
unsigned int a[4];
unsigned char i;
unsigned int r;
adc_init(); //初始化ADC
while (1)
{
_delay_ms(300); //每次采集间隔300ms
SetCursor(1,1); //光标定位在第1行第1字符
r=adc_read(6); //读取ADC6
a[0]=r/1000; //下面把读取的ADC6按四位数转化成字符,并显示在LCD1602上
a[1]=(r%1000)/100;
a[2]=(r%100)/10;
a[3]=r%10;
for(i=0;i<4;i++)
{
lcd_data(a+0x30); //1+0x30=0x31,等于字符“1”的值,2+0x30=0x32,等于字符“2”的值,依次类推。
}
}
}
int main(void)
{
lcd_init(); // 初始化lcd1602
SetCursor(1,2); //下面四条语句为显示欢迎词,同时也验证lcd1602显示正常
lcd_string("Good Morning");
SetCursor(2,3);
lcd_string("Nice day!");
_delay_ms(1000); //延时1秒
lcd_clear(); //清屏
adc_display(); //循环显示ADC采集值。
}
头文件ADC.C中只有我们在上一节课讲过的两个函数,即adc_init和adc_read。所有的文件我均打包在ADC.rar 文件中,在AVR Studio 4中编译通过。
源程序打包http://yunpan.cn/cZMJr4v3gGiRW 访问密码 fbae
接自制模型遥控器8CH(7)---kalrry