当前位置:   article > 正文

STM32笔记--ADC(DMA方式)_stm32 adc dma 寄存器例程

stm32 adc dma 寄存器例程

    在上一次的博客中重新学习了DMA(附上链接:点击打开链接),这次我们便学以致用了,ADC的概念想必大家都是十分清楚了,模拟转数字,可以用在测信号,测电压,在我们的生活中有着十分巨大的作用,这次我们就来看看ADC又有哪些操作吧!

       ADC流程,首先ADC采集一个信号(信号范围大都为0-3.3V,ps:3.3V可通过更改Vref寄存器修改),每隔相同时间菜一次数值发送到一个可变16位数中,下面是我们的数组定义:

__IO uint16_t ADC_ConvertedValue;    //定义该16位数用来传输数据,原因是我们使用的12位AD,由于寄存器的定义方便,因此使用16位数

下面是ADC的初始化和配置代码:

  1. void ADC1_Init(void)
  2. {
  3. ADC1_GPIO_Config(); //下面有详细的代码配置
  4. ADC1_Mode_Config();
  5. }
  6. static void ADC1_GPIO_Config(void)
  7. {
  8. GPIO_InitTypeDef GPIO_InitStructure; //定义写入寄存器的结构体
  9. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能时钟,注意使能的是DMA1
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); //本实验使用的是GPIOC1,使能ADC1,GPIO时钟
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //配置为PC.1
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //设置为模拟输入
  13. GPIO_Init(GPIOC, &GPIO_InitStructure); // 初始化写入寄存器中
  14. }
  15. static void ADC1_Mode_Config(void)
  16. {
  17. DMA_InitTypeDef DMA_InitStructure; //定义写入DMA寄存器的结构体
  18. ADC_InitTypeDef ADC_InitStructure; //定义写入ADC寄存器的结构体
  19. DMA_DeInit(DMA1_Channel1); //复位初始化,配置为复位模式,下面我们再重新配置(不知道有用没)
  20. DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //设置源地址
  21. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //设置内存地址
  22. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置传输方向
  23. DMA_InitStructure.DMA_BufferSize = 1; //因为我们最后一直改变一个变量,所以只有一位
  24. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
  25. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址固定
  26. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设传输数据大小为半字
  27. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存传输数据大小为半字
  28. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式
  29. DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高优先级
  30. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止内存间传输数据
  31. DMA_Init(DMA1_Channel1, &DMA_InitStructure); //将结构体写入寄存器中
  32. DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA寄存器的1通道
  33. /* ADC1 configuration */
  34. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //因为只有一个通道,所以为独立ADC模式
  35. ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //一个通道,所以不使能扫描模式
  36. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换,就是不停转换
  37. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发,外部触发只有几个固定引脚,详情看手册
  38. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //我们定义16位数,采集12位,所以要定义对齐方向,在这我们采取右对齐
  39. ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目
  40. ADC_Init(ADC1, &ADC_InitStructure); 将结构体写入寄存器中
  41. RCC_ADCCLKConfig(RCC_PCLK2_Div8); //72M时钟8分频为9M PS:ADC最大时钟速率为14M,后面解释
  42. ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5); //初始化,采样时间为55.5us,采样序号是1,PS:采样时间最 // 为1.5us,转换时间为固定12.5us,所以相当于采集完一次数为14us
  43. ADC_DMACmd(ADC1, ENABLE); // 使能DMA1
  44. ADC_Cmd(ADC1, ENABLE); //使能ADC1
  45. ADC_ResetCalibration(ADC1); //复位校准寄存器
  46. while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准寄存器完成
  47. ADC_StartCalibration(ADC1); //ADC校准
  48. while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成
  49. ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1的软件触发
  50. }

以上就是我们用到的ADC的配置代码,若要读出ADC的数值,只需要调用我们的输出寄存器值就可完成,下面有个小例子,结合之前的串口通信代码,可将采集到的AD数值发送到电脑串口调试助手上

 
  1. while (1)
  2. {
  3. ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3; // 转化 PS:将0-3.3分成4096份,ADC读出的是多少份,所以以这 //样计算
  4. printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertedValue);
  5. printf("\r\n The current AD value = %f V \r\n",ADC_ConvertedValueLocal); //打印,USART代码 链接:点击打开链接
  6. Delay(0xffffee); //延时
  7. }



以上,有问题或有建议的同学可在下面评论或者私信我,我都会看的哈哈!


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/888774
推荐阅读
相关标签
  

闽ICP备14008679号