我是靠谱客的博主 粗暴蜗牛,最近开发中收集的这篇文章主要介绍AVR单片机模数转换的ADC实验 ATmega16,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

6.2 模数转换的ADC实验

  1. 10位精度;
  2. 0.5LSB积分非线形误差
  3. ±2LSB的绝对精度;
  4. 13µs~260µs的转换时间;
  5. 在最大精度下可达到每秒15kSPS的采样速率;
  6. 8路可选的单端输入通道;
  7. 7路差分输入通道;
  8. 2路差分输入通道带有可选的10×和200×增益;
  9. ADC转换结果的读取可设置为左端对齐(LEFT ADJUSTMENT);
  10. ADC的电压输入范围0~Vcc;
  11. 可选择的内部2.56V的ADC参考电压源;
  12. 自由连续转换模式和单次转换模式;
  13. ADC自动转换触发模式选择;
  14. ADC转换完成中断;
  15. 休眠模式下的噪声抑制器(NOISE CANCELER)。

在本实例中,我们将编写程序实现将模数转换后获得的电压值通过单片机的串口发送到计算机,然后通过计算机上的串口助手显示测量的电压值。
6.2.2、器件和原理

1、ATmega16单片机的模数转换器ADC介绍
2、ATmwga16单片机的模数转换器ADC相关的I/O寄存器

  1. 位7,6—REFS[1:0]:ADC参考电源选择

REFS1、REFS2用于选择ADC的参考电压源,见表6.2.1。如果这些位在ADC转换过程中被改变,新的选择将在该次ADC转换完成后(ADCSRA中的ADIF被置位)才生效。一旦选择内部参考源(AVcc、2.56V)为ADC的参考电压后,AREF引脚上不得施加外部的参考电源,只能与GND之间并接抗干扰电容。

 


REFS1

REFS0

ADC参考电源

0

0

外部引脚AREF,断开内部参考源连接

0

1

AVcc,AREF外部并接电容

1

0

保留

1

1

内部2.56V,AREF外部并接电容

  1. 位5—ADLAR:ADC结果左对齐选择

ADLAR位决定转换结果在ADC数据寄存器中的存放形式。写“1”到ADLAR位,将使转换结果左对齐(LEFT ADJUST);否则,转换结果为右对齐(RIGHT ADJUST)。无论ADC是否正在进行转换,改变ADLAR位都将会立即影响ADC数据寄存器。

  1. 位4..0—MUX4:0:模拟通道和增益选择

这5个位用于对连接到ADC的输入通道和差分通道的增益进行选择设置,详见表6.2.2。注意,只有转换结束后(ADCSRA的ADIF是“1”),改变这些位才会有效。


MUX[4:0]

单端输入

差分正极输入

差分负极输入

增益

00000

ADC0

N/A

00001

ADC1

00010

ADC2

00011

ADC3

00100

ADC4

00101

ADC5

00110

ADC6

00111

ADC7

01000

N/A

ADC0

ADC0

10×

01001

ADC1

ADC0

10×

01010

ADC0

ADC0

200×

01011

ADC1

ADC0

200×

01100

ADC2

ADC2

10×

01101

ADC3

ADC2

10×

01110

ADC2

ADC2

200×

01111

ADC3

ADC2

200×

10000

ADC0

ADC1

10001

ADC1

ADC1

10010

ADC2

ADC1

10011

ADC3

ADC1

10100

ADC4

ADC1

10101

ADC5

ADC1

10110

ADC6

ADC1

10111

ADC7

ADC1

11000

ADC0

ADC2

11001

ADC1

ADC2

11010

ADC2

ADC2

11011

ADC3

ADC2

11100

ADC4

ADC2

11101

ADC5

ADC2

11110

1.22V(VBG)

N/A

11111

0V(GND)

   本实例中我们需要设置ADC的参考电压源为AVcc,即REFS0设置为1,ADC默认转换结果为右对齐,我们不需要改变,模拟通道选择ADC0通道单端输入,即MUX4:0。

  1. 位7—ADEN:ADC使能

该位写入“1”时使能ADC,写入“0”关闭ADC。如在ADC转换过程中将ADC关闭,该次转换随即停止。

  1. 位6—ADSC:ADC转换开始

在单次转换模式下,置该位为“1”,将启动一次转换。在自由连续转换模式下,该位写入“1”将启动第一次转换。先置位ADEN位使能ADC,再置位ADSC;或置位ADSC的同时使能ADC,都会使能ADC开始进行第一次转换。第一次ADC转换将需要25个ADC时钟周期,而不是常规转换的13个ADC时钟周期,这是因为第一次转换需要完成对ADC的初始化。

  1. 位5—ADATE:ADC自动转换触发允许

当该位被置为“1”时,允许ADC工作在自动转换触发工作模式下。在该模式下,在触发信号的上升沿时ADC将自动开始一次ADC转换过程。ADC的自动转换触发信号源由SFIOR寄存器中的ADTS位选择确定。

  1. 位4—ADIF:ADC中断标志位

当ADC转换完成并且ADC数据寄存器被更新后该位被置位。如果ADIE位(ADC转换结束中断允许)和SREG寄存器中的I位被置“1”,ADC中断服务程序将被执行。ADIF在执行相应的中断处理向量时被硬件自动清零。此外,ADIF位可以通过写入逻辑“1”来清零。

  1. 位3—ADIE:ADC中断允许

当该位和SREG寄存器中的I位同时被置位时,允许ADC转换完成中断。

  1. 位2,0—ADPS[2:0]:ADC预分频选择

这些位决定了XTAL时钟与输入到ADC的ADC时钟之间分频数,见表6.2.3。

 

表6.2.3   ADC时钟分频

ADPS[2:0]

分  频  系  数

000

2

001

2

010

4

011

8

100

16

101

32

110

64

111

128

本实例中我们需要使能ADC,即ADEN设置为1,我们不用自动转换,也不需要中断,所以,ADTE、ADIE位不需要设置。在通常情况下,ADC的逐次比较转换电路要达到最大精度时,需要50kHz~200kHz之间的采样时钟。本例中使用的时钟是12M的,所以要将时钟64分频,分频后ADC频率为188KHz,即时钟分频选择ADPS[2:0]=6。

3.ADC数据寄存器—ADCL和ADCH

  1. ADLAR = 0,ADC转换结果右对齐时,ADC结果的保存方式

  1. ADLAR = 1,ADC转换结果左对齐时,ADC结果的保存方式


  1. 位7..5—ADTS[2:0]:ADC自动转换触发源选择

当ADCSRA寄存器中的ADATE为“1”,允许ADC工作在自动转换触发工作模式时,这3位的设置用于选择ADC的自动转换触发源。如果禁止了ADC的自动转换触发(ADATE为“0”),这3个位的设置值将不起任何作用。

 

表10-6   ADC自动转换触发源的选择

ADTS[2:0]

触  发  源

000

连续自由转换

001

模拟比较器

010

外部中断0

011

T/C0比较匹配

100

T/C0溢出

101

T/C1比较匹配B

110

T/C1溢出

111

T/C1输入捕捉

本例中我们不使用自动转换功能,所以该寄存器可以不必设置。
6.2.3、电路
1、电路原理
2、电路连接
是交叉串口线,而不是串口延长线。


2、 单片机与计算机串行通信结果的观察
3、函数说明
注意是晶振,不是外部振荡器,一定不要选择错了,否则会导致单片机不能再烧写程序)。

#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> //中断函数头文件

//常量声明 #define BAUD 9600 //波特率设置值

//全局变量声明 unsigned int ADData; //AD转换获得的数据

//函数声明 void Port_Init(void); //端口初始化配置 void Usart_Init(void); //USART寄存器设置 void AD_Init(void); //AD初始化 void Usart_PutChar(unsigned char cTXData); //字节发送函数 void Usart_PutString(unsigned char *pcString); // 字符串发送数据 unsigned int AD_GetData(void); //AD转换函数

int main(void) { unsigned char Delay3s;

Port_Init(); Usart_Init(); AD_Init(); Usart_PutString("AD转换测试程序"); Usart_PutString("测得ADC0通道的电压值为:"); sei(); //使能全局中断 while(1) { ADData = (int)((long)AD_GetData() * 5010 / 1024); //将获得的AD值转换为电压值 //单位为mv。 Usart_PutChar(ADData / 1000 + 0x30); //得到电压值的千位并发送 Usart_PutChar('.'); //发送小数点 Usart_PutChar(ADData % 1000 / 100 + 0x30); //得到电压值的百位并发送 Usart_PutChar(ADData % 100 / 10 + 0x30); //得到电压值的十位并发送 Usart_PutChar(ADData % 10 + 0x30); //得到电压值的个位并发送 Usart_PutChar('V'); //发送电压符号“V” Usart_PutChar(0x0d); // Usart_PutChar(0x0a); // AD值发送结束,回车换行 for(Delay3s = 0;Delay3s < 30;Delay3s++) //延时3S { _delay_ms(90); } } }

//端口状态初始化设置函数 void Port_Init() { PORTA = 0X00; DDRA = 0x00; //ADC通道设置为输入口,高阻态 }

//USART寄存器配置函数 void Usart_Init() { UCSRA = 0X00; UCSRC |= (1<<URSEL) | (1 << UCSZ1) | (1 << UCSZ0); //异步,数据格式8,N,1 //UCSRC寄存器与UBRRH寄存器共用相同的I/O地址,写 UCSRC 时, URSEL 应设置为 1。 UBRRL = (F_CPU / BAUD / 16 - 1) % 256; //波特率设置 UBRRH = (F_CPU / BAUD / 16 - 1) / 256; UCSRB |= (1 << RXCIE) | (1 << RXEN) | (1 << TXEN); //发送使能 }

//字节发送函数 void Usart_PutChar(unsigned char cTXData) { while( !(UCSRA & (1 << UDRE)) ); //只有数据寄存器为空时才能发送数据 UDR = cTXData; //发送数据送USART I/O数据寄存器-UDR }

//接收中断函数 ISR(USART_RXC_vect ) { unsigned char Rev; Rev = UDR; //从USART I/O数据寄存器-UDR中读出数据 Usart_PutChar(Rev); //将接收到的数据发送 }

void Usart_PutString(unsigned char *pcString) { while (*pcString) { Usart_PutChar(*pcString++); } Usart_PutChar(0x0D); Usart_PutChar(0x0A); //结尾发送回车换行 }

//AD转换初始化函数 void AD_Init() { ADMUX |= (1 << REFS0); //ADC参考电压为AVcc,ADC结果右对齐,选择通道ADC0 ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); //使能AD转换,ADC时钟64分频 }

//AD转换函数 unsigned int AD_GetData() { ADCSRA |= (1 << ADSC); //开始AD转换 while(!(ADCSRA & (1 << ADIF))); //等待转换完成 ADCSRA |= (1 << ADIF); //清零ADC中断标志位 return ADC; //返回ADC值 }

附录:ADC应用设计要点

1.预分频与转换时间

 


转 换 形 式

采样保持时间

完 成 转 换 总 时 间

启动ADC后的第一次转换

13.5个ADC时钟

25个ADC时钟

正常转换,单端输入

1.5个ADC时钟

13个ADC时钟

自动触发方式

2个ADC时钟

13.5个ADC时钟

正常转换,差分输入

1.5/2.5个ADC时钟

13/14个ADC时钟

当ADCSRA寄存器中的ADSC位置位,启动ADC转换时,A/D转换将在随后ADC时钟的上升沿开始。一次正常的A/D转换开始时,需要1.5个ADC时钟周期的采样保持时间(ADC首次启动后需要13.5个ADC时钟周期的采样保持时间)。当一次A/D转换完成后,转换结果写入ADC数据寄存器,ADIF(ADC中断标志位)将被置位。在单次转换模式下,ADSC也同时被清零。用户程序可以再次置位ADSC位,新的一次转换将在下一个ADC时钟的上升沿开始。

2.ADC输入通道和参考电源的选择

  1. 当要改变ADC输入通道时,应该遵守以下方式,以保证能够选择到正确的通道:

在单次转换模式下,总是在开始转换前改变通道设置。尽管输入通道改变发生在ADSC位被写入“1”后的1个ADC时钟周期内,然而,最简单的方法是等到转换完成后,再改变通道选择。

  1. ADC电压参考源

ADC的参考电压(VREF)决定了A/D转换的范围。如果单端通道的输入电压超过VREF,将导致转换结果接近于0x3FF。ADC的参考电压VREF可以选择为AVCC或芯片内部的2.56V参考源,或者为外接在AREF引脚上的参考电压源。

附录2、ADC应用设计的深入讨论

 

最后

以上就是粗暴蜗牛为你收集整理的AVR单片机模数转换的ADC实验 ATmega16的全部内容,希望文章能够帮你解决AVR单片机模数转换的ADC实验 ATmega16所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部