⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad转换滤波后led显示.txt

📁 对3个通道交替进行AD转换,然后把转换后的结果存在一个18个*3数据窗口中,滤波时对窗口内的18个数据进行去极值取平均值滤波,然后送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 + -