STM32F1双ADC慢速交替模式,软件触发AD转换

2019-10-15 06:22发布

本帖最后由 ljmf5 于 2017-1-21 10:56 编辑
前几天,发现STM32的ADC还有双模式,就自己学了一下。基本上能实现对同一通道的慢速交叉采样。这里使用软件触发,硬件触发还没想明白怎么搞
第一次发分享帖,心中还有点小兴奋
下面直接贴代码,工程文件见附件,要做这个的坛友们可以互相学习一下,也还有些问题没搞清楚


[mw_shl_code=c,true]#include "stm32f10x.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"  //我写代码,总是要添加这些固件库头文件,不知道哪里有疏漏?
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "dma.h"
#include "ad.h"
#include "timer.h"

//DMA的内存地址
u32 DMA_buffer;

int main(void)
{        

        delay_init();
        uart_init(9600);
        DMA_initial(DMA1_Channel1, (u32)&ADC1->DR, (u32)&DMA_buffer, 1);
        
        ADC12_init();
        
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);

//        ADC_SoftwareStartConvCmd(ADC2, ENABLE); // 这一句无论是否添加,输出的结果是一样的,
                                                                                        //具体也不知道会不会有什么运行机制上的差别?
        DMA_start(DMA1_Channel1,1);
        
        
        printf("1111 ");
        while(1)
        {
                printf("2222 ");
                DMA_start(DMA1_Channel1,1);
                while(DMA_GetFlagStatus(DMA1_FLAG_TC1))        //等待DMA传输完成
                {
                   DMA_ClearFlag(DMA1_FLAG_TC1);                        //清楚中断完成标志
                         printf("ADC1:%d, %f ", ADC1->DR, ADC1->DR*3.3/4096);        
                   printf("ADC2:%d, %f ",ADC2->DR,ADC2->DR*3.3/4096);
                         printf("DMA_buffer:%d, %f ",DMA_buffer, (DMA_buffer)*3.3/4096);        
                   printf("ADC1:%d, %f ",DMA_buffer&0x0000ffff, (DMA_buffer&0x0000ffff)*3.3/4096);        
                   printf("ADC2:%d, %f ",((DMA_buffer>>16)&0x0000ffff),((DMA_buffer>>16)&0x0000ffff)*3.3/4096);        
                   printf(" -------------------------------------------------- ");        
                }         
        }
}
[/mw_shl_code]



[mw_shl_code=c,true]void ADC12_init(void)
{
        //通道IO初始化
        GPIO_InitTypeDef  GPIO_InitStructure;
        ADC_InitTypeDef  ADC_InitStructure;
        //使能PA、ADC1时钟和ADC2时钟,最开始忘记了使能ADC2的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);         
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                 //PA0
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;         //模拟输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
        GPIO_Init(GPIOA, &GPIO_InitStructure);         //根据设定参数初始化GPIOA0

        //复位ADC1,并设置ADC分频因子
        ADC_DeInit(ADC1);
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频,72/6=12MHz
        
        //ADC1相关参数配置
        ADC_InitStructure.ADC_ScanConvMode= DISABLE; //只有1个通道,不在通道件切换
        ADC_InitStructure.ADC_ContinuousConvMode= DISABLE; //连续扫描
        ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right;//右对齐
        ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None;//不使用外部触发
        ADC_InitStructure.ADC_Mode= ADC_Mode_SlowInterl;//规则通道 慢速交叉模式
        ADC_InitStructure.ADC_NbrOfChannel= 1;//只有1个通道,不需要设置规则通道组的次序
        ADC_Init(ADC1, &ADC_InitStructure);        
        //配置ADC1采样时间及RANK等相关参数
        ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
        
        
        //复位ADC2,并设置ADC分频因子
        ADC_DeInit(ADC2);
//        RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频,72/6=12MHz
        //ADC2相关参数配置
        ADC_InitStructure.ADC_ScanConvMode= DISABLE; //只有1个通道,不在通道件切换
        ADC_InitStructure.ADC_ContinuousConvMode= DISABLE; //连续扫描
        ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right;//右对齐
        ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None;//不使用外部触发
        ADC_InitStructure.ADC_Mode= ADC_Mode_SlowInterl;//规则通道 慢速交叉模式
        ADC_InitStructure.ADC_NbrOfChannel= 1;//只有1个通道,不需要设置规则通道组的次序
        ADC_Init(ADC2, &ADC_InitStructure);
        //配置ADC2采样时间及RANK等相关参数
        ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
        //使能ADC1的DMA传输
        ADC_DMACmd(ADC1, ENABLE);
        //使能并校准ADC1
        ADC_Cmd(ADC1, ENABLE);//使能ADC1
        ADC_ResetCalibration(ADC1);//复位校准ADC1
        while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准ADC1
        ADC_StartCalibration(ADC1);//校准ADC1
        while(ADC_GetCalibrationStatus(ADC1));//等待校准ADC1
        //使能并校准ADC2
        ADC_Cmd(ADC2, ENABLE);//使能ADC2
        ADC_ResetCalibration(ADC2);//复位校准ADC2
        while(ADC_GetResetCalibrationStatus(ADC2));//等待复位校准ADC2
        ADC_StartCalibration(ADC2);//校准ADC1
        while(ADC_GetCalibrationStatus(ADC2));//等待校准ADC2
        
        //使能ADC2外部触发转换
        ADC_ExternalTrigConvCmd(ADC2, ENABLE);//不加这个就会导致数据错误,
                                                                //ADC2->DR 和DMA_buffer>>16均有问题,而且这两个值还不相等
                                                                 //不知道这是为什么?
}[/mw_shl_code]



[mw_shl_code=c,true]
#include "dma.h"
#include "stm32f10x_dma.h" //这里也是,不添加就会提示错误?

extern u32 DMA_buffer;

//DMA1--通道1--ADC1
//外设基地址ADC1->DR
//内存基地址

void DMA_initial(DMA_Channel_TypeDef* DMAy_Channelx, u32 cpar, u32 cmar, u16 count)
{
        DMA_InitTypeDef  DMA_InitStructure;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA时钟
        DMA_DeInit(DMAy_Channelx);
        DMA_InitStructure.DMA_M2M= DMA_M2M_Disable; //非内存到内存
        DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;//外设为数据源
        DMA_InitStructure.DMA_PeripheralBaseAddr= cpar; //外设数据地址
        DMA_InitStructure.DMA_PeripheralDataSize= DMA_PeripheralDataSize_Word; //外设的数据尺寸为字,即32位
        DMA_InitStructure.DMA_PeripheralInc= DMA_PeripheralInc_Disable; //外设地址不自增
        DMA_InitStructure.DMA_MemoryBaseAddr= cmar; //内存数据存储地址
        DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_Word; //DMA接收的数据尺寸为字,即32位
        DMA_InitStructure.DMA_MemoryInc= DMA_MemoryInc_Disable; //DMA内存接受地址不自增
        DMA_InitStructure.DMA_Mode= DMA_Mode_Normal ;//DMA工作在正常缓存模式
        DMA_InitStructure.DMA_BufferSize= count; //设置接收的数据量为1
        DMA_InitStructure.DMA_Priority= DMA_Priority_Medium;//中等优先级
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);
}

void DMA_start(DMA_Channel_TypeDef* DMAy_Channelx, u16 count)
{
        DMA_Cmd(DMAy_Channelx, DISABLE);
        DMA_SetCurrDataCounter(DMAy_Channelx, count);
        DMA_Cmd(DMAy_Channelx, ENABLE);
}
[/mw_shl_code]


0条回答

一周热门 更多>