需要确认注册邮箱后才能开通博客,立即确认我的邮箱
文章 搜索 高级搜索 ?3? ?3?
  • 滤波器new!
  • LED驱动 new!
  • 新能源 new!
  • PLL
  • PCIE协议
  • 可穿戴
  • LSI
  • FCI
文章 论坛 博客 小组 研讨会
EDN China>EDN论坛>单片机专区>【ATMEGA16L】实验三十:ADC实验
?
大家在做什么...
楼主 问题:

【ATMEGA16L】实验三十:ADC实验

发布时间:2009-3-25 上午1:12

作者: 林夕依然

等级: 资深技术总监

积分: 5388分

发帖数: 100次

网站总积分: 10765分

588分

发送消息

加为好友

查看用户的所有发言

查看用户的个人主页

需要确认注册邮箱后才能下载,立即确认我的邮箱
回复后可下载附件
??????? 今天对ADC模块进行了深入学习和实践验证,对ATMEGA16L的2.56V片内基准电压源存在疑问:为什么实际测得值是2.633V,误差似乎太大了,并且以此做为基准时,ADC转换结果不稳定,有较大波动。因此,我推断ATMEGA16L的2.56V片内基准电压源有较大跳变,并因此导致ADC转换结果有较大波动一、硬件电路:

二、程序结构:

三、程序源代码
1、main.c
/*******************************************************************************
Platform: AVR mega16学习板(www.iccavr.com
Project : 实验三十:ADC实验
Clock F : 3.6864MHz
Software: ICCAVR7.14C
Author? : 林夕依然
Version : 09.03.24
Updata? :
comments:
1、串口发送命令开启一次ADC,并将结果通过串口发送到PC,任意字符开始;
2、USART使用中断方式接收数据,当接收到数据后,开启一次ADC转换;
3、当ADC转换完成后产生中断,并置一个自定义的标志;
4、对ADC转换完成后的中断标志进行检测,为1时则将ADC转换数据发送给PC;
5、采用单通道AVCC外部参考源和2.56V 的片内基准电压源两种方式;
5、参考:D:\mcu\ICCAVR学习板\旧版例程\7-ADC
problem :
1、2.56V 的片内基准电压源实测值在ADC0/ADC1通道时均为2.633V,误差较大,
?? 可能是造成ADC转换电压不稳定的主要原因。
*******************************************************************************/
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
uchar AdcData;?????????????????????? //ADC转换的结果
uchar AdcConCom = 0;???? //ADC转换完成标志
/*-----------------------------------------------------------------
函数名称: void AdcInit(void)
函数功能: ADC初始化
参??? 数:
返 回 值: 无
-----------------------------------------------------------------*/
void AdcInit(void)
{
?ADCSR = 0x00;? //ADC关闭
?ADMUX = 0x67;? //外部参考源AVCC,左对齐,选择ADC7通道
?//ADMUX = 0xE0;? //2.56V 的片内基准电压源,左对齐,选择ADC0通道
?//ADMUX = 0xE1;? //2.56V 的片内基准电压源,左对齐,选择ADC1通道
?ACSR =? 0x80;? //模拟比较器控制和状态寄存器ACSR的ACD置1,使模拟比较器禁用
?ADCSR = 0x8B;? //开启ADC,8分频,ADC中断使能
}
/*-----------------------ADC转换中断程序--------------------------------------*/
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
?AdcData= ADCH; //读ADC转换结果,只读高8位,即8位精度,此种情况Vin=(AVCC/256)*ADC?
?AdcConCom = 1; //置ADC转换完成标志
}
/*-----------------------------------------------------------------
函数名称: void InitDevices(void)
函数功能: 初始化各种信息
参??? 数:
返 回 值: 无
-----------------------------------------------------------------*/
void InitDevices(void)
{
??CLI(); ???? ?????//关全部中断
??Usart_init03();???????????????????? //中断方式初始化
?AdcInit();
??MCUCR = 0x00;
??SEI();?? ? ??? ?????//开全中断
}
void main(void)
{
?InitDevices();
??while(1)
?{
? ?if(AdcConCom)
??{
?? ?AdcConCom = 0;????//清ADC转换完成标志
???USART_Transmit(AdcData);???//发送转换结果
??}
?}
}
/************************模拟比较器控制和状态寄存器ACSR************************
ACD??? 模拟比较起禁用
ACBG?? 模拟比较器的能隙基准源
ACO??? 模拟比较起输出
ACI??? 模拟比较器中断标志
ACIE?? 模拟比较器中断使能
ACIC?? 模拟比较器输入捕捉使能
ACIS1? 模拟比较器中断模式选择
ACIS0
*******************************************************************************/
/*************************ADC控制和状态寄存器A-ADCSRA**************************
???????????? ADEN?? ADSC? ADATE?? ADIF?? ADIE? ADPS2? ADPS1? ADPS0
?ADEN????? ADC使能模数转换
?ADSC????? ADC开始转换
?ADATE???? ADC自动触发使能
?ADIF????? ADC 中断标志
?ADIE????? ADC中断使能
?ADPS2???? ADC 预分频器选择位
?ADPS1
?ADPS0
?*****************************************************************************/
/***********************************测试*************************************
1、ADMUX = 0x67;? //外部参考源AVCC,左对齐,选择ADC7通道
?? AdcData= ADCH; //读ADC转换结果,只读高8位,即8位精度,此种情况Vin=(AVCC/256)*AdcData
?? 1)将RW2分得电压为3.92V接在ADC7上,用万用表测得AVCC=5.02V
????? 用串口助手接收AdcData的值为C7(图1),即十进制199,经计算:Vin=5.02/256*199=3.902265625V
????? 据此可验证串口助手接收到的数据是准确的。
?? 2)将RW2分得电压为4.71V接在ADC7上,用万用表测得AVCC=5.02V
????? 用串口助手接收AdcData的值为F0(图2),即十进制240,经计算:Vin=5.02/256*240=4.70625V
????? 据此可验证串口助手接收到的数据是准确的。
??
2、ADMUX = 0xE1;? //2.56V 的片内基准电压源,左对齐,选择ADC1通道
?? AdcData= ADCH; //读ADC转换结果,只读高8位,即8位精度,此种情况Vin=(AREF/256)*AdcData
?? 1)将RW2分得电压为1.008V接在ADC1上,用万用表测得AREF=2.633V,并非手册上的2.56V,有较大偏差
????? 用串口助手接收AdcData的值不确定(图3),而由:1.008=2.633/256*AdcData计算得AdcData=98,即二进制62才对
?? 2)将通道换为ADC0,现象同上。
????? 据上可推知,有可能ATMEGA16L内部基准电压误差太大。
*****************************************************************************/
2、function.c
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define F_CPU 3686400
/*-----------------------------------------------------------------
函数名称: void Usart_init01(void)
函数功能: 串口初始化方式01(波特率设置用查表)
??? 波特率 9600 0.2% ,8bit,异步,倍速,无奇偶校验,1个停止位
参??? 数:
返 回 值: 无
-----------------------------------------------------------------*/
void Usart_init01(void)?????? //初始化串口方式1
{
? UCSRA="0X02";???????????????? //倍速选择
? UCSRB=(1<<RXEN)|(1<<TXEN);? //使能接收,发送
? UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8bit,异步,无奇偶校验,1个停止位
? UBRR="47"; //9600波特率,见M16_cn中文P155:Table68-72通用振荡器频率下设置 UBRR ???????????????????
}
/*-----------------------------------------------------------------
函数名称: void Usart_init02(void)
函数功能: 串口初始化方式02(波特率设置用公式)
??? 波特率 9600 0.2% 8bit,异步,常速,无奇偶校验,2个停止位
参??? 数:
返 回 值: 无
-----------------------------------------------------------------*/
void Usart_init02( unsigned int baud )//初始化串口方式2,并设置波特率
{
unsigned int tmp;
tmp= F_CPU/baud/16-1;??????? //设置波特率,见M16_cn中文P135:Table60波特率计算公式
UBRRH = (unsigned char)(tmp>>8);
UBRRL = (unsigned char)tmp;
UCSRB = (1<<RXEN)|(1<<TXEN); //接收器与发送器使能
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ0)|(1<<UCSZ1);//异步,8bit,2停止位,无奇偶校验
}
/*-----------------------------------------------------------------
函数名称: void Usart_init03(void)
函数功能: 串口初始化方式03(中断方式接收)
??? 波特率 9600 0.2%,8bit,异步,倍速,无奇偶校验,1个停止位
参??? 数:
返 回 值: 无
-----------------------------------------------------------------*/
void Usart_init03(void)
{
??UCSRB = 0x00; ??????????? //关串口
??UCSRA = 0x02;??????????? //倍速模式?? M16中文P151
??UCSRC = BIT(URSEL) | 0x06;???????? //写UCSRC寄存器,设定8个bit,1停止位,异步
??UBRR? = 47;? ?? ??? ???????????? //设定串口波特率为9600
??UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//使能接收结束中断,使能收发
}
#pragma interrupt_handler UartRecvData:12
void UartRecvData(void)
{
??uchar temp;
?temp = UDR;
?ADMUX |= (1<<MUX2)|(1<<MUX1)|(1<<MUX0); //选择ADC7通道
?ADCSRA|= (1<<ADSC);??? ?? ?????? //开启一次ADC转换
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmit( unsigned char data )
函数功能: 数据发送【发送5 到8 位数据位的帧】
参??? 数:
返 回 值: 无
说??? 明:直接从数据手册上拷贝过来的
-----------------------------------------------------------------*/
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) ) ;? //等待发送缓冲器为空
UDR = data;??????????????????????? // 将数据放入缓冲器,发送数据
}
/*-----------------------------------------------------------------
函数名称: unsigned char USART_Receive( void )
函数功能: 数据接收【以5 到8 个数据位的方式接收数 据帧】
参??? 数:
返 回 值: UDR
说??? 明:直接从数据手册上拷贝过来的
-----------------------------------------------------------------*/
unsigned char USART_Receive( void )
{
while ( !(UCSRA & (1<<RXC)) );? // 等待接收数据
return UDR;???????????????????? // 从缓冲器中获取并返回数据
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmits01( void )
函数功能: 连续发送字符"Hello"
参??? 数:
返 回 值:
-----------------------------------------------------------------*/
void USART_Transmits01( void )
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'H';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'e';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'l';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'l';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'o';
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmits02(unsigned char *ptr)
函数功能: 字符串的操作
参??? 数:
返 回 值:
说??? 明:未能过验证
-----------------------------------------------------------------*/
void USART_Transmits02(unsigned char *ptr)//字符串
{
?? while (*ptr)
?? {
?????? USART_Transmit(*ptr);
?????? *ptr++;
?? }
?? newline();
}
void newline()?? //换行
{
?? USART_Transmit(0x0d);? //发送一个回车
?? USART_Transmit(0x0a);? //发送一个换行
}
void blank()??? //空格
{
?? USART_Transmit(0x20);?
}

/************************************************
? UMSEL? 模式选择
??? 0??? 异步操作
??? 1??? 同步操作
? USBS 停止位位数
??? 0???? 1
??? 1???? 2
? UCSZ2 UCSZ1 UCSZ0 字符长度
??? 0???? 0???? 0???? 5 位
??? 0???? 0???? 1???? 6 位
??? 0???? 1???? 0???? 7 位
??? 0???? 1???? 1???? 8 位
??? 1???? 0???? 0???? 保留
??? 1???? 0???? 1???? 保留
??? 1???? 1???? 0???? 保留
??? 1???? 1???? 1???? 9 位
*************************************************/
四、附图
图1:

图2:

图3:

点此进入:AVR单片机小组
??????? AVR单片机小组,以ICCAVR为编译平台,以资源共享、经验交流为主旨,以共同进步和提高为目标。期待志同道合的朋友加入!
【相关实验】
实验一:流水灯实验(八种LED点亮模式)
实验二:有源蜂鸣器驱动实验
实验三:按键扫描(用KEY选择对应LED点亮)
实验四:键盘扫描+8种LED亮灭模式控制
实验二四:四线制LCD1602B驱动实验????????
实验二五:八线制LCD1602B驱动实验
实验二八:USART综合实验
实验二九:模拟比较器实验
分享到:? 新浪微博 ?? 微信 ??


打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮

1.扫描左侧二维码
2.点击右上角的分享按钮
3.选择分享给朋友
qq空间 ?? 腾讯微博 ?? 人人网 ?? 百度搜藏 ??
引用 回复 收藏 推荐到小组 ( 0) ( 0) 关注

EDN China电子设计技术揭秘氮化镓(GaN)在无线基站中的应用(下)
第1楼

谢谢分享!给你加精!

发布时间:2009-3-25 上午8:00

作者: 小可哥

等级: 皇家级工程师

积分: 12514分

发帖数: 1368次

网站总积分: 24279分

3265分

发送消息

加为好友

查看用户的所有发言

查看用户的个人主页

需要确认注册邮箱后才能下载,立即确认我的邮箱
回复后可下载附件
谢谢分享!给你加精!
引用 回复
( 0) ( 0)


EDN China电子设计技术揭秘氮化镓(GaN)在无线基站中的应用(上)
第2楼 好贴,顶一下 发布时间:2009-3-26 下午5:13

作者: 1231481801020

等级: 初学者

积分: 51分

发帖数: 1次

网站总积分: 102分

51分

发送消息

加为好友

查看用户的所有发言

查看用户的个人主页

需要确认注册邮箱后才能下载,立即确认我的邮箱
回复后可下载附件
好贴,顶一下
引用 回复
( 0) ( 0)


快速回复 高级回复
用户名:?
美国的游客?????? (您将以游客身份发表,请登陆 | 注册) ?
标题: * 标题还可以输入80
评论: * 你还可以输入30000
验证码: ?*?
分享: 新浪微博?? qq空间?? qq微博?? 人人网?? 百度搜藏??
维护专业、整洁的论坛环境需要您的参与,请及时举报违规帖子,如果举报属实,我们将给予相应的积分奖励。
谢谢您的热心参与!
返回单片机 | 返回专业技术交流区
本论坛仅陈述专家或个人观点,并不代表EDN China 电子技术设计互动社区网站立场。
积分排行榜
彩云 [殿堂级工程师]
mzlr [殿堂级工程师]
特权同学 [殿堂级工程师]
敬请关注EDNC官方微信“edn-china"

每月定期向您递送电子元器件规格书网中的最新元器件数据手册下载、库存信息及技术参数更新。请点击订阅:

2016我的工程师社区
EDN官方QQ群???更多QQ群
  • EDN-深圳 8366025
  • 菜农Cortex-M0技术交流 12047788
  • EDN-哈尔滨 75642591
  • EDN-上海 15156661
  • EDN-广州 57660943
  • EDN-桂林 48813559
  • EDN-武汉 25150805
  • EDN-模拟电路 2837145
  • EDN-通讯 30548292
  • EDN-综合 57490949

促进EDN网友交流合作,方便EDN网友学习沟通

有问题请反馈