Matrix 发表于 2024-11-22 09:54:22

论坛里有可以达到16位的方法

Emmetttttt 发表于 2024-11-22 09:57:11

Matrix 发表于 2024-11-22 09:54
论坛里有可以达到16位的方法

现在的问题不是精度的问题,是adc采样转换无法得到成功的标志
这是官方例程里的获取成功标志位的方法,一样是输出4096
        for(i=0; i<250; i++)                //超时返回,正常i等于10以内就可以转换完成
        {
                if(ADC_CONTR & ADC_FLAG)
                {
                        ADC_CONTR &= ~ADC_FLAG;
                        if(ADCCFG &(1<<5))                //转换结果右对齐。
                        {
                                adc = ((u16)ADC_RES << 8) | ADC_RESL;
                        }
                        else                //转换结果左对齐。
                        {
                                #if ADC_RES_12BIT==1
                                        adc = (u16)ADC_RES;
                                        adc = (adc << 4) | ((ADC_RESL >> 4)&0x0f);
                                #else
                                        adc = (u16)ADC_RES;
                                        adc = (adc << 2) | ((ADC_RESL >> 6)&0x03);
                                #endif
                        }
                        return        adc;
                }
        }
        return        4096;        //错误,返回4096,调用的程序判断

梁工 发表于 2024-11-22 10:00:10

Emmetttttt 发表于 2024-11-22 09:57
现在的问题不是精度的问题,是adc采样转换无法得到成功的标志
这是官方例程里的获取成功标志位的方法,一 ...

你的单片机具体型号是什么?

Emmetttttt 发表于 2024-11-22 10:10:21

梁工 发表于 2024-11-22 10:00
你的单片机具体型号是什么?

8G1K08A

梁工 发表于 2024-11-22 11:32:37

Emmetttttt 发表于 2024-11-22 10:10
8G1K08A

用户请先别修改程序, 直接下载“ADC相关程序-STC8G1K08A-8PIN”里的"02-5路ADC转换-BandGap-串口1(P3.1)返回结果-C语言"里的"ADC.hex"测试. 下载时选择主频11.0592MHZ。
测试时, 电脑的串口助手设置115200,8,n,1.

本程序演示4路ADC(P3.0 P3.2 P3.3 P5.4 P5.5)和bandgap查询采样,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.
0~3通道对应P3.0~P3.3, 4通道-->P5.4, 5通道-->P5.5, 15通道为内部1.19V基准电压做输入的ADC值.





Emmetttttt 发表于 2024-11-22 11:48:08

本帖最后由 Emmetttttt 于 2024-11-22 11:57 编辑

梁工 发表于 2024-11-22 11:32
用户请先别修改程序, 直接下载“ADC相关程序-STC8G1K08A-8PIN”里的"02-5路ADC转换-BandGap-串口1(P3.1) ...
这样的测试是好的
接收←
                               ADC00=1023
接收←ADC02=0000
接收←ADC03=0000
接收←ADC04=0000
接收←ADC05=0234
接收←ADC15=0249



那种收不到转换成功的标志位是偶尔出现的,而且是运行挺久才有可能出现,这样的测试感觉有些难复现那种情况
我不确定是不是电压采集频率过快导致的了,或者说是母线电压出现了波动,因为将这个电压采集出来显示再数码管的时候,平常会有540v跳到490v这样的情况

梁工 发表于 2024-11-22 12:22:58

本帖最后由 梁工 于 2024-11-22 12:25 编辑

Emmetttttt 发表于 2024-11-22 11:48
这样的测试是好的
接收←
                               ADC00=1023

ADC是硬件外设,一旦启动,就会自动转换直至完成,绝对不会出现卡死的情况。
ADC设置采样时间要要合适,不知道你说的“电压采集频率过快”指的什么?
你可能程序中将ADC关闭了,所以等不来ADC转换完成标志,否则一旦启动,必然会完成。

我的例子没有超时处理,你可以连续通电一个月(要保证电源可靠哦),看看会不会出现你说的问题。我用过无数ADC场合,没有遇到ADC会完成不了的情况。

Emmetttttt 发表于 2024-11-22 13:17:42

梁工 发表于 2024-11-22 12:22
ADC是硬件外设,一旦启动,就会自动转换直至完成,绝对不会出现卡死的情况。
ADC设置采样时间要要合适,不 ...

if(div_01ms)                                                //0.1ms任务
{
        GetVinValue();
        div_01ms = 0;
}
if(div_1ms)                                                        //1ms任务
{
        GetTempValue();
        Get_BrkFanFlag();
        div_1ms = 0;
}
电压采集ADC开启转换频率是10KHz,温度是1KHz,ADC采样时间设置的是最大的
程序里没有关闭ADC的代码,应该不是这个问题
按照官方例程里的代码也是由于获取不到标志位导致函数输出4096
//========================================================================
// 函数: u16        Get_ADCResult(u8 channel)
// 描述: 查询法读一次ADC转换结果.
// 参数: channel: 选择要转换的ADC通道.
// 返回: ADC转换结果.
// 版本: V1.0, 2012-10-22
//========================================================================
u16        Get_ADCResult(u8 channel)        //channel = 0~15
{
        u16        adc;
        u8        i;

        if(channel > ADC_CH15)        return        4096;        //错误,返回4096,调用的程序判断       
        ADC_RES = 0;
        ADC_RESL = 0;

        ADC_CONTR = (ADC_CONTR & 0xf0) | channel;
        ADC_CONTR |= ADC_START;                        //启动转换
        NOP(10);

        for(i=0; i<250; i++)                //超时返回,正常i等于10以内就可以转换完成
        {
                if(ADC_CONTR & ADC_FLAG)
                {
                        ADC_CONTR &= ~ADC_FLAG;
                        if(ADCCFG &(1<<5))                //转换结果右对齐。
                        {
                                adc = ((u16)ADC_RES << 8) | ADC_RESL;
                        }
                        else                //转换结果左对齐。
                        {
                                #if ADC_RES_12BIT==1
                                        adc = (u16)ADC_RES;
                                        adc = (adc << 4) | ((ADC_RESL >> 4)&0x0f);
                                #else
                                        adc = (u16)ADC_RES;
                                        adc = (adc << 2) | ((ADC_RESL >> 6)&0x03);
                                #endif
                        }
                        return        adc;
                }
        }
        return        4096;        //错误,返回4096,调用的程序判断
}


页: 1 [2]
查看完整版本: 关于AI8G1K08A-8Pin的ADC采样问题