打印
[技术问答]

SC92F7547 多通道切换ADC问题

[复制链接]
2164|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liu281469315|  楼主 | 2018-10-10 13:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我现在使用 3路 AD,一路 AD 按键,
一路测温度,
一路测湿度 ,
在同时开启3路轮询转换的情况下 每一路得到的AD会不对,只开一路AD 值就正常.能帮忙分析下原因么? 不知道是不是软件问题,硬件上电压都正常 ,困扰我很久了,相关代码如下:

////////////////////////////////////////////////// AD初始化配置等
uint ADC_Convert(void)
{
        unsigned int Tad=0,MinAd=0x0fff,MaxAd=0x0000,TempAdd=0;
        unsigned char t=0;
       
//        ADCCON |= Channel;
        for(t=0;t<10;t++)
        {
                ADCCON |= 0X40;        //开始 ADC 转换
                while(!(ADCCON&0x20));        //等待 ADC 转换完成
                ADCCON&=~(0X20);        //清中断标志位
                Tad = ((unsigned int)ADCVH<<4)+(ADCVL>>4); //取得一次转换值
        if (Tad>MaxAd)
        {
                MaxAd=Tad        ;//获得当前的最大值
        }
        if (Tad<MinAd)
        {
                MinAd=Tad;        //获得当前的最小值
        }
        TempAdd+=Tad;        //转换值累加
        }
        TempAdd-=MinAd;        //去掉最小值
        TempAdd-=MaxAd;        //去掉最大值
        TempAdd>>=3;        //求平均值
        return(TempAdd);
}
/*****************************************************
*函数名称:void ADC_channel(unsigned char channel)
*函数功能:ADC通道选择
*入口参数:void
*出口参数:Channel
*****************************************************/
void ADC_Channel(unsigned char Channel)
{
        ADCCON |= Channel;        //ADC 输入选择为 ADCchannel 口
        if(Channel<8)
        {
                ADCCFG0 = 1<<Channel;   //设置Channel作为采样口
        }
        else
        {
                ADCCFG1 = 1<<(Channel-8);   //设置Channel作为采样口
        }
}
////////////////////////////////////////////////
void ADC_Multichannel(void)
{
        ADCCFG0 = 0;        // 设置为 ADC 口,并自动将上拉电阻移除。
        ADCCFG1 = 0;        //设置 AIN12-15设置为 ADC 口,并自动将上拉电阻移除。
        ADCCFG2 = 0x06;        //fsys/6, 36个采样周期 //大约19us一次转换
        ADCCON  |= 0X80;        //开启 ADC 模块电源
        EADC = 0;
        ADCCON&=~(0X20);        //清中断标志位
//        TEMPR_Value = ADC_Convert(14); //启动 ADC 转换,获得转换值
//       
//        HUMR_Value = ADC_Convert(15); //启动 ADC 转换,获得转换值

//        LDR_Value = ADC_Convert(12); //启动 ADC 转换,获得转换值
       
//        KEY_Value = ADC_Convert(13); //启动 ADC 转换,获得转换值
}

//////////////////////////////////////////////////////////////////主函数调用

        ADC_Multichannel();
        RAM_Init();
        while(1)
        {
                if(Flag & UPDATA_F){//10ms定时
                        Flag &= ~UPDATA_F;
                        Key_Function();        ///按键               
                        PWM_FAN(KEY_Anion);
                        ALM_Function();
                               
                        calc_display();       
                        BT_RESET();
                }
                if(Flag & SEC5_F)//5s定时
                {
                        Flag &= ~SEC5_F;
                        THTEMP_Function();        //测温湿度
                }
                         
        }

/////////////////////////////////////////////////////按键子函数 10ms调用一次
uchar Get_Key(void)
{
        uint value;
        uchar keyvalue;
       
                ADC_Channel(KEY_AN);
                value = ADC_Convert(); //
                if((KEY_YEAR_VALUE < value) && (value <= KEY_MAX_VALUE))
                        keyvalue = KEY_NULL;
                else if ((KEY_SET_VALUE < value) && (value < KEY_YEAR_VALUE))
                        keyvalue = KEY1;
                else if ((KEY_UP_VALUE < value) && (value < KEY_SET_VALUE))
                        keyvalue = KEY2;
                else if ((KEY_DOWN_VALUE <= value) && (value < KEY_UP_VALUE))
                        keyvalue = KEY3;
                else if ((KEY_MIN_VALUE <= value) && (value < KEY_DOWN_VALUE))
                        keyvalue = KEY4;
                else return 0;
               
                return keyvalue;
       
}

///////////////////////////////////////////////////////////////////////测湿度子函数
void THTEMP_Function(void)//测量温湿度值
{
        uchar loc,gbl;
        uint i,j,temp;


                        ADC_Channel(TEMPR_AN);
                        temp = ADC_Convert();        
                        for(gbl = 1;gbl < 60;) //温度范围-10-55度,0表示-10度,60表示50度
                        {
                                if(temp > TabTEMP[gbl])break;
                                gbl++;
                        }
                        i = TabTEMP[gbl-1] -TabTEMP[gbl];
                        TEMP_L = (uchar)(i/(temp - TabTEMP[gbl]));
                       
                                        gbl--;
                            gbl+=1;
                        TEMPR_Value = gbl; //温度值
                        //
                        ADC_Channel(HUMR_AN);
                        temp = ADC_Convert(); //
                        gbl /= 5;
                        for(loc = 1;loc < 15;)
                        {
                                i = TabTH[gbl][loc];
                                if(temp > i)loc++;
                                else break;
                                j = i;
                        }
                        loc--;       
                        temp = temp-j;
                        j = i-j;
                        j /= 5;
                        gbl = 20 + loc * 5; //湿度值
                        gbl += (uchar)(temp / j);
                        HUMR_Value = gbl;

}

//////////////////////////////////////////////////////

相关帖子

沙发
赛元MCU1| | 2018-10-10 18:15 | 只看该作者
你好!有关这个问题,请到官网下载《赛元SC92F系列MCU应用指南》里面有介绍多路ADC切换时的使用注意事项及方法。

使用特权

评论回复
板凳
lxs0026| | 2018-10-10 20:28 | 只看该作者
多路切换确实比较复杂,官网资料也不错。

使用特权

评论回复
地板
liu281469315|  楼主 | 2018-10-11 09:45 | 只看该作者
赛元MCU1 发表于 2018-10-10 18:15
你好!有关这个问题,请到官网下载《赛元SC92F系列MCU应用指南》里面有介绍多路ADC切换时的使用注意事项及 ...

我就是看了里面的注意事项,稍微改动了一下调用,设置都是按里面来的,所以发帖求大神

使用特权

评论回复
5
xiaoqi000| | 2018-10-17 21:36 | 只看该作者
拿着小板凳来观看

使用特权

评论回复
6
knk| | 2018-10-19 14:43 | 只看该作者
ADCCON |= Channel;        //ADC 输入选择为 ADCchannel 口
你不觉得这行有问题吗?

使用特权

评论回复
7
等你下课| | 2018-10-30 11:48 | 只看该作者
嗯,感觉是有地方比较怪,楼上说的是不是楼主少打了什么?

使用特权

评论回复
8
knk| | 2018-11-6 15:16 | 只看该作者
等你下课 发表于 2018-10-30 11:48
嗯,感觉是有地方比较怪,楼上说的是不是楼主少打了什么?

设置新的通道之前要把上次设置的通道清除掉,否则后果可想而知。

使用特权

评论回复
9
liu281469315|  楼主 | 2018-11-6 15:46 | 只看该作者
knk 发表于 2018-11-6 15:16
设置新的通道之前要把上次设置的通道清除掉,否则后果可想而知。

感谢,正解,回来结贴!
        ADCCON &=0xe0;//改为默认口0
        ADCCON |= Channel;        //ADC 输入选择为 ADCchannel 口

切换通道前清零

使用特权

评论回复
10
taotao1987| | 2019-8-31 00:28 | 只看该作者
ADCCON &=0xe0;//改为默认口
ADCCON |= Channel;        //ADC 输入选择为 ADCchannel 口

MCU型号没有说清,这个转换我还是没有调式通

使用特权

评论回复
11
liu281469315|  楼主 | 2019-9-3 09:13 | 只看该作者
taotao1987 发表于 2019-8-31 00:28
ADCCON &=0xe0;//改为默认口
ADCCON |= Channel;        //ADC 输入选择为 ADCchannel 口

标题,SC92F7547

使用特权

评论回复
12
taotao1987| | 2019-9-3 22:11 | 只看该作者

我用的是Sc92F7251按你说的没有调式通

使用特权

评论回复
13
2083759| | 2019-9-19 16:57 | 只看该作者
切换通道前清零

使用特权

评论回复
14
taobaofarmer| | 2019-10-7 14:11 | 只看该作者
单片机内部只有一个ADC,留出多个AD接口,其实都用的这一个ADC模块,内部是通过类似4052这种模拟开关切换的,这样的话任意时刻,ADC只能接通一个对外的AD引脚,知道这个原理就会解决你的问题了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝