📄 ad转换滤波后led显示.txt
字号:
#include "config.h"
uint8 ucADC_select; // 四通道AD选择
uint8 ucADC_count; // AD转换计数
uint8 config=0x10,config_temp=0x10; // 功能选择设定
uint8 ucADC_select; // 四通道AD选择
uint8 ucADV_count; //转换计数器
uint16 ADC0_DATA,ADC1_DATA,ADC2_DATA; //AD转换结果
volatile uint16 ADC0_value[18]; // 0通道AD,18个数据
volatile uint16 ADC1_value[18]; // 1通道AD,18个数据
volatile uint16 ADC2_value[18]; // 2通道AD,18个数据
uint32 time2_count; // TIME2 中断计数N,0.1S计数
/*双字节无符号数去极值平均滤波法子程序
*/
uint16 arr[18]; // 18个数据临时寄存器
uint16 average(uint16 arr[18])
{
uint8 i;
uint16 temp=0,max=0,min=0x3ff;
for(i=0;i<18;i++){
if(max<arr[i])
{max=arr[i];}
else if(min>arr[i])
{min=arr[i];}
temp+=arr[i];
}
temp=(temp-max-min)/16;
return (temp);
}
/********由定时器T2中断启动 连续转换3个ADC通道的值 **********/
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
//uint8 num1,num2; // 临时寄存器
//uint16 uitemp1,uitemp2; // 临时寄存器
uint16 uiadc_value_temp;
uiadc_value_temp = ADCL;
uiadc_value_temp |= (uint16)ADCH << 8;
// SEI();
switch(ucADC_select)
{
case 0 : // ADC0通道 数据处理
{
//ADMUX = 0xc1; // 切换到ADC1通道,内部Vref
ADMUX = 0x01; // 外部Vref,ADC1通道
ADC0_value[ucADC_count] = uiadc_value_temp; //
// ADCSRA |= (1<<ADSC); // enable adc
ucADC_select ++ ; // 切换到ADC1通道
break;
}
case 1 : // ADC1通道 数据处理
{
//ADMUX = 0xc2; // 切换到ADC2通道,内部Vref
ADMUX = 0x02; // 外部Vref,ADC2通道
ADC1_value[ucADC_count] = uiadc_value_temp; //
// ADCSRA |= (1<<ADSC); // enable adc
ucADC_select ++ ; // 切换到ADC2通道
break;
}
case 2 : // ADC2通道 数据处理
{
//ADMUX = 0xc0; // 切换到ADC0通道,内部Vref,但不启动,等待定时器T2启动
ADMUX = 0x00; // 外部Vref,ADC0通道
ADC2_value[ucADC_count] = uiadc_value_temp; //
ucADC_select = 0 ; // 切换到ADC0通道,但不启动,等待定时器T2启动
ucADC_count++;
// if(ucADC_count>=18)
// {ucADC_count = 0 ;}
break;
// else
// {ADCSRA |= (1<<ADSC);} // enable adc
// break;
}
default :
{
ADMUX = 0xc0; // 切换到ADC0通道,内部Vref,但不启动,等待定时器T2启动
//ADCSRA |= (1<<ADSC); // enable adc
ucADC_select = 0 ; // 切换到ADC0通道,但不启动,等待定时器T2启动
// ucADC_count = 0 ;
break;
}
} // switch end
} // AD中断处理 end
/********由定时器T2中断启动 连续转换3个ADC通道的值 ****** end */
// *********** ADC的设定及函数****************
//ADC initialize
// Conversion time: 128KHz(系统位8MHz,128分频)
void adc_init(void)
{
ADCSRA= 0x00; //disable adc
ACSR = (1<<ACD); //disable comparator
//ADMUX = 0xc0; //内部Vref,ADC0通道
ADMUX = 0x00; //外部Vref,ADC0通道
//ADCSRA= (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); // enable adc,中断允许,32分频|(1<<ADSC)
//ADCSRA= (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); //enable adc,64分频
ADCSRA= (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);//enable adc,128分频
}
// *********** ADC的设定及函数**************end**
// ICC-AVR application builder : 2007-9-25
// Target : M16
// Crystal: 8Mhz
// 工程5led 七段数码管显示
#include "config.h"
extern const led_data[16]; //声明外部led显示数据,led_data在led.c中
extern uint16 uiADC_value_sum[4]; // 四通道AD,64个数据加和值extern
extern uint16 ADC0_value_sum[18]; // 0通道AD,18个数据
extern uint16 ADC1_value_sum[18]; // 1通道AD,18个数据
extern uint16 ADC2_value_sum[18]; // 2通道AD,18个数据
extern uint8 ucADC_select; // 四通道AD选择
extern uint8 ucADC_count; // AD转换计数
extern uint8 config,config_temp; // 功能选择设定
extern uint8 display_control; // LCD显示的定时控制字节
extern uint8 ucADC_select; // 四通道AD选择
extern uint16 uiadc_value_temp;
extern uint32 uladc_data,uladc_data2,time2_count; // ADC的转换数据,
extern uint16 ADC0_value[18]; // 0通道AD,18个数据
extern uint16 ADC1_value[18]; // 1通道AD,18个数据
extern uint16 ADC2_value[18]; // 2通道AD,18个数据
extern uint16 ADC0_DATA,ADC1_DATA,ADC2_DATA; // AD转换结果
uint8 time2_cmp_i=54; // TIME2 比较中断i=采样率*AD通道数
extern uint16 countdata;
extern uint8 count;
extern uint8 dot;
//端口初始化
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//TIMER2 initialize - prescale:1024
// WGM: CTC
// actual value: 1SEC采样100次,0.01SEC中断一次
void timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR = 0x00; //关闭异步方式
TCNT2 = 0x00; //setup
OCR2 = 0x25; //
TCCR2 = (1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20); //内部时钟1024分频
TIMSK |= (1<<OCIE2); //timer2 中断允许
}
//Watchdog initialize
// prescale: 2048K
void watchdog_init(void)
{
WDR(); //this prevents a timout on enabling
WDTCR = 0x1F; //WATCHDOG ENABLED - dont forget to issue WDRs
WDTCR = 0x0F; //WATCHDOG ENABLED - 看门狗定时器预分频设为2048K,2.1S
WDR();
}
/******定时器T2中断*****************************
*1、喂狗;2、启动ADC;
*3、将ADC的加和值平均,计算电压值
************************************************/
#pragma interrupt_handler timer2_comp_isr:8
void timer2_comp_isr(void) // TIME2做三通道ADC0、ADC1、ADC2的积分滤波 10Hz,18采样率
{
WDR(); //喂狗
time2_cmp_i --;
count--;
if(count<1)
{count=4;}
if((time2_cmp_i % 0x03) == 0x00)
{ADC0_DATA=average(ADC0_value);
ADC1_DATA=average(ADC1_value);
ADC2_DATA=average(ADC2_value);
ADCSRA |= (1<<ADSC); // 启动ADC,18次采样率
}
if(time2_cmp_i == 0)
{time2_cmp_i = 54;}
// SEI();
// time2_count ++; // 0.1S计数
}
//******定时器T2中断************************* end */
/*************************************************
主程序
*************************************************/
void main(void)
{
CLI(); //disable all interrupts
port_init();
led_init(); //5位7段数码管显示
timer2_init(); // 使能AD转换
watchdog_init();
adc_init(); // 使能ADC
SEI(); //re-enable interrupts
while(1)
{
dot=4;
display(countdata,dot,count); //普通模式,显示countdata的值,countdata将在timer1定时一秒溢出时改变
countdata=ADC0_DATA;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -