📄 atmege8ad.txt
字号:
ATMege8的AD采样程序.
文章发布: Admin 发布时间: 2007-8-14 13:15:02 百强电子世界 保留网站所有权限
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define uiVref_preset 2560
uchar const SEG7[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar const ACT[8]={0xf7,0xfb,0xfd,0xfe};
uint adc_val,dis_val;
unsigned char time2_cmp_i=128; // TIME2 比较中断i=采样率*AD通道数
unsigned int uiadc_value_temp; // ADC中断的 采样值
unsigned int uitime2_adc0_value_sum,uiadc0_value; // TIME2 ADC0 16个采样值的加和值,电压输出值=Vref*uitime2_adc0_value_sum/16/1024
unsigned int uitime2_adc1_value_sum,uiadc1_value; // TIME2 ADC1 16个采样值的加和值,电压输出值
unsigned int uitime2_adc2_value_sum,uiadc2_value; // TIME2 ADC2 16个采样值的加和值,电压输出值
unsigned int uitime2_adc3_value_sum,uiadc3_value; // TIME2 ADC3 16个采样值的加和值,电压输出值
unsigned int uitime2_adc4_value_sum,uiadc4_value; // TIME2 ADC4 16个采样值的加和值,电压输出值
unsigned long uladc_data,uladc_data2,time2_count; // ADC的转换数据, TIME2 中断计数N,0.1S计数(可作长时间定时器136年)
unsigned char ucADC_select; // 五通道AD选择
unsigned int uiADC_value_sum[5]; // 五通道AD,64个数据加和值
//uint uiadc[5]; // 参考电压=2665mV
uint f;
unsigned char i;
void port_init(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
DDRC = 0x00;
PORTC = 0x00; //m103 output only
DDRD = 0xFF;
PORTD = 0xFF;
}
// *********** ADC的设定及函数****************
//ADC initialize
// Conversion time: 128KHz(系统位4.096MHz,32分频)
void adc_init(void)
{
ADCSRA= 0x00; //disable adc
ACSR = (1< ADMUX = 0xe0; //内部Vref,ADC0通道
ADCSRA= (1< }
// *********** ADC的设定及函数**************end**
//TIMER2 initialize - prescale:1024
// WGM: CTC
// actual value: 32*2*10Hz (0.0%)=采样率*AD通道数*工频50Hz的倍数
void timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR = 0x00; //关闭异步方式
TCNT2 = 0x00; //setup
OCR2 = 0XEA; //设置TIME2 比较中断频率10ms
TCCR2 = (1< TIMSK |= (1< }
unsigned int cal_VD(unsigned int uiAD_16sum_data)
{
uladc_data = uiAD_16sum_data;
return ((unsigned int)((uladc_data*uiVref_preset)>>12)); // 输出ADC0的电压值VD0=Vref*uitime2_adc0_value_sum/16/2的8次方
}
#pragma interrupt_handler timer2_comp_isr:4
void timer2_comp_isr(void) // TIME2做四通道ADC0、ADC1、ADC2、ADC3的积分滤波 10Hz,16采样率
{
CLI();
f++;
if((time2_cmp_i & 0x07) == 0x00) ADCSRA |= (1< time2_cmp_i --;
if(time2_cmp_i == 0)
{
uitime2_adc0_value_sum = uiADC_value_sum[0]; // 16个数据加和值
uiadc0_value=cal_VD(uitime2_adc0_value_sum); // 输出ADC0的电压值VD0=Vref*uitime2_adc0_value_sum/16/1024
uiADC_value_sum [0]= 0; // 清零
uitime2_adc1_value_sum = uiADC_value_sum[1]; // 16个数据加和值
uiadc1_value=cal_VD(uitime2_adc1_value_sum); // 输出ADC0的电压值VD0=Vref*uitime2_adc0_value_sum/16/1024
uiADC_value_sum[1] = 0; // 清零
uitime2_adc2_value_sum = uiADC_value_sum[2]; // 16个数据加和值
uiadc2_value=cal_VD(uitime2_adc2_value_sum); // 输出ADC0的电压值VD0=Vref*uitime2_adc0_value_sum/16/1024
uiADC_value_sum [2]= 0; // 清零
uitime2_adc3_value_sum = uiADC_value_sum[3]; // 16个数据加和值
uiadc3_value=cal_VD(uitime2_adc3_value_sum); // 输出ADC0的电压值VD0=Vref*uitime2_adc0_value_sum/16/1024
uiADC_value_sum[3] = 0; // 清零
uitime2_adc4_value_sum = uiADC_value_sum[4]; // 16个数据加和值
uiadc4_value=cal_VD(uitime2_adc4_value_sum); // 输出ADC0的电压值VD0=Vref*uitime2_adc0_value_sum/16/1024
uiADC_value_sum[4] = 0;
time2_cmp_i =128;
SEI();
}
}
//******定时器T2中断************************* end */
/********由定时器T2中断启动 连续转换四个ADC通道的值 **********/
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{CLI();
uiadc_value_temp = ADCH;
//uiadc_value_temp |= (unsigned int)ADCH << 8;
switch(ucADC_select)
{
case 0 : // ADC0通道 数据处理
{
ADMUX = 0xe1; // 切换到ADC1通道,内部Vref
uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
ADCSRA |= (1< ucADC_select ++ ; // 切换到ADC1通道
break;
}
case 1 : // ADC1通道 数据处理
{
ADMUX = 0xe2; // 切换到ADC2通道,内部Vref
uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
ADCSRA |= (1< ucADC_select ++ ; // 切换到ADC2通道
break;
}
case 2 : // ADC2通道 数据处理
{
ADMUX = 0xe3; // 切换到ADC3通道,内部Vref
uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
ADCSRA |= (1< ucADC_select ++ ; // 切换到ADC3通道
break;
}
case 3 : // ADC3通道 数据处理
{
ADMUX = 0xe4; // 切换到ADC0通道,内部Vref,但不启动,等待定时器T2启动
uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
ADCSRA |= (1< ucADC_select ++; // 切换到ADC0通道,但不启动,等待定时器T2启动
break;
}
case 4 : // ADC3通道 数据处理
{
ADMUX = 0xe0; // 切换到ADC0通道,内部Vref,但不启动,等待定时器T2启动
uiADC_value_sum[ucADC_select] += uiadc_value_temp; //加和值
//ADCSRA |= (1< ucADC_select =0 ; // 切换到ADC0通道,但不启动,等待定时器T2启动
break;
}
default :
{
ADMUX = 0xe0; // 切换到ADC0通道,内部Vref,但不启动,等待定时器T2启动
ucADC_select = 0 ; // 切换到ADC0通道,但不启动,等待定时器T2启动
break;
}
SEI();
} // switch end
} // AD中断处理 end
/********由定时器T2中断启动 连续转换四个ADC通道的值 ****** end */
void init_devices()
{port_init();
adc_init();
timer2_init();
SEI();
}
void main(void)
{uint j,k,n;
init_devices();
while(1)
{//if(f<1000) dis_val=uiadc0_value;
//else if (f<2000) dis_val=uiadc1_value;
//else if (f<3000) dis_val=uiadc2_value;
//else if (f<4000) dis_val=uiadc3_value;
//else if (f<5000) dis_val=uiadc4_value;
//else f=0;
dis_val=uiadc2_value;
if(++i>3)i=0;
switch(i)
{
case 0: PORTB=SEG7[dis_val%10];PORTD=ACT[i];
break;
case 1: PORTB=SEG7[(dis_val/10)%10];PORTD=ACT[i];
break;
case 2: PORTB=SEG7[(dis_val/100)%10];PORTD=ACT[i];
break;
case 3: PORTB=SEG7[dis_val/1000];PORTD=ACT[i];
break;
default:break;
}
}
}
欢迎光临百强电子世界,本站网址:http://www.bqmcu.com.cn
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -