Excellence 发表于 2012-5-28 16:49:42

请教个问题,UCOSII中ADC的滤波。谢。

/****************************************Copyright (c)**************************************************
**                               广州周立功单片机发展有限公司
**                                     研    究    所
**                                        产品一部   
**
**                                 http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: ADC01.C
**创   建   人: 黄绍斌
**最后修改日期: 2004年3月25日
**描      述: 使用ADC模块的通道0、1进行电压的测量,然后将转换结果从串口输出,上位机使用EasyARM软件全仿真的DOS字
**             符窗口观察。
**             通讯格式为8位数据位,1位停止位,无奇偶校验,波特率为115200。
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人:   
** 版本:   
** 日 期:   
** 描 述:   
**
**------------------------------------------------------------------------------------------------------
** 修改人:   
** 版本:   
** 日 期:   
** 描 述:   
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 黄绍斌
** 日 期: 2004年3月25日
** 描 述: 在TARGET.C文件中初始化UART0。
** 说明: 将JP5、JP10短接,由W1、W2调节测量电压值;
**      将PC的COM1(或COM2)与EasyARM2100开发板的CZ2连接。      
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/   
   
#include    "config.h"   
   
#define   TASK_STK_SIZE       128               /* 定义任务堆栈大小 */   
   
OS_STK      TaskStartStk;   
OS_STK      TaskStk;   
   
OS_EVENT    *AdcDataMbox;                           /* 定义邮箱,用于传递ADC转换结果 */   
   
   
voidTaskStart(void *data);   
voidTaskAdc(void *data);   
   
/*********************************************************************************************************
** 函数名称: main
** 功能描述: c语言的主函数,由它启动多任务环境
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: OSInit,OSTaskCreate,OSStart
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人:   
** 日 期:   
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/   
      int main (void)   
{   
    OSInit();   
   
    OSTaskCreate(TaskStart, (void *)0, &TaskStartStk, 0);   
    OSStart();   
    return 0;   
}   
   
/*********************************************************************************************************
** 函数名称: TaskStart
** 功能描述: μCOS-II的第一个任务,通常由它初始化目标板和建立其它任务
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块:   
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人:   
** 日 期:   
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/   
   
      voidTaskStart(void *pdata)   
{      
    uint32*cp;   
    uint8   err;   
    uint32ADC_Data;   
    char    s;   
   
    pdata = pdata;                                                /* 避免编译警告 */   
      
    AdcDataMbox = OSMboxCreate(NULL);                               /* 建立邮箱   */   
    if (AdcDataMbox == NULL)   
    {   
      while (1);   
    }   
   
    PINSEL1 = ( (PINSEL1&0xfc3fffff) | 0x01400000);               /* 设置P0.27、P0.28连接到AIN0、AIN1 */   
    TargetInit();                                                   /* 目标板初始化 */   
      
    OSTaskCreate(TaskAdc, (void *)0, &TaskStk, 10); /* 创建任务   */   
   
    for (;;)   
    {   
      cp = (uint32 *)OSMboxPend(AdcDataMbox, 0, &err);            /* 接收数据 */   
         
      ADC_Data = (cp>>6) & 0x3FF;   
      ADC_Data = ADC_Data * 3300;   
      ADC_Data = ADC_Data / 1024;   
      sprintf(s, "%4dmV at VIN1", ADC_Data);   
      PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);   
               
      ADC_Data = (cp>>6) & 0x3FF;   
      ADC_Data = ADC_Data * 3300;   
      ADC_Data = ADC_Data / 1024;   
      sprintf(s, "%4dmV at VIN2", ADC_Data);   
      PC_DispStr(60, 21, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);   
    }   
}   
   
/*********************************************************************************************************
** 函数名称: TaskAdc
** 功能描述: μCOS-II的任务,用于进行ADC转换。
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块:   
**
** 作 者: 陈明计
** 日 期: 2003年7月8日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2003年7月21日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/   
      voidTaskAdc(void *pdata)   
{   
    uint32 Buf;   
   
    pdata = pdata;                                    /* 避免编译警告 */   
   
    /* 进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延) */   
    ADCR = (1 < 0)                     |             /* SEL = 1 ,选择通道0 */   
         ((Fpclk / 1000000 - 1) < 8) |               /* CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz */   
         (0 < 16)                  |             /* BURST = 0 ,软件控制转换操作 */   
         (0 < 17)                  |               /* CLKS = 0 ,使用11clock转换 */   
         (1 < 21)                  |               /* PDN = 1 , 正常工作模式(非掉电转换模式) */   
         (0 < 22)                  |               /* TEST1:0 = 00 ,正常工作模式(非测试模式) */   
         (1 < 24)                  |               /* START = 1 ,直接启动ADC转换 */   
         (0 < 27);                                 /* EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)    */   
   
    for (;;)   
    {   
      ADCR = (ADCR&0xFFFFFF00)|0x01|(1 < 24);      /* 切换通道并进行第一次转换 */   
      while( (ADDR&0x80000000)==0 )                   /* 等待转换结束 */   
      {OSTimeDly(OS_TICKS_PER_SEC / 100);   
      }   
      ADCR = ADCR | (1 < 24);                      /* 再次启运转换 */   
      while( (ADDR&0x80000000)==0 )   
      {OSTimeDly(OS_TICKS_PER_SEC / 100);   
      }   
      Buf = ADDR;                                  /* 读取ADC结果 */   
         
      ADCR = (ADCR&0xFFFFFF00)|0x02|(1 < 24);   
      while( (ADDR&0x80000000)==0 )   
      {OSTimeDly(OS_TICKS_PER_SEC / 100);   
      }   
      ADCR = ADCR | (1 < 24);                     
      while( (ADDR&0x80000000)==0 )   
      {OSTimeDly(OS_TICKS_PER_SEC / 100);   
      }   
      Buf = ADDR;                           
   
      OSMboxPost(AdcDataMbox, (void *)Buf);   
         
      OSTimeDly(OS_TICKS_PER_SEC / 10);   
    }   
      
}   
   
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

这个是老周的例程,如果AD滤波,在任务里怎么滤波?
如果无OS查询的话,可以多读几次,平均。

Excellence 发表于 2012-5-28 16:50:03

上传一个老周的例程来讨论一下。

gaolf_2012 发表于 2012-5-28 19:08:30

本帖最后由 gaolf_2012 于 2012-5-28 19:12 编辑

for (;;)   
{   
        cp = (uint32 *)OSMboxPend(AdcDataMbox, 0, &err);            /* 接收数据 */   
          
        ADC_Data = filter1(cp);   
        ADC_Data = ADC_Data * 3300;   
        ADC_Data = ADC_Data / 1024;   
        sprintf(s, "%4dmV at VIN1", ADC_Data);   
        PC_DispStr(60, 23, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);   
                  
        ADC_Data = filter1(cp);   
        ADC_Data = ADC_Data * 3300;   
        ADC_Data = ADC_Data / 1024;   
        sprintf(s, "%4dmV at VIN2", ADC_Data);   
        PC_DispStr(60, 21, s, DISP_FGND_YELLOW + DISP_BGND_BLUE);   
}
       
uint32 filter1(uint32 dwData)
{
        static uint32 dwpDataBuff = {0};
        static unsigned char bPos=0;
        uint32 dwI=0;
        unsigned char bI;

        dwpDataBuff = (dwData>>6) & 0x3FF;
        if (bPos > 15)
        {
                bPos = 0;
        }

        for (bI=0; bI<16; bI++)
        {
                dwI += dwpDataBuff;
        }
        return (dwI >> 4);
}

uint32 filter2(uint32 dwData)
{
        static uint32 dwpDataBuff = {0};
        static unsigned char bPos=0;
        uint32 dwI=0;
        unsigned char bI;

        dwpDataBuff = (dwData>>6) & 0x3FF;
        if (bPos > 15)
        {
                bPos = 0;
        }

        for (bI=0; bI<16; bI++)
        {
                dwI += dwpDataBuff;
        }
        return (dwI >> 4);
}

试试看

Excellence 发表于 2012-5-28 20:34:34

谢谢。试试。

xiong57785 发表于 2013-5-26 12:44:50

mark      滤波
页: [1]
查看完整版本: 请教个问题,UCOSII中ADC的滤波。谢。