当前位置:   article > 正文

STM32 7-8

STM32 7-8

目录

ADC

AD单通道

AD多通道

DMA

DMA转运数据

DMA+AD多通道


ADC

AD单通道

AD.c

  1. #include "stm32f10x.h" // Device header
  2. /**
  3. * @brief 初始化AD所需要的所有设备
  4. * @param 无
  5. * @retval 无
  6. */
  7. void AD_Init(void)
  8. {
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  11. RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADCCLK为六分频
  12. GPIO_InitTypeDef GPIO_InitStructure;
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
  14. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  15. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16. GPIO_Init(GPIOA,&GPIO_InitStructure);
  17. ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1, ADC_SampleTime_55Cycles5);//配置输入通道
  18. //所选ADC设备,指定ADC通道,规则组序列器中的次序,指定通道采样时间(更快就选小参数,更稳定就选大参数)
  19. //初始化ADC
  20. ADC_InitTypeDef ADC_InitStructure;
  21. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式
  22. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐
  23. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择
  24. //单通道单次转换非扫描模式
  25. //单通道连续转换,非扫描模式
  26. ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数目
  27. ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描转换模式
  28. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//非连续转换模式
  29. //ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换模式
  30. ADC_Init(ADC1,&ADC_InitStructure);
  31. ADC_Cmd(ADC1,ENABLE);//开启ADC1
  32. //进行ADC校准
  33. ADC_ResetCalibration(ADC1);//复位校准
  34. while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成
  35. ADC_StartCalibration(ADC1);//开始校准
  36. while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
  37. //ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
  38. }
  39. /**
  40. * @brief 获取AD所得值
  41. * @param 无
  42. * @retval 转化出来的数据量最大为4095
  43. */
  44. uint16_t AD_GetValue(void)
  45. {
  46. ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
  47. while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//获取标志位状态(为Reset表示没有转换完成)
  48. //大约等待 (1 / 72MHz / 6) X (55.5 + 12.5) = 5.6us
  49. return ADC_GetConversionValue(ADC1);//调用后会自动清除EOC标志位
  50. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "AD.h"
  5. uint16_t ADValue;
  6. float Voltage;
  7. int main(void)
  8. {
  9. OLED_Init();
  10. AD_Init();
  11. OLED_ShowString(1,1,"ADValue:");
  12. OLED_ShowString(2,1,"Voltage:0.00V");
  13. while(1)
  14. {
  15. ADValue = AD_GetValue();
  16. Voltage = (float)ADValue / 4095 * 3.3;
  17. OLED_ShowNum(1,9,ADValue,4);
  18. OLED_ShowNum(2,9,Voltage,1);//输出整数部分
  19. OLED_ShowNum(2,11,(uint16_t)(Voltage * 100) % 100,2);//输出小数部分
  20. Delay_ms(100);
  21. }
  22. }
AD多通道

AD.c

  1. #include "stm32f10x.h" // Device header
  2. /**
  3. * @brief 初始化AD所需设备
  4. * @param 无
  5. * @retval 无
  6. */
  7. void AD_Init(void)
  8. {
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  11. RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADCCLK为六分频
  12. GPIO_InitTypeDef GPIO_InitStructure;
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
  14. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  15. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16. GPIO_Init(GPIOA,&GPIO_InitStructure);
  17. //初始化ADC
  18. ADC_InitTypeDef ADC_InitStructure;
  19. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式
  20. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐
  21. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择
  22. //单通道单次转换非扫描模式
  23. ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数目
  24. ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描转换模式
  25. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//非连续转换模式
  26. ADC_Init(ADC1,&ADC_InitStructure);
  27. ADC_Cmd(ADC1,ENABLE);//开启ADC1
  28. //进行ADC校准
  29. ADC_ResetCalibration(ADC1);//复位校准
  30. while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成
  31. ADC_StartCalibration(ADC1);//开始校准
  32. while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
  33. }
  34. /**
  35. *@brief 通过传入不同ADC通道,实现多通道AD,本质还是单通道
  36. *@param ADC_Channel:所选通道
  37. *@retval 转化出的数据量最大为4095
  38. */
  39. uint16_t AD_GetValue(uint8_t ADC_Channel)
  40. {
  41. ADC_RegularChannelConfig(ADC1,ADC_Channel,1, ADC_SampleTime_55Cycles5);//配置输入通道
  42. //所选ADC设备,指定ADC通道,规则组序列器中的次序,指定通道采样时间(更快就选小参数,更稳定就选大参数)
  43. ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
  44. while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//获取标志位状态(为Reset表示没有转换完成)
  45. //大约等待 (1 / 72MHz / 6) X (55.5 + 12.5) = 5.6us
  46. return ADC_GetConversionValue(ADC1);//调用后会自动清除EOC标志位
  47. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "AD.h"
  5. uint16_t AD0,AD1,AD2,AD3;
  6. int main(void)
  7. {
  8. OLED_Init();
  9. AD_Init();
  10. OLED_ShowString(1,1,"AD0:");
  11. OLED_ShowString(2,1,"AD1:");
  12. OLED_ShowString(3,1,"AD2:");
  13. OLED_ShowString(4,1,"AD3:");
  14. while(1)
  15. {
  16. AD0 = AD_GetValue(ADC_Channel_0);
  17. AD1 = AD_GetValue(ADC_Channel_1);
  18. AD2 = AD_GetValue(ADC_Channel_2);
  19. AD3 = AD_GetValue(ADC_Channel_3);
  20. OLED_ShowNum(1,5,AD0,4);
  21. OLED_ShowNum(2,5,AD1,4);
  22. OLED_ShowNum(3,5,AD2,4);
  23. OLED_ShowNum(4,5,AD3,4);
  24. Delay_ms(100);
  25. }
  26. }

DMA

DMA转运数据

MyDMA.c

  1. #include "stm32f10x.h" // Device header
  2. uint16_t MyDMA_Size;
  3. /**
  4. * @brief 初始化DMA
  5. * @param AddrA:外设起始地址
  6. * @param AddrB:存储器起始地址
  7. * @param Size:传输次数
  8. * @retval 无
  9. */
  10. void MyDMA_Init(uint32_t AddrA,uint32_t AddrB,uint16_t Size)
  11. {
  12. MyDMA_Size = Size;
  13. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//开启MDA1时钟
  14. DMA_InitTypeDef DMA_InitStructrue;
  15. DMA_InitStructrue.DMA_PeripheralBaseAddr = AddrA;//外设起始地址
  16. DMA_InitStructrue.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据宽度
  17. DMA_InitStructrue.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//外设是否自增
  18. DMA_InitStructrue.DMA_MemoryBaseAddr = AddrB;//存储器起始地址
  19. DMA_InitStructrue.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte ;//存储器数据宽度
  20. DMA_InitStructrue.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器是否自增
  21. DMA_InitStructrue.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向(外设作为源头)
  22. DMA_InitStructrue.DMA_BufferSize = Size;//传输计数器(传输次数)
  23. DMA_InitStructrue.DMA_Mode = DMA_Mode_Normal;//传输模式,是否使用自动重装(转运后停止)
  24. DMA_InitStructrue.DMA_M2M = DMA_M2M_Enable;//选择硬件触发,还是软件触发(软件触发)
  25. DMA_InitStructrue.DMA_Priority = DMA_Priority_Medium;//优先级(多个通道进行配置)
  26. DMA_Init(DMA1_Channel1,&DMA_InitStructrue);
  27. DMA_Cmd(DMA1_Channel1,DISABLE);//不让DMA初始化后立刻转运
  28. }
  29. /**
  30. * @brief 将外设数据通过DMA写入存储器
  31. * @param 无
  32. * @retval 无
  33. */
  34. void MyDMA_Transfer(void)
  35. {
  36. DMA_Cmd(DMA1_Channel1,DISABLE);//为传输计数器赋值,需先失能DMA
  37. DMA_SetCurrDataCounter(DMA1_Channel1,MyDMA_Size);//重新给传输计数器写入值
  38. DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA
  39. while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//检查DMA1通道1转换完成的标志位(完成标志位置一)
  40. //未完成则一直空循环等待
  41. DMA_ClearFlag(DMA1_FLAG_TC1);//需要手动清除标志位
  42. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "MyDMA.h"
  5. uint8_t DataA[] = {0x01,0x02,0x03,0x04};
  6. uint8_t DataB[] = {0,0,0,0};
  7. uint8_t i;
  8. int main(void)
  9. {
  10. OLED_Init();
  11. MyDMA_Init((uint32_t)DataA,(uint32_t)DataB,4);//DataA 转运至 Data
  12. OLED_ShowString(1,1,"DataA");
  13. OLED_ShowString(3,1,"DataA");
  14. OLED_ShowHexNum(1,8,(uint32_t)DataA,8);
  15. OLED_ShowHexNum(3,8,(uint32_t)DataB,8);
  16. for(i = 0;i < 4;i++)
  17. {
  18. OLED_ShowHexNum(2,3*i+1,DataA[i],2);
  19. }
  20. for(i = 0;i < 4;i++)
  21. {
  22. OLED_ShowHexNum(4,3*i+1,DataB[i],2);
  23. }
  24. while(1)
  25. {
  26. DataA[0] ++;
  27. DataA[1] ++;
  28. DataA[2] ++;
  29. DataA[3] ++;
  30. for(i = 0;i < 4;i++)
  31. {
  32. OLED_ShowHexNum(2,3*i+1,DataA[i],2);
  33. }
  34. for(i = 0;i < 4;i++)
  35. {
  36. OLED_ShowHexNum(4,3*i+1,DataB[i],2);
  37. }
  38. Delay_s(1);
  39. MyDMA_Transfer();//开始转运
  40. for(i = 0;i < 4;i++)
  41. {
  42. OLED_ShowHexNum(2,3*i+1,DataA[i],2);
  43. }
  44. for(i = 0;i < 4;i++)
  45. {
  46. OLED_ShowHexNum(4,3*i+1,DataB[i],2);
  47. }
  48. Delay_s(1);
  49. }
  50. }
DMA+AD多通道

AD.c

  1. #include "stm32f10x.h" // Device header
  2. uint16_t AD_Value[4];
  3. /**
  4. * @brief 初始化AD以及DMA
  5. * @param 无
  6. * @retval 无
  7. */
  8. void AD_Init(void)
  9. {
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  12. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//开启MDA1时钟
  13. RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADCCLK为六分频
  14. GPIO_InitTypeDef GPIO_InitStructure;
  15. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  17. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  18. GPIO_Init(GPIOA,&GPIO_InitStructure);
  19. ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1, ADC_SampleTime_55Cycles5);//配置输入通道
  20. ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2, ADC_SampleTime_55Cycles5);//配置输入通道
  21. ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3, ADC_SampleTime_55Cycles5);//配置输入通道
  22. ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4, ADC_SampleTime_55Cycles5);//配置输入通道
  23. //所选ADC设备,指定ADC通道,规则组序列器中的次序,指定通道采样时间(更快就选小参数,更稳定就选大参数)
  24. //初始化ADC
  25. ADC_InitTypeDef ADC_InitStructure;
  26. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式
  27. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐
  28. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择
  29. //ADC扫描模式+数据转运
  30. //ADC连续扫描+DMA循环转运
  31. ADC_InitStructure.ADC_NbrOfChannel = 4;//通道数目
  32. ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描转换模式(设置为扫描模式)
  33. //ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//是否为连续模式
  34. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  35. ADC_Init(ADC1,&ADC_InitStructure);
  36. //配置DMA
  37. DMA_InitTypeDef DMA_InitStructrue;
  38. DMA_InitStructrue.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设起始地址
  39. DMA_InitStructrue.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度(16位)
  40. DMA_InitStructrue.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设是否自增(始终转运同一位置数据)
  41. DMA_InitStructrue.DMA_MemoryBaseAddr = (uint32_t)AD_Value;//存储器起始地址
  42. DMA_InitStructrue.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据宽度
  43. DMA_InitStructrue.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器是否自增
  44. DMA_InitStructrue.DMA_DIR = DMA_DIR_PeripheralSRC;//传输方向(外设作为源头)
  45. DMA_InitStructrue.DMA_BufferSize = 4;//传输计数器(传输次数)
  46. //DMA_InitStructrue.DMA_Mode = DMA_Mode_Normal;//传输模式,是否使用自动重装(转运后停止)
  47. DMA_InitStructrue.DMA_Mode = DMA_Mode_Circular;//循环模式
  48. DMA_InitStructrue.DMA_M2M = DMA_M2M_Disable;//选择硬件触发,还是软件触发(硬件触发)
  49. DMA_InitStructrue.DMA_Priority = DMA_Priority_Medium;//优先级(多个通道进行配置)
  50. DMA_Init(DMA1_Channel1,&DMA_InitStructrue);//这里的通道必须使用DMA1_Channel1,详情查表
  51. DMA_Cmd(DMA1_Channel1,ENABLE);//让DMA初始化后立刻转运
  52. ADC_DMACmd(ADC1,ENABLE);//开启ADC触发DMA信号
  53. ADC_Cmd(ADC1,ENABLE);//开启ADC1
  54. //进行ADC校准
  55. ADC_ResetCalibration(ADC1);//复位校准
  56. while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待复位校准完成
  57. ADC_StartCalibration(ADC1);//开始校准
  58. while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校准完成
  59. ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
  60. }
  61. /**
  62. *@brief 通过传入不同ADC通道,实现多通道AD,本质还是单通道
  63. *@param ADC_Channel:所选通道
  64. *@retval 转化出的数据量最大为4095
  65. */
  66. //void AD_GetValue(void)
  67. //{
  68. // DMA_Cmd(DMA1_Channel1,DISABLE);//为传输计数器赋值,需先失能DMA
  69. // DMA_SetCurrDataCounter(DMA1_Channel1,4);//重新给传输计数器写入值
  70. // DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA
  71. //
  72. // //ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启软件触发转换
  73. //
  74. // while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//检查DMA1通道1转换完成的标志位(完成标志位置一)
  75. // //未完成则一直空循环等待
  76. // DMA_ClearFlag(DMA1_FLAG_TC1);//需要手动清除标志位
  77. //}

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "AD.h"
  5. int main(void)
  6. {
  7. OLED_Init();
  8. AD_Init();
  9. OLED_ShowString(1,1,"AD0:");
  10. OLED_ShowString(2,1,"AD1:");
  11. OLED_ShowString(3,1,"AD2:");
  12. OLED_ShowString(4,1,"AD3:");
  13. while(1)
  14. {
  15. //AD_GetValue();
  16. OLED_ShowNum(1,5,AD_Value[0],4);
  17. OLED_ShowNum(2,5,AD_Value[1],4);
  18. OLED_ShowNum(3,5,AD_Value[2],4);
  19. OLED_ShowNum(4,5,AD_Value[3],4);
  20. Delay_ms(100);
  21. }
  22. }

7

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

闽ICP备14008679号