AVR ADC多通道采集应用
时间:10-02
整理:3721RD
点击:
这几天做了个小项目:图传双天线接收。
程序都很简单,大概思路是:两个5.8G的图传模块一起接收数据,单片机ADC同时采RSSI的值,判断哪个信号强就输出哪个视频信号。这里会用到一个模拟切换开关74CH4052D(这个器件很关键,刚开始的时候用的是NJM2264,切换的时候画面老是会跳动,换了这个零件就效果非常好)。
代码:单片机用的是ATMEGA16A
#include <avr/io.h>
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
/视频选择开关
#define SW0_DDR DDRB |=(1<<0);//I/O输出
#define SW0_H PORTB |=(1<<0);
#define SW0_L PORTB &=~(1<<0);
#define SW1_DDR DDRB |=(1<<1);//I/O输出
#define SW1_H PORTB |=(1<<1);
#define SW1_L PORTB &=~(1<<1);
#define SW2_DDR DDRB |=(1<<2);//I/O输出
#define SW2_H PORTB |=(1<<2);
#define SW2_L PORTB &=~(1<<2);
//模块LED指示灯
#define LED1_DDR DDRC |=(1<<0);//I/O输出
#define LED1_H PORTC |=(1<<0);
#define LED1_L PORTC &=~(1<<0);
#define LED2_DDR DDRC |=(1<<1);//I/O输出
#define LED2_H PORTC |=(1<<1);
#define LED2_L PORTC &=~(1<<1);
void ADC_init(uchar channel)
{
DDRA &=~(1<<1);
DDRA &=~(1<<2);
switch (channel)
{
case 0:ADMUX=0X80;break;//ADC通道0
case 1:ADMUX=0X81;break;//ADC通道1
case 2:ADMUX=0X82;break;//ADC通道2
case 3:ADMUX=0X83;break;//ADC通道3
case 4:ADMUX=0X84;break;//ADC通道4
case 5:ADMUX=0X85;break;//ADC通道5
case 6:ADMUX=0X86;break;//ADC通道6
case 7:ADMUX=0X87;break;//ADC通道7
default:break;
}
//ADMUX |=(1<<REFS1)|(1<<REFS0);//选择片内2.56V参考电压源,数据默认右对齐
//(1<<ADLAR);//数据左对齐
ADCSRA |=(1<<ADEN)//AD使能,
|(1<<ADSC)//转换能使,
|(1<<ADATE)//自动触发使能,由于ADTS2~0均为0,故为连续转换模式
//(1<<ADIF)//写1清空中断标志
//(1<<ADIE)//中断使能,
|(1<<ADPS2)//预分频选择128分频
|(1<<ADPS1)
|(1<<ADPS0);
while(!(ADCSRA&0X10));//等待转换完成置位
}
//读取AD采样值
uint ADC_Read(void)
{
return ADC;
}
int main(void)
{
//I/O配置成输出
SW0_DDR;
SW1_DDR;
SW2_DDR;
LED1_DDR;
LED2_DDR;
int temp,temp1;
while(1)
{
//通道0
ADC_init(0);
temp=ADC_Read();
//通道1
ADC_init(1);
temp1=ADC_Read();
if(temp>temp1)
{
LED1_H;//LED1亮,LED2灭
LED2_L;
SW0_H;
SW1_H;//VIN1=VOUT
SW2_L;
}
else
{
LED1_L;//LED1灭,LED2亮
LED2_H;
SW0_H;
SW1_L;//VIN2=VOUT
SW2_L;
}
}
}
程序都很简单,大概思路是:两个5.8G的图传模块一起接收数据,单片机ADC同时采RSSI的值,判断哪个信号强就输出哪个视频信号。这里会用到一个模拟切换开关74CH4052D(这个器件很关键,刚开始的时候用的是NJM2264,切换的时候画面老是会跳动,换了这个零件就效果非常好)。
代码:单片机用的是ATMEGA16A
#include <avr/io.h>
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
/视频选择开关
#define SW0_DDR DDRB |=(1<<0);//I/O输出
#define SW0_H PORTB |=(1<<0);
#define SW0_L PORTB &=~(1<<0);
#define SW1_DDR DDRB |=(1<<1);//I/O输出
#define SW1_H PORTB |=(1<<1);
#define SW1_L PORTB &=~(1<<1);
#define SW2_DDR DDRB |=(1<<2);//I/O输出
#define SW2_H PORTB |=(1<<2);
#define SW2_L PORTB &=~(1<<2);
//模块LED指示灯
#define LED1_DDR DDRC |=(1<<0);//I/O输出
#define LED1_H PORTC |=(1<<0);
#define LED1_L PORTC &=~(1<<0);
#define LED2_DDR DDRC |=(1<<1);//I/O输出
#define LED2_H PORTC |=(1<<1);
#define LED2_L PORTC &=~(1<<1);
void ADC_init(uchar channel)
{
DDRA &=~(1<<1);
DDRA &=~(1<<2);
switch (channel)
{
case 0:ADMUX=0X80;break;//ADC通道0
case 1:ADMUX=0X81;break;//ADC通道1
case 2:ADMUX=0X82;break;//ADC通道2
case 3:ADMUX=0X83;break;//ADC通道3
case 4:ADMUX=0X84;break;//ADC通道4
case 5:ADMUX=0X85;break;//ADC通道5
case 6:ADMUX=0X86;break;//ADC通道6
case 7:ADMUX=0X87;break;//ADC通道7
default:break;
}
//ADMUX |=(1<<REFS1)|(1<<REFS0);//选择片内2.56V参考电压源,数据默认右对齐
//(1<<ADLAR);//数据左对齐
ADCSRA |=(1<<ADEN)//AD使能,
|(1<<ADSC)//转换能使,
|(1<<ADATE)//自动触发使能,由于ADTS2~0均为0,故为连续转换模式
//(1<<ADIF)//写1清空中断标志
//(1<<ADIE)//中断使能,
|(1<<ADPS2)//预分频选择128分频
|(1<<ADPS1)
|(1<<ADPS0);
while(!(ADCSRA&0X10));//等待转换完成置位
}
//读取AD采样值
uint ADC_Read(void)
{
return ADC;
}
int main(void)
{
//I/O配置成输出
SW0_DDR;
SW1_DDR;
SW2_DDR;
LED1_DDR;
LED2_DDR;
int temp,temp1;
while(1)
{
//通道0
ADC_init(0);
temp=ADC_Read();
//通道1
ADC_init(1);
temp1=ADC_Read();
if(temp>temp1)
{
LED1_H;//LED1亮,LED2灭
LED2_L;
SW0_H;
SW1_H;//VIN1=VOUT
SW2_L;
}
else
{
LED1_L;//LED1灭,LED2亮
LED2_H;
SW0_H;
SW1_L;//VIN2=VOUT
SW2_L;
}
}
}
挺好的,正好可以参考
小编厉害 avr不能和32一样连续转换吗 初始化一次采集一次才行啊