QQ624353765 发表于 2024-12-17 20:20:37

ADC_DMA测多通道时通道之间会影响吗

<p><img src="data/attachment/forum/202412/17/201324yne6keurfkg6nkzi.png" alt="0f51ddf0-eb4c-40ee-a250-973dff66b1d3.png" title="0f51ddf0-eb4c-40ee-a250-973dff66b1d3.png" /></p>
<p>当我只开启15通道测得的电压是对的,但我同时开启10通道一起测时,原本15通道的值就不对了</p>
<p>10通道暂时是悬空的</p>
<p><img src="data/attachment/forum/202412/17/201738dnc0hzmp7922c56m.png" alt="QQ20241217-201715.png" title="QQ20241217-201715.png" /></p>
<p>在xdata创建两个数组,把数组地址赋值给DMA_ADC_RXA,测得的数组第二个值就是15通道的值,计算得到的电压不对,</p>
<p>但只测15通道,使用数组第一个值计算得到的电压是正确的</p>

王昱顺 发表于 2024-12-17 20:37:05

<p><img src="data/attachment/forum/202412/17/203506aca35pqmebt3uei8.png" alt="image.png" title="image.png" /></p>
<p>不更改 <code>ADC_DMA 配置寄存器 2(DMA_ADC_CFG2)</code>的话,默认转换次数就是1,如果你使用int宽度的数组,那么第一通道就需要占用数组的0~2地址,第二个通道需要从数组的第三个下标开始取出</p>
<p>例如<code>ShuZu</code>这种形式,而不是是直接取出下一个。</p>

DebugLab 发表于 2024-12-17 21:07:51

unsigned char xdata DMA_Buffer _at_ DMA_ADDR;
for(i=0;i<ADC_CH;i++)
                        {
                                ADC_Value=DMA_Buffer;
                                ADC_Value<<=8;
                                ADC_Value|=DMA_Buffer;
                                ADC_Value<<=8;
                                ADC_Value|=DMA_Buffer;
                                ADC_Value>>=4;        //20bit结果右移4位得16位结果
                        }https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=2537&pid=19963

QQ624353765 发表于 2024-12-18 08:49:54

王昱顺 发表于 2024-12-17 20:37
不更改 ADC_DMA 配置寄存器 2(DMA_ADC_CFG2)的话,默认转换次数就是1,如果你使用int宽度的数组,那么第 ...

转换一次不就各个通道取一次值吗,两个通道不就取了4个字节数据吗
为什么会有8字节数据

王昱顺 发表于 2024-12-18 08:53:07

QQ624353765 发表于 2024-12-18 08:49
转换一次不就各个通道取一次值吗,两个通道不就取了4个字节数据吗
为什么会有8字节数据 ...

有硬件自动平均值和对应的通道号,上面的数据格式截图已经说明了具体的内容

QQ624353765 发表于 2024-12-18 08:57:44

王昱顺 发表于 2024-12-18 08:53
有硬件自动平均值和对应的通道号,上面的数据格式截图已经说明了具体的内容 ...

硬件取平均值每个通道都会有吗,也就是一个通道取一次就有5字节数据

王昱顺 发表于 2024-12-18 09:33:34

<p>每个通道都会有</p>
<p>一个通道如果只转换一次的话,也是需要占用6个byte数据</p>
<p><img src="data/attachment/forum/202412/18/093331b1znk12kb7cq7ibk.png" alt="image.png" title="image.png" /></p>

平常心 发表于 2025-8-8 20:23:32

王昱顺 发表于 2024-12-18 09:33
每个通道都会有
一个通道如果只转换一次的话,也是需要占用6个byte数据



大神能不能解释一下,
41 44 43 30 3A 20 20
41 44 43 31 3A 20 20
41 44 43 32 3A 20 20
41 44 43 33 3A 20 20
41 44 43 34 3A 20 20
41 44 43 35 3A 20 20这个我是直接复制参考程序,不知道这些代表什么意思,

王昱顺 发表于 2025-8-8 21:30:10

平常心 发表于 2025-8-8 20:23
大神能不能解释一下,
41 44 43 30 3A 20 20
41 44 43 31 3A 20 20


看不出来,感觉不像adcdma的数据?里面没有ADC转换通道号啊

平常心 发表于 2025-8-9 08:32:59

这个是STC官方例程,
#include "config.h"
bit        B_ADC_DMA_busy;
bit        B_ADC_DMA_ok;

u16        xdata adc_tmp;       
//adc存放的数组, 为每次转换的值, 高字节为ADC通道号,低字节为取平均值后的余数,
//为平均值

void ADC_DMA_Init()
{
//P1n_HighZ(0x3b);        //设置要做ADC的IO做高阻输入, P1.0(ADC0) P1.1(ADC1) P1.3(ADC3) P1.4(ADC4) P1.5(ADC5)
        //P5n_HighZ(0x00);        //设置要做ADC的IO做高阻输入, P5.4(ADC2)
                ADC_CONTR = 0x80 + 0;        //ADC on + channel
        ADCCFG = RES_FMT + ADC_SPEED;
        ADCTIM = CSSETUP + CSHOLD + SMPDUTY;
       
        DMA_ADC_CFG= (1<<7) + (0<<2) + 0;        //bit7=1: 允许ADC_DMA中断, 0:禁止.bit3 bit2: ADC_DMA中断优先级(低0~3高), bit1 bit0: ADC_DMA数据总线访问优先级(低0~3高)
        DMA_ADC_STA= 0;                //bit0: ADC_DMA完成(中断请求)标志, 需要软件清0.
        DMA_ADC_CFG2 = 9;                //每个通道转换的次数, 0-->1次, 8-->2次, 9-->4次, 10-->8次, 11-->16次, 12-->32次, 13-->64次, 14-->128次, 15-->256次.
        DMA_ADC_CHSW1 = 0x00;        //ADC通道使能, bit7~bit0对应通道15~8.
        DMA_ADC_CHSW0 = 0x3f;        //ADC通道使能, bit7~bit0对应通道7~0.
}

void        ADC_DMA_TRIG(u16 xdata *AdcBuf)
{
        u16        i;

        if(B_ADC_DMA_busy)        return;                //DMA正忙则返回,避免重复触发
        i   = (u16)AdcBuf;                                //要发送数据的首地址
        DMA_ADC_RXAH   = (u8)(i >> 8);        //存放的地址高字节
        DMA_ADC_RXAL   = (u8)i;                        //存放的地址低字节
        DMA_ADC_STA    = 0;                //bit0: ADC_DMA完成(中断请求)标志, 需要软件清0.
        B_ADC_DMA_busy = 1;                //标志ADC-DMA忙,ADC DMA中断中清除此标志,使用ADC DMA前要确认此标志为0
        DMA_ADC_CR   = (1<<7) + (1<<6);                //启动ADC_DMA,bit7=1:允许ADC_DMA功能, 0:禁止.   bit6=1:触发ADC_DMA功能.
}


void ADC_DMA()
{
                u8        i,k;
          static u16        j = 0;
                delay_ms(1);
                if(++j >= 1000)        //每隔1000ms触发一次DMA_ADC
                {
                        j = 0;
                        ADC_DMA_TRIG(&adc_tmp);        //启动ADC_DMA
                }

                if(B_ADC_DMA_ok)        //已完成
                {
                        B_ADC_DMA_ok = 0;
                        for(i=0; i<CHANNELS; i++)
                        {
                                //printf("ADC%u:", adc_tmp>>8);        //打印通道号ADCn:
          printf("ADC%u:", adc_tmp);        //打印通道号ADCn:
                                for(k=0; k<COUNTS; k++)
                                {
                                        //printf("采样%u= ", (int)k);        //打印提示采样值序号 采样x
                                //        printf("%u,", adc_tmp);        //使用printf()发送,字符不对齐
                                        //Tx_u16(adc_tmp);                        //使用Tx_u16()发送,字符对齐
                                }
                                        //printf("平均值=%u.\r\n", adc_tmp);
                        }
                }
}



void ADC_DMA_Interrupt(void) interrupt 13
{
        DMA_ADC_STA = 0;        //清除ADC_DMA完成(中断请求)标志
        B_ADC_DMA_busy = 0;        //清除ADC-DMA忙标志
        B_ADC_DMA_ok   = 1;        //标志已完成
}
页: [1] 2
查看完整版本: ADC_DMA测多通道时通道之间会影响吗