AVR 进行多通道AD转换的设计 例子 模型


AD中断采集完成后切换通道,这样AD触发用定时器触发或者连续采集模式都可以使用。

采样结果用一个数组存起来。
CODE:

//注意,得到的AD值并非实际的电压,而是0~1024(10)0~255(8)
#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
//conversion complete, read value (int)
#if AD_JINGDU ==10
  advalue=ADCL;        //Read 8 low bits first (important)
  advalue|=(int)ADCH << 8; //read 2 high bits and shift into top byte
#endif
#if AD_JINGDU ==8
  advalue = ADCH;
#endif
if(SET_ADC==3) SET_ADC=0; //这是多路采集的一个思路
SET_ADC++;
AD_done=1;  //转换完成标识位
}
[Copy to clipboard]
CODE:

//ICC-AVR application builder : 2007-7-25 10:40:22
// Target : M16
// Crystal: 7.3728Mhz
// 作者:古欣 AVR与虚拟仪器 [url]www.avrvi[/url]
// AD转换测试程序
#include "config.h"
volatile uint8 ADC_Value[]={0x00,0x00,0x00};

void main(void)
{
adc_init(SET_ADC); //启动ADADC0PA0)输入
DDRB = 0xff;

while(1)
{
if(AD_done==1) //AD转换完成标志位
{
AD_done=0;
advalue=(advalue*5000)/1024;//AVCC的实际测得电压乘以1000代替5000,结果转化成了mv,后面的1024取决于 #define AD_JINGDU 10,如果使用8位精度,则是256
ADC_Value[SET_ADC]=advalue; //SET_ADC02变化,采集三路电压值,存到 ADC_Value[0],ADC_Value[1],ADC_Value[2],具体的存放,你自己完成吧
//PORTB = advalue; //AD采样结果将在中断中存入advalue
//show(ADget_vol();) //显示浮点的实际电压值
}

}
}
[Copy to clipboard]

16进制字符串转16进制数组




压缩包中附一个AD转换测试程序,在硬件上测试通过。
CODE:

//ICC-AVR application builder : 2007-7-25 10:40:22
// Target : M16
// Crystal: 7.3728Mhz

#include <iom16v.h>
#include <macros.h>

#define AD_JINGDU 10

volatile unsigned int value=0;

void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}

//ADC initialize
// Conversion time: 112uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0
ACSR = 0x80;
ADCSR = 0xCE;
}

void adc_single_init(unsigned char adc_input)
{
ADCSR = 0x00; //disable adc
#if AD_JINGDU ==10
ADMUX=0xC0|(1<<ADLAR)|adc_input; //2.56V 的片内基准电压源, AREF 引脚外加滤波电容,左对齐,8位精度,AD输入端ADC0
#endif
#if AD_JINGDU == 8
ADMUX=0xC0|adc_input;
#endif
//ADMUX=0x40|adc_input; //AVCC AREF 引脚外加滤波电容
//ADMUX=adc_input; //AREF 内部Vref 关闭, AREF 引脚外加滤波电容
ACSR |= 0x80;    //禁用模拟比较器
ADCSR = (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|0x06; //允许AD,启动转换,自动触发使能,中断使能,64分频
SFIOR &=~ 0xe0;//自动中断源选择,连续转换模式
}

#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
//conversion complete, read value (int)
#if AD_JINGDU ==10
  value=ADCL;        //Read 8 low bits first (important)
  value|=(int)ADCH << 8; //read 2 high bits and shift into top byte
#endif
#if AD_JINGDU ==8
  value = ADCH;
#endif
}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
adc_single_init(0);

MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}

void main(void)
{
init_devices();
while(1)
{
PORTB = value;
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。