打印

关于AD多通道采集的总结

[复制链接]
3640|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fmj2008|  楼主 | 2008-8-30 21:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

前几天小试了下,用STM32做了个万用表,采集电压电流电阻并液晶显示。
期间遇到一个最大的问题应该就是,要开启多个AD通道,结合DMA传输,小结下
下面是我对AD的配置,还有DMA
void DMA_ADC_Config()
{
      /* DMA channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA_Channel1);//复位DMA通道x
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address;//定义 DMA通道外设基地址=ADC1_DR_Address     源
                                                              //AD采集到的数据存放的寄存器
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab;//定义DMA通道存储器地址,内存中的数据 目的
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设为源地址
  DMA_InitStructure.DMA_BufferSize = 4;//定义DMA缓冲区大小4,4路AD,最后采集到的数值放在4位数组中
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//当前外设寄存器地址不变
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//当前存储器地址递增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度16位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//定义存储器数据宽度16位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA通道操作模式位环形缓冲模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道优先级高
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止DMA通道存储器到存储器传输
  DMA_Init(DMA_Channel1, &DMA_InitStructure);//初始化DMA通道1
  DMA_Cmd(DMA_Channel1, ENABLE);//使能DMA通道1  
  
}

void ADC1_config()
{
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//AD转换模式
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;//使能扫描,多通道
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;;//有软件控制转换
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
  ADC_InitStructure.ADC_NbrOfChannel = 4;//转换通道为通道4,4个通道来回扫描
  ADC_Init(ADC1, &ADC_InitStructure);
  /* ADC1 regular channel14 configuration */
  //ADC1选择信道14|15,采集次序1,采样时间55.5个周期
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); //通道14,PC4 扫面顺序1   
  ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_55Cycles5); 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5);   
}

DMA其实开一个就够了,它可以定义缓冲区大小,然后配置成
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//当前存储器地址递增

这样就可以传递多个数据,我是定义了一个数组
vu16 ADC_RegularConvertedValueTab[4];
AD采集到的值放在寄存器ADC_DR_Address    ((u32)0x4001244C)中,
每次采集好后DMA把数据取到数组中,接下去配置AD的时候采用扫描模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;//使能扫描,多通道
多个通道在下面开启,并配置顺序
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); //通道14,PC4 扫面顺序1   
  ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_55Cycles5); 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5); 
这样AD就来回采集通道 14 15 6 4 结合DMA后把数据存在刚才定义的数组中。
以上是心得,下面是一些疑问
1.在配置GPIO的时候我把AD口配成了输出模式,但是后来我把这段注释掉,采集还是一样没错误。难道可以不用配的?
2.AD有两个大的模式,一个是规则一个是注入,看了很久还是不明白这两个到底具体各代表什么
3.学习板光盘上面的DEMO烧进去,好像一直跳的很厉害,不知道如何才能稳下来,我是采用多次取值采用平均值,效果还可以,但是好像比较耗资源。
沙发
violet520| | 2008-9-1 10:46 | 只看该作者

LZ自己的AD采样稳定吗?

使用特权

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

本版积分规则

6

主题

24

帖子

1

粉丝