1. 本块代码实现了定时器定时触发ADC,多通道采样,并通过DMA进行数据传输到内存的操作。
  2. #include    "adc.h"
[cpp] view plaincopy
  1. #define DMA_BUFFER_SIZE     6
  2. uint8 sample_finish = 0;
  3. int16 adc_dma_tab[6] = { 0 };
  4. uint8 sample_index = 0;
  5. //采样点数据
  6. int16 sample_1[128] = { 0 };
  7. int16 sample_2[128] = { 0 };
  8. int16 sample_3[128] = { 0 };
  9. int16 sample_4[128] = { 0 };
  10. int16 sample_5[128] = { 0 };
  11. int16 sample_6[128] = { 0 };
  12. void user_adc_init()
  13. {
  14. adc_gpio_init();
  15. adc_config();               // 注意此处的初始化顺序,否则采样传输的数据容易出现数据错位的结果
  16. adc_dma_init();             //
  17. adc_timer_init();           //
  18. }
  19. void adc_config()
  20. {
  21. ADC_InitTypeDef adc_init_structure;
  22. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);            //使能ADC时钟
  23. ADC_DeInit(ADC1);                                               //复位ADC
  24. ADC_StructInit(&adc_init_structure);                            //初始化ADC结构体
  25. adc_init_structure.ADC_ContinuousConvMode = DISABLE;            //禁用连续转换模式
  26. adc_init_structure.ADC_DataAlign = ADC_DataAlign_Right;         //采样数据右对齐
  27. adc_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; //外部触发设置为TIM2
  28. adc_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;//上升沿触发
  29. adc_init_structure.ADC_Resolution = ADC_Resolution_12b;         //12位分辨率
  30. adc_init_structure.ADC_ScanDirection = ADC_ScanDirection_Upward;//向上扫描0-18通道
  31. ADC_Init(ADC1, &adc_init_structure);
  32. ADC_OverrunModeCmd(ADC1, ENABLE);                               //使能数据覆盖模式
  33. ADC_ChannelConfig(ADC1, ADC_Channel_0 | ADC_Channel_1 | ADC_Channel_2
  34. | ADC_Channel_8 | ADC_Channel_14 | ADC_Channel_15,
  35. ADC_SampleTime_13_5Cycles);               //配置采样通道,采样时间125nS
  36. ADC_GetCalibrationFactor(ADC1);                                 //使能前校准ADC
  37. ADC_Cmd(ADC1, ENABLE);                                          //使能ADC1
  38. while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET);         //等待ADC1使能完成
  39. ADC_DMACmd(ADC1, ENABLE);                                       //使能ADC_DMA
  40. ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);           //配置DMA请求模式为循环模式
  41. ADC_StartOfConversion(ADC1);                                    //开启一次转换(必须)
  42. }
  43. void adc_gpio_init()
  44. {
  45. GPIO_InitTypeDef gpio_init_structure;
  46. //使能GPIO时钟
  47. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);
  48. GPIO_StructInit(&gpio_init_structure);
  49. //GPIOA                                                         //PA-0~3用作ADC
  50. gpio_init_structure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);
  51. gpio_init_structure.GPIO_Mode = GPIO_Mode_AN;                   //使用附加(模拟)功能
  52. gpio_init_structure.GPIO_OType = GPIO_OType_PP;                 //推挽输出
  53. gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz;              //Fast speed
  54. gpio_init_structure.GPIO_PuPd= GPIO_PuPd_UP;                    //上拉
  55. GPIO_Init(GPIOA, &gpio_init_structure);
  56. //GPIOB
  57. gpio_init_structure.GPIO_Pin = GPIO_Pin_0;                      //PB-0 用作ADC
  58. GPIO_Init(GPIOB, &gpio_init_structure);
  59. //GPIOC
  60. gpio_init_structure.GPIO_Pin = (GPIO_Pin_4 | GPIO_Pin_5);       //PC-4~5用作ADC
  61. GPIO_Init(GPIOC, &gpio_init_structure);
  62. }
  63. void adc_dma_init()
  64. {
  65. DMA_InitTypeDef dma_init_structure;
  66. NVIC_InitTypeDef nvic_init_structure;
  67. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);              //使能DMA时钟
  68. nvic_init_structure.NVIC_IRQChannel = DMA1_Channel1_IRQn;       //选择DMA1通道中断
  69. nvic_init_structure.NVIC_IRQChannelCmd = ENABLE;                //中断使能
  70. nvic_init_structure.NVIC_IRQChannelPriority = 0;                //优先级设为0
  71. NVIC_Init(&nvic_init_structure);
  72. DMA_DeInit(DMA1_Channel1);                                      //复位DMA1_channel1
  73. DMA_StructInit(&dma_init_structure);                            //初始化DMA结构体
  74. dma_init_structure.DMA_BufferSize = DMA_BUFFER_SIZE;            //DMA缓存数组大小设置
  75. dma_init_structure.DMA_DIR = DMA_DIR_PeripheralSRC;             //DMA方向:外设作为数据源
  76. dma_init_structure.DMA_M2M = DISABLE;                           //内存到内存禁用
  77. dma_init_structure.DMA_MemoryBaseAddr = (uint32)&adc_dma_tab[0];//缓存数据数组起始地址
  78. dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据大小设置为Halfword
  79. dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable;        //内存地址递增
  80. dma_init_structure.DMA_Mode = DMA_Mode_Circular;                //DMA循环模式,即完成后重新开始覆盖
  81. dma_init_structure.DMA_PeripheralBaseAddr = (uint32) &(ADC1->DR);//取值的外设地址
  82. dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设取值大小设置为Halfword
  83. dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址递增禁用
  84. dma_init_structure.DMA_Priority = DMA_Priority_High;             //DMA优先级设置为高
  85. DMA_Init(DMA1_Channel1, &dma_init_structure);
  86. DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);                  //使能DMA中断
  87. DMA_ClearITPendingBit(DMA_IT_TC);                                //清除一次DMA中断标志
  88. DMA_Cmd(DMA1_Channel1, ENABLE);                                  //使能DMA1
  89. }
  90. void adc_timer_init()
  91. {
  92. TIM_TimeBaseInitTypeDef timer_init_structure;
  93. NVIC_InitTypeDef nvic_init_structure;
  94. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);            //使能TIM2时钟
  95. nvic_init_structure.NVIC_IRQChannel = TIM2_IRQn;                //选择TIM2中断通道
  96. nvic_init_structure.NVIC_IRQChannelCmd = ENABLE;                //使能TIM2中断
  97. nvic_init_structure.NVIC_IRQChannelPriority = 0;                //优先级为0
  98. NVIC_Init(&nvic_init_structure);
  99. TIM_DeInit(TIM2);                                               //复位TIM2
  100. TIM_TimeBaseStructInit(&timer_init_structure);                  //初始化TIMBASE结构体
  101. timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1;          //系统时钟,不分频,48M
  102. timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up;      //向上计数模式
  103. timer_init_structure.TIM_Period = 312;                          //每312 uS触发一次中断,开启ADC
  104. timer_init_structure.TIM_Prescaler = 48-1;                      //计数时钟预分频,f=1M,systick=1 uS
  105. timer_init_structure.TIM_RepetitionCounter = 0x00;              //发生0+1次update事件产生中断
  106. TIM_TimeBaseInit(TIM2, &timer_init_structure);
  107. TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                      //使能TIM2中断
  108. TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);           //选择TIM2的update事件更新为触发源
  109. TIM_Cmd(TIM2, ENABLE);                                          //使能TIM2
  110. }
  111. /****************************中断服务程序****************************/
  112. void TIM2_IRQHandler()
  113. {
  114. if(TIM_GetITStatus(TIM2, TIM_IT_Update))            //判断发生update事件中断
  115. {
  116. TIM_ClearITPendingBit(TIM2, TIM_IT_Update);     //清除update事件中断标志
  117. }
  118. }
  119. void DMA1_Channel1_IRQHandler()
  120. {
  121. if(DMA_GetITStatus(DMA_IT_TC))                      //判断DMA传输完成中断
  122. {
  123. if(sample_finish == 0)
  124. {
  125. sample_1[sample_index] = adc_dma_tab[0];
  126. sample_2[sample_index] = adc_dma_tab[1];
  127. sample_3[sample_index] = adc_dma_tab[2];
  128. sample_4[sample_index] = adc_dma_tab[3];
  129. sample_5[sample_index] = adc_dma_tab[5];
  130. sample_6[sample_index] = adc_dma_tab[4];
  131. sample_index++;
  132. }
  133. if(sample_index >= 128)                         //注意防止数组越界导致未知错误
  134. {
  135. sample_index = 0;
  136. TIM_Cmd(TIM2, DISABLE);                     //完成周波采样,停止定时器
  137. DMA_Cmd(DMA1_Channel1, DISABLE);            //完成周波采样,停止DMA
  138. sample_finish = 1;                          //置采样完成标志位
  139. }
  140. }
  141. DMA_ClearITPendingBit(DMA_IT_TC);                   //清除DMA中断标志位
  142. }

STM32F0 定时器触发ADC,多通道采样、DMA传输数据的配置相关推荐

  1. dma和通道的区别_STM32 定时器触发 ADC 多通道采集,DMA搬运至内存

    引言 ADC 的功能是将模拟信号采样得到数字信号,而有些时候,我们需要使用到定时采样,比如在计算一个采集的波形的频率的时候,我们需要精确的知道采样频率,也就是 1 s 内采集的点数,这个时候,就需要使 ...

  2. STM32F4时钟触发ADC双通道采样DMA传输进行FFT+测频率+采样频率可变+显示波形(详细解读)...

    此文转载自:https://blog.csdn.net/qq_45620831/article/details/110819495 写在前面的婆婆妈妈的话 本人大三,参加过数次电赛,来CSDN好久, ...

  3. STM32F4时钟触发ADC双通道采样DMA传输进行FFT+测频率+采样频率可变+显示波形(详细解读)

    写在前面的婆婆妈妈的话(代码链接在最下方) 本人大三,参加过数次电赛,来CSDN好久, 每次都是在绝望中从这里找到了希望,每次都仿佛一个即将被怪兽打翻的小船突然被危险流浪者救起来.是众多前辈的智慧,让 ...

  4. STM32F103C8T6制作舵机测试仪详细图文教程 | 定时器触发ADC | DMA传输 | PWM输出 | RTC实时时钟 | USART串口输出 | OLED IIC显示

    自主学习STM32已有一周,先实现一个小demo,算是给自己一个动力叭,有目标的学习收获会更多.虽然本科也修了嵌入式课程,但那种走马观花式的学习,最后真正得到的知识实在寥寥无几.个人理解,学习STM3 ...

  5. STM8单片机通过PWM触发ADC同步采样

      在做数字开关电源开发过程中使用最多的就是PWM功能和ADC采样功能.ADC采样时采样的时间点很重要,必须在PWM输出高电平的时候取采样,这样采样出来的数据才是最准确的.在STM8单片机中,可以通过 ...

  6. STM8学习笔记---ADC多通道采样

    STM8S003单片机ADC采样通道总共有5个,从AIN2---AIN6,多通道采样时需要将ADC转换设置为单次转换模式,每次切换采样通道后,需要重新初始化 ADC,采样结果在中断中读取. IO口初始 ...

  7. STM32F030 使用CUBEMX配置ADC多通道采集 DMA传输

    STM32CubeMX的配置 以下为测试代码 //usart重定向,注意使用前需要包含头文件<stdio.h> int fputc(int ch, FILE *f) {HAL_UART_T ...

  8. 【STM32】定时器TIM触发ADC采样,DMA搬运到内存(超详细讲解)

    TIM+ADC+DMA原理 一般情况下,当我们需要进行采样的时候,需要用到ADC.例如:需要对某个信号进行定时采样(也就是隔一段时间,比如说2ms). 本文提供的解决方案是:使用ADC的定时器触发AD ...

  9. STM8单片机ADC采样功能通过定时器触发

      在使用STM8单片机的ADC功能时,读取ADC数据时一般有两种方式,一种是通常不断地读取采样标志位,来判断ADC采样是否结束,一种是通过中断的方式来通知系统采样是否结束.   有时候采样ADC数据 ...

最新文章

  1. zeroclipboard 粘贴板的应用示例, 兼容 Chrome、IE等多浏览器
  2. 安装SQL2000,挂起无法安装问题
  3. UVA 10594 Data Flow
  4. erlang精要(4)-列表及运算
  5. 快速准备电子设计大赛
  6. 红黑联盟c语言教程,1.1.2 C语言的特点
  7. 2013与2014之流水
  8. mysql往前一天同一时间_Mysql时间轴数据 获取同一天数据的前三条
  9. Kettle入门--作业和转换的使用
  10. html定位 浏览器兼容,IE6浏览器不支持固定定位(position:fixed)解决方案
  11. php pear mail 发送邮件,PHP用pear自带的mail类库发邮件
  12. 80%的销售来源于第4至11次的跟踪!
  13. 无法定位程序输入点于动态链接库(更新)
  14. visio 画箭头_visio2013中画箭头的具体操作步骤
  15. php一年过去多少天,php获取一年有多少天
  16. 南邮——计算机图像学——会动的立方体(变换)
  17. Bootstrap抽样和Monte Carlo思想
  18. 图解分布式一致性协议Paxos
  19. 如何查看自己的CSDN积分
  20. 依靠国家资源,发展人工智能

热门文章

  1. [BZOJ1188/Luogu3185][HNOI2007]分裂游戏
  2. noip2018——题解总结
  3. 【转载】Apache Spark Jobs 性能调优(二)
  4. Entity Framework 基础
  5. MagicalRecord使用中的注意事项
  6. 【转载】windows mobile 上隐藏和关闭X以及OK的处理
  7. 发文越多,影响力会越大吗?
  8. springboot项目启动优化
  9. NVIDIA与服务器制造商合作推进AI云计算
  10. cisco dhcp vlan vrrp ospf 实验