STM32 ADC模数转换

STM32 ADC模数转换

独立模式/双重DMA/三重DMA

//使能ADC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//APB2时钟为72MHz
//ADCCLK时钟最大为14MHz
//设置ADC分频因子6 72M/6=12MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div6);

ADC_DeInit(ADC1);                                                 //复位ADC1
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;                   //单个ADC工作时配置为独立模式
ADC_InitStruct.ADC_ScanConvMode = ENABLE;                         //扫描模式--多通道使能
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;                   //单次转换模式/连续转换模式
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  //硬件触发/软件触发
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;               //数据左对齐/右对齐
ADC_InitStruct.ADC_NbrOfChannel = 7;                              //7通道
ADC_Init(ADC1, &ADC_InitStruct);

//配置ADC转换顺序和采样周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 7, ADC_SampleTime_239Cycles5);
//使能软件触发
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
//使能DMA
ADC_DMACmd(ADC1, ENABLE);
//使能ADC
ADC_Cmd(ADC1, ENABLE);
//复位ADC
ADC_ResetCalibration(ADC1);
//获取ADC重置校准寄存器的状态 等待复位结束
while (ADC_GetResetCalibrationStatus(ADC1));
//开始指定ADC的校准状态
ADC_StartCalibration(ADC1);

while (ADC_GetCalibrationStatus(ADC1));

ADC_ExternalTrigConvCmd(ADC1, ENABLE);

触发方式

外部边沿触发适合周期性采集信号;而软件触发适合不定时任意时刻采集信号。

  • 软件触发
    当ADC转换设置为软件触发时,无需设置触发源,转换开始后硬件会将控制位SWSTART清零,软件会自动将控制位SWSTART置1。
 ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;                   //连续转换模式
 ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  • 定时器+外部边沿触发
    只有上升沿才会触发ADC转换。
    当ADC转换设置为外部边沿触发时,需要设置触发源。
    在这里插入图片描述
 ADC_ExternalTrigConvCmd(ADC1, ENABLE);

定时器+ADC+DMA传输方式

  • 采用定时器触发方式,ADC的转换时间由定时器周期决定。
  • 当ADC有多通道,DMA buffer传输时,ADC的转换时间由定时器周期和各通道采集次数有关。
初始化定时器代码 TIM4-CH4 PB9

void TIM4_Init(u16 arr,u16 psc,u16 pulse)
{
    //定义结构体
    GPIO_InitTypeDef  GPIO_InitStruct;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
    TIM_OCInitTypeDef  TIM_OCInitStruct;

    //使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	//初始化引脚
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
	
    TIM_DeInit(TIM4);
    //初始化时基
    TIM_TimeBaseStruct.TIM_Period = arr;
    TIM_TimeBaseStruct.TIM_Prescaler = psc;
    TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);

    //通道4
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse = pulse;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC4Init(TIM4, &TIM_OCInitStruct);

    /*使能通道4重载*/
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);

    //使能定时器
    TIM_Cmd(TIM4, ENABLE);

    //使能TIM2在ARR上的预装载寄存器
    TIM_ARRPreloadConfig(TIM4, ENABLE);

    //设置PMW主输出
    TIM_CtrlPWMOutputs(TIM4, ENABLE);
}
初始化ADC+DMA
u16 digital_data[10][5] = {0};
void ADC1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    ADC_InitTypeDef ADC_InitStruct;
    DMA_InitTypeDef DMA_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    //初始化GPIO--PA1 PA2 PA3 PA4 PA5
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    //初始化ADC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    //APB2时钟为72MHz
    //ADCCLK时钟最大为14MHz
    //设置ADC分频因子6 72M/6=12MHz
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);

    ADC_DeInit(ADC1);                                                 //复位ADC1
    ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;                   //独立模式
    ADC_InitStruct.ADC_ScanConvMode = ENABLE;                         //多通道使能
    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;                  //关闭连续转换模式
    ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;//软件触发
    ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;               //数据右对齐
    ADC_InitStruct.ADC_NbrOfChannel = 5;                              //5通道
    ADC_Init(ADC1, &ADC_InitStruct);

    //配置ADC转换顺序和采样周期
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_239Cycles5);
    //使能硬件触发
	ADC_ExternalTrigConvCmd(ADC1, ENABLE);
	//使能DMA
    ADC_DMACmd(ADC1, ENABLE);
    //使能ADC
    ADC_Cmd(ADC1, ENABLE);
    //复位ADC
    ADC_ResetCalibration(ADC1);
    //获取ADC重置校准寄存器的状态 等待复位结束
    while(ADC_GetResetCalibrationStatus(ADC1));
    //开始指定ADC的校准状态
    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1));
    //使能软件触发
	ADC_ExternalTrigConvCmd(ADC1, ENABLE);
	
    //外设ADC1请求信号经过通道1到达DMA1
    //初始化DMA1_Channel1
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(0x40012400+0x4c);   //ADC数据寄存器
    DMA_InitStruct.DMA_MemoryBaseAddr = (u32)(digital_data);
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;                   //外设到存储器
    DMA_InitStruct.DMA_BufferSize = 50;                               //转换10次
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;     //外设地址不变
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;              //存储器地址递增
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStruct.DMA_Priority = DMA_Priority_High;
    DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStruct);

    //使能DMA请求
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
    DMA_Cmd(DMA1_Channel1, ENABLE);

    //设置DMA中断
    NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
}

规则通道和注入通道

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Paper_Love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值