12
返回列表 发新帖
楼主: hotpower

补充一些IAR AVR常用的H和CPP文件

[复制链接]
 楼主| 发表于 2009-4-2 23:41:54 | 显示全部楼层
adc.cpp(略)
hotpower 发表于 2007-8-23 02:26 AVR 单片机 ←返回版面   举报该贴

#include "adc.h"

AdcObj::AdcObj(void)
{
  Init();
}

/*----------------------------------------------------
R0 = 10K, R1 = 51K, Vref = 2.50V
公式:Vx = Vref * (R0 + R1) / R0

     V0 =2.5*(61/10)=15.25V
     V1 =2.5*(61/10)=15.25V
     V23=2.5*(85/10)=21.25V
     Ak = Vx / 1024
-----------------------------------------------------*/
void AdcObj::Init(void)
{
unsigned char i;
    AdcChNum = 0;
    ADCSRA = 0x00;
    ADMUX  = 0;//选择外部2.50为基准
    ACSR = (1 << ACD);//关闭模拟比较器
    SetAdcChNum(AdcChNum);//设置新通道
    for (i = 0; i < 4; i ++) {
        AdcVal[i] = 0;
        AdcCount[i] = 0;
    }
    AdcSum[1] = 0;
    AdcMax[1] = 0;
    AdcMin[1] = 0x1ff;//9位ADC

    AdcSum[2] = 0;
    AdcMax[2] = 0;
    AdcMin[2] = 0x3ff;//10位ADC

    AdcSum[3] = 0;
    AdcMax[3] = 0;
    AdcMin[3] = 0x3ff;//10位ADC
/*----------------------------------------------------
R0 = 10K, R1 = 51K, Vref = 2.50V, Vk = 10, N = 9, 10
公式:Vx = Vref * (R0 + R1) / R0
    Ak = Vx * / 2 ^ n
    Ak0 = 15250 / 512   (N = 9)
        = 30500 / 1024
    Ak1 = 15250 / 1024
    Ak2 = 21250 / 1024
    Ak3 = 21250 / 1024
-----------------------------------------------------*/

    ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频,启动AD转换
}

inline
unsigned char AdcObj::GetAdcChNum(unsigned char ChNum)
{
__root __flash  static const unsigned char AdcChNumTab[4] =
{//ADC通道变换表
    0x09,//0b00001001,//差分测试,*10,ADC1-ADC0
    0x09,//0b00001001,//差分测试,*10,ADC1-ADC0
    0x02,//0b00000010,//单端测试,*1,ADC2
    0x00//0b00000000,//单端测试,*1,ADC0
//    0x03//0b00000011,//电压,单端测试,*1,ADC3
};
    return AdcChNumTab[ChNum & 0x03];//返回ADC通道变换号
}

inline
void AdcObj::SetAdcChNum(unsigned char ChNum)//设置ADC通道变换号
{
//    ADMUX = (1 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择内部2.56为基准
    ADMUX = (0 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择外部2.50为基准
}

void AdcObj::Exec(void)
{
//volatile
unsigned int AdcResult;
//volatile
unsigned long val;
    AdcResult = ADC & 0x3ff;//取ADC转换电压,并保存
    SetAdcChNum(AdcChNum + 1);//设置新通道
    if (AdcChNum > 0)
    {
/*-----------------------------------------------------------
  求累加和
------------------------------------------------------------*/
        AdcSum[AdcChNum] += AdcResult;//存累加和
/*-----------------------------------------------------------
  求最大值
------------------------------------------------------------*/
        if (AdcResult > AdcMax[AdcChNum])
        {
            AdcMax[AdcChNum] = AdcResult;//最大值
        }
/*-----------------------------------------------------------
  求最小值
------------------------------------------------------------*/
        if (AdcResult <= AdcMin[AdcChNum])
        {
            AdcMin[AdcChNum] = AdcResult;//存最小值
        }
        AdcCount[AdcChNum] ++;
        if (AdcCount[AdcChNum] >= 18)//每点测试18次,滤波
        {
/*-----------------------------------------------------------
  求平均值
------------------------------------------------------------*/
/*----------------------------------------------------
     V0 =2.5*(61/10)=15.25V
     V1 =2.5*(61/10)=15.25V
     V23=2.5*(85/10)=21.25V
-----------------------------------------------------*/
            val = AdcSum[AdcChNum] - AdcMax[AdcChNum] - AdcMin[AdcChNum];
            val *= AdcAkVal[AdcChNum];
            val >>= 14;//18中取16后除以1024
            AdcVal[AdcChNum] = val;
/*-----------------------------------------------------------
  初始化
------------------------------------------------------------*/
            AdcSum[AdcChNum] = 0;
            AdcMax[AdcChNum] = 0;
            if (AdcChNum == 1)
            {
                AdcMin[AdcChNum] = 0x1ff;//9位ADC
            }
            else
            {
                AdcMin[AdcChNum] = 0x3ff;//10位ADC
            }
            AdcCount[AdcChNum] = 0;
    }
    AdcChNum ++;//准备下个通道
    AdcChNum &= 3;
    ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频
}
 楼主| 发表于 2009-4-2 23:42:15 | 显示全部楼层
本帖最后由 hotpower 于 2009-4-2 23:44 编辑

注意楼上的"跳水"滤波算法
hotpower 发表于 2007-8-23 02:51 AVR 单片机 ←返回版面   举报该贴


hotpower 发表于 2007-8-13 21:07 PIC 单片机 ←返回版面

8楼: 这种算法的优点是点数无限~~~(附"跳水算法")

当然N>=3.而且最好N>3为好.在N很大时就见其优点了.
例如: 3中取1,4中取2,5中取3...10中取8...252中取"二百五"~~~
全部只用这4个寄存器~~~,当然要考虑累加越界类型选择的问题.
注意: N最好取4, 6, 10, 34, 66, 130等等~~~!!!!!!!!!!!!!!


/*-----------------------------------------------------------
取ADC转换电压
------------------------------------------------------------*/
AdcResult = ADC & 0x3ff;//取ADC转换电压结果
/*-----------------------------------------------------------
  求累加和
------------------------------------------------------------*/
AdcSum += AdcResult;//存累加和
/*-----------------------------------------------------------
  求最大值
------------------------------------------------------------*/
if (AdcResult > AdcMax)
{
  AdcMax = AdcResult;//最大值
}
/*-----------------------------------------------------------
  求最小值
------------------------------------------------------------*/
if (AdcResult < AdcMin)//注意:千万不敢写成else if ()...
{
  AdcMin = AdcResult;//存最小值
}
AdcCount ++;//计数1次
/*-----------------------------------------------------------
  10中取8("跳水评分算法---去掉一个最高分,去掉...最后得分...")
------------------------------------------------------------*/
if (AdcCount >= 10)//每次滤波10点
{
/*-----------------------------------------------------------
  求平均值
------------------------------------------------------------*/
  val = AdcSum - AdcMax - AdcMin;//自然做到了N-2,以下除法变移位
  val *= AdcGain;//乘增益(一定要先乘后除!!!否则精度丢失!!!)
  val >>= 13;//10中取8后除以1024.(直接得到10进制的mV值)
  AdcVal = val;//得到跳水队员分数~~~
/*-----------------------------------------------------------
  下一轮初始化(也是ADC的初始化,这里原本是调用函数的~~~)
------------------------------------------------------------*/
  AdcSum = 0;//一定清0
  AdcMax = 0;//一定取最小值
  AdcMin = 0x3ff;//10位ADC,一定取最大值
  AdcCount = 0;//重新开始
}

哈哈~~~有时间再灌灌它与排序的不同和优缺点~~~
发表于 2009-4-6 21:59:25 | 显示全部楼层
大叔讲课,俺认识听讲,做好学生
发表于 2009-6-14 22:35:21 | 显示全部楼层
好!hotpower玩C++就是牛!
发表于 2009-6-18 12:37:48 | 显示全部楼层
发表于 2009-6-18 12:45:10 | 显示全部楼层
老HOT实在是强 啊~~
发表于 2010-9-26 23:46:53 | 显示全部楼层
学习了
发表于 2011-2-14 15:51:56 | 显示全部楼层
不错
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表