一、ADC参考手册学习

A/D转换可以按单次、连续设置采样;可以一一扫描或间断的对多个ADC通道进行采集。

ADC的结果有左对齐和右对齐。

ADC的输入时钟不得超过14Mhz,它是由PCLK2经分频产生。

二、ADC通道选择

16个多路通道,可以分成:规则组和注入组。

规则组:可以设定任意的顺序进行的通道排列。(最多16个)

注入组:可以像中断一样优先进行转换。(最多4个)

三、数据对齐

四、外部触发事件

当外部触发信号被选中时,只有上升沿(外部触发的)可以启动转换。

在手册中详细写了计时器触发对应ADC的触发源时哪些。

五、DMA请求

当转换多个规则通道时需要使用DMA,这可以避免对视已经存储在ADC_DR寄存器中的数据。

只有在规则通道的转换结束时才产生DMA请求。

只有ADC1和ADC3拥有DMA功能。ADC2转化的数据可以通过双ADC模式,利用ADC1的DMA功能传输。

六、代码部分

adc.c:

  1. #include "adc.h"
  2. #include "usart.h"
  3. #include "systick.h"
  4. vu16 ADC_ConvertedValue[4];
  5. #define ADC1_DR_Address     ((u32)&ADC1->DR)
  6. //left     ADC1_2:    PA2
  7. //         ADC1_3:    PA3
  8. //right    ADC1_0:    PA0
  9. //        ADC1_1:    PA1
  10. void ADC_GPIO_Config(void)
  11. {
  12. GPIO_InitTypeDef GPIO_InitStructure;
  13. /*配置ADC和GPIOA、DMA的时钟*/
  14. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
  15. /*配置GPIOA0~4为输入模式*/
  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  18. GPIO_Init(GPIOA, &GPIO_InitStructure);
  19. }
  20. void ADC_DMA_Config(void)
  21. {
  22. DMA_InitTypeDef DMA_InitStructure; // 注:ADC为12位模数转换器,只有ADCConvertedValue的低12位有效
  23. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
  24. DMA_DeInit(DMA1_Channel1);//开启DMA1的第一通道
  25. DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//DMA对应的外设基地址
  26. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue; //内存存储基地址
  27. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的转换模式为SRC模式,由外设搬移到内存
  28. DMA_InitStructure.DMA_BufferSize = 4;//DMA缓存大小,1个
  29. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收一次数据后,设备地址禁止后移
  30. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //关闭接收一次数据后,目标内存地址后移
  31. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度为16位
  32. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA搬移数据尺寸,HalfWord就是为16位
  33. DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;//循环转换模式
  34. DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA优先级高
  35. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//M2M模式禁用
  36. DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  37. DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);//使能传输完成中断
  38. }
  39. void ADC_Config(void)
  40. {
  41. ADC_InitTypeDef ADC_InitStructure;
  42. ADC_GPIO_Config();
  43. ADC_DMA_Config();
  44. NVIC_EnableIRQ(DMA1_Channel1_IRQn);                                                //打开NVIC中对应的DMA通道
  45. /* Enable DMA1 channel1 */
  46. DMA_Cmd(DMA1_Channel1, ENABLE);
  47. /* ADC1 configuration ------------------------------------------------------*/
  48. ADC_DeInit(ADC1);                                                                //先复位一下
  49. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                                //各通道独立模式
  50. ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                    //打开扫描
  51. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                                //关闭连续转换
  52. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;            //使用TIM4的CC4(外部触发)
  53. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                            //数据右对齐
  54. ADC_InitStructure.ADC_NbrOfChannel = 4;                                            //一共要采样的通道数
  55. ADC_Init(ADC1, &ADC_InitStructure);
  56. ADC_Cmd(ADC1, ENABLE);                                                            //开启ADC
  57. ADC_DMACmd(ADC1, ENABLE);                                                        //开启ADC--DMA数据传输通道
  58. RCC_ADCCLKConfig(RCC_PCLK2_Div8);                                                //配置ADC采样参考时钟的预分频值
  59. ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_71Cycles5);        //71.5个ADC时钟
  60. ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_71Cycles5);
  61. ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_71Cycles5);
  62. ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_71Cycles5);
  63. ADC_ResetCalibration(ADC1);                                                        //重置ADC采样校准器
  64. while(ADC_GetCalibrationStatus(ADC1));                                            //等待校准成功
  65. ADC_StartCalibration(ADC1);                                                        //开启ADC采样状态
  66. while(ADC_GetCalibrationStatus(ADC1));                                            //等到开启成功
  67. ADC_ExternalTrigConvCmd(ADC1, ENABLE);                                            //使能外部触发ADC采样
  68. }
  69. void DMA1_Channel1_IRQHandler(void)
  70. {
  71. u8 i=0;
  72. if(DMA_GetITStatus(DMA1_IT_TC1) == SET)
  73. {
  74. for(i=0;i<4;i++)
  75. printf("adc value is %d .\n",ADC_ConvertedValue[i]);
  76. DMA_ClearITPendingBit(DMA1_IT_TC1);
  77. }
  78. }

tim.c:

  1. #include "tim.h"
  2. //利用定时器TIM4的通道4输出比较功能,给ADC1提供采样触发信号,这里触发周期为:100ms
  3. //公式: psc/72*period/1000000 (单位为秒)
  4. //psc 是预分频的值
  5. void TIM_OCTigrConfig(void)
  6. {
  7. TIM_TimeBaseInitTypeDef TIM_timeBaseStructure;
  8. TIM_OCInitTypeDef TIM_ocInitStructure;
  9. u16 period = 60000;                                //设置周期值
  10. u16 pluse = 30000;                                //设置CRR值
  11. //失能TIM4的时钟,TIM4时挂在APB1总线上的,注意TIM4的时钟是72M的
  12. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  13. TIM_timeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                    //预分频因子
  14. TIM_timeBaseStructure.TIM_Prescaler = 120-1;                            //预分频
  15. TIM_timeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                //向上计数
  16. TIM_timeBaseStructure.TIM_Period = period;                                //设置周期,给ARR赋值
  17. TIM_TimeBaseInit(TIM4, &TIM_timeBaseStructure);
  18. //配置TIM4通道4的输出比较
  19. TIM_ocInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                        //PWM输出模式为PWM1
  20. TIM_ocInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;                //设置有效电平的极性
  21. TIM_ocInitStructure.TIM_OutputState = TIM_OutputState_Enable;            //使能通道输出
  22. TIM_ocInitStructure.TIM_Pulse = pluse;                                    //设置PWM的脉冲宽度值,即CRR值
  23. TIM_OC4Init(TIM4, &TIM_ocInitStructure);
  24. TIM_ARRPreloadConfig(TIM4, ENABLE);                                        //使能TIM4寄存器ARR的预装载功能
  25. TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);                        //使能TIM4通道1的CCR的预装载功能
  26. //使能TIM4定时器
  27. TIM_Cmd(TIM4, ENABLE);
  28. }

教训总结:在设置DMA时钟时错把 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟

写成了                                        RCC_APB1PeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟

DMA是AHB上的外设。。。。

四轴遥控器ADC部分的更多相关文章

  1. 四轴电池ADC监控学习

    一.硬件原理 电池供电通过两个分压电阻接地,STM32则在两电阻中间通过ADC检测电池电压.(引脚BAT_DET) 二.ADC通道初始化 //初始化电池检测ADC //开启ADC1的通道8 //Bat ...

  2. STM32学习笔记(七) ADC模数转换测电平(普通和DMA模式)

    嵌入式系统在微控制领域(温度,湿度,压力检测,四轴飞行器)中占据着重要地位,这些功能的实现是由微处理器cpu(如stm32)和传感器以及控制器共同完成的,而连接他们,使它们能够互相正常交流的正是本小节 ...

  3. 四轴飞行diy全套入门教程(从最基础的开始)

    转载:http://www.cnmox.com/thread-12460-1-1.html首先声明本人也是菜鸟,此教程就是从一个菜鸟的角度来讲解,现在论坛上的帖子都突然冒很多名词出来,又不成体系,我自 ...

  4. 四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法

    四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法  原创文章,欢迎转载,转载请注明出处      最近时间花在最多的地方就是STM32的I2C上了.之前就知道STM32的I2C并不好用, ...

  5. 四轴自适应控制算法的一些尝试开源我的山猫飞控和梯度在线辨识自适应等算法—(转)

    本文的最主要目的在于抛砖引玉,阿莫论坛真的是非常好的一个论坛,没有这个论坛,没有那么多这个论坛上的前人无私的奉献和热烈的讨论,我想我是怎么也无法入门四轴的控制的.只是论坛上已经很多年都没有看到过新东西 ...

  6. QAV250四轴穿越机安装全程详解(多图)

    QAV250四轴穿越机安装全程详解 最近团队准备使用轻型穿越机QAV250做实验,本文记录了QAV250的安装过程,整理了开箱后较合理的安装顺序,以及各个步骤的注意事项,希望对有需要的朋友有所帮助.主 ...

  7. 逆向破解 H.Koenig 遥控器 Part 1

    逆向破解 H.Koenig 遥控器(Part 1)   最近我正在尝试一研究些自动吸尘器机器人.iRobot公司的Roomba貌似是该领域的领导者,但是作为实验来讲的话这些东西真是太昂贵了,我也找不到 ...

  8. 四轴飞行器飞行原理与双闭环PID控制

    四轴轴飞行器是微型飞行器的其中一种,相对于固定翼飞行器,它的方向控制灵活.抗干扰能力强.飞行稳定,能够携带一定的负载和有悬停功能,因此能够很好地进行空中拍摄.监视.侦查等功能,在军事和民用上具备广泛的 ...

  9. 四轴PID思路整理

    参考资料: https://blog.csdn.net/nemol1990/article/details/45131603 https://blog.csdn.net/qq_27114397/art ...

随机推荐

  1. Activity 启动模式总结

    Activity 启动模式: 1. standard: 默认启动模式,每次启动一个Activity都会重新创建一个实例: 2. singleTop: 栈顶复用模式,新Activity位于任务栈的栈顶, ...

  2. LOJ 2978 「THUSCH 2017」杜老师——bitset+线性基+结论

    题目:https://loj.ac/problem/2978 题解:https://www.cnblogs.com/Paul-Guderian/p/10248782.html 第 i 个数的 bits ...

  3. Alex and Number

    Alex and Number 时间限制: 1 Sec  内存限制: 128 MB提交: 69  解决: 12[提交][状态] 题目描述 Alex love Number theory. Today ...

  4. zkw 线段树

    优秀的 zkw 线段树讲解:<线段树的扩展之浅谈 zkw 线段树> 存一份模板代码(区间修改.区间查询): /* zkw Segment Tree * Au: GG */ #include ...

  5. js中Array方法重写(二):myForEach;myEvery;mySome;myFilter;myReduce

    一.myForEach //myForeach 数组每个元素都执行一次回调函数 Array.prototype.myForEach = function(callback){ for(var i = ...

  6. idea中git回退远程仓库版本

    工作中遇到,代码已提交并已提交到远程仓库,现需要回退到之前版本,记录如下: 记录当前版本的版本号和需要回退到版本的版本号. current version:85e7f32dfe421c5892a4e2 ...

  7. 用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 reCAPTCHA 应用 reCAPTCHA 前文列表 用 Flask ...

  8. 测开之路三十八:css布局之定位

    常用的布局方式: static:静态定位(默认),什么都不用管,元素会按照默认顺序排列,排不下是会默认换行relative:相对定位(同一层),相对于某一个元素进行定位fixed:绝对定位,指定位置a ...

  9. 显示等待WebDriverWait+EC

    参考:https://www.cnblogs.com/yoyoketang/p/6538505.html 百度搜索关键字,等待搜索结果页面显示完成后,验证搜索结果的第一条记录 通过WebDriverW ...

  10. Html5 学习笔记 【PC固定布局】 实战3 热门旅游展示区

    最终效果图: html 代码: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta char ...