四轴遥控器ADC部分
一、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:
- #include "adc.h"
- #include "usart.h"
- #include "systick.h"
- vu16 ADC_ConvertedValue[4];
- #define ADC1_DR_Address ((u32)&ADC1->DR)
- //left ADC1_2: PA2
- // ADC1_3: PA3
- //right ADC1_0: PA0
- // ADC1_1: PA1
- void ADC_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /*配置ADC和GPIOA、DMA的时钟*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
- /*配置GPIOA0~4为输入模式*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- }
- void ADC_DMA_Config(void)
- {
- DMA_InitTypeDef DMA_InitStructure; // 注:ADC为12位模数转换器,只有ADCConvertedValue的低12位有效
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
- DMA_DeInit(DMA1_Channel1);//开启DMA1的第一通道
- DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//DMA对应的外设基地址
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue; //内存存储基地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的转换模式为SRC模式,由外设搬移到内存
- DMA_InitStructure.DMA_BufferSize = 4;//DMA缓存大小,1个
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收一次数据后,设备地址禁止后移
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //关闭接收一次数据后,目标内存地址后移
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度为16位
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA搬移数据尺寸,HalfWord就是为16位
- DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;//循环转换模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA优先级高
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//M2M模式禁用
- DMA_Init(DMA1_Channel1, &DMA_InitStructure);
- DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);//使能传输完成中断
- }
- void ADC_Config(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- ADC_GPIO_Config();
- ADC_DMA_Config();
- NVIC_EnableIRQ(DMA1_Channel1_IRQn); //打开NVIC中对应的DMA通道
- /* Enable DMA1 channel1 */
- DMA_Cmd(DMA1_Channel1, ENABLE);
- /* ADC1 configuration ------------------------------------------------------*/
- ADC_DeInit(ADC1); //先复位一下
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //各通道独立模式
- ADC_InitStructure.ADC_ScanConvMode = ENABLE; //打开扫描
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //关闭连续转换
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; //使用TIM4的CC4(外部触发)
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
- ADC_InitStructure.ADC_NbrOfChannel = 4; //一共要采样的通道数
- ADC_Init(ADC1, &ADC_InitStructure);
- ADC_Cmd(ADC1, ENABLE); //开启ADC
- ADC_DMACmd(ADC1, ENABLE); //开启ADC--DMA数据传输通道
- RCC_ADCCLKConfig(RCC_PCLK2_Div8); //配置ADC采样参考时钟的预分频值
- ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_71Cycles5); //71.5个ADC时钟
- ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_71Cycles5);
- ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_71Cycles5);
- ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_71Cycles5);
- ADC_ResetCalibration(ADC1); //重置ADC采样校准器
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准成功
- ADC_StartCalibration(ADC1); //开启ADC采样状态
- while(ADC_GetCalibrationStatus(ADC1)); //等到开启成功
- ADC_ExternalTrigConvCmd(ADC1, ENABLE); //使能外部触发ADC采样
- }
- void DMA1_Channel1_IRQHandler(void)
- {
- u8 i=0;
- if(DMA_GetITStatus(DMA1_IT_TC1) == SET)
- {
- for(i=0;i<4;i++)
- printf("adc value is %d .\n",ADC_ConvertedValue[i]);
- DMA_ClearITPendingBit(DMA1_IT_TC1);
- }
- }
tim.c:
- #include "tim.h"
- //利用定时器TIM4的通道4输出比较功能,给ADC1提供采样触发信号,这里触发周期为:100ms
- //公式: psc/72*period/1000000 (单位为秒)
- //psc 是预分频的值
- void TIM_OCTigrConfig(void)
- {
- TIM_TimeBaseInitTypeDef TIM_timeBaseStructure;
- TIM_OCInitTypeDef TIM_ocInitStructure;
- u16 period = 60000; //设置周期值
- u16 pluse = 30000; //设置CRR值
- //失能TIM4的时钟,TIM4时挂在APB1总线上的,注意TIM4的时钟是72M的
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
- TIM_timeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //预分频因子
- TIM_timeBaseStructure.TIM_Prescaler = 120-1; //预分频
- TIM_timeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
- TIM_timeBaseStructure.TIM_Period = period; //设置周期,给ARR赋值
- TIM_TimeBaseInit(TIM4, &TIM_timeBaseStructure);
- //配置TIM4通道4的输出比较
- TIM_ocInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM输出模式为PWM1
- TIM_ocInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; //设置有效电平的极性
- TIM_ocInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能通道输出
- TIM_ocInitStructure.TIM_Pulse = pluse; //设置PWM的脉冲宽度值,即CRR值
- TIM_OC4Init(TIM4, &TIM_ocInitStructure);
- TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIM4寄存器ARR的预装载功能
- TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4通道1的CCR的预装载功能
- //使能TIM4定时器
- TIM_Cmd(TIM4, ENABLE);
- }
教训总结:在设置DMA时钟时错把 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
写成了 RCC_APB1PeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
DMA是AHB上的外设。。。。

四轴遥控器ADC部分的更多相关文章
- 四轴电池ADC监控学习
一.硬件原理 电池供电通过两个分压电阻接地,STM32则在两电阻中间通过ADC检测电池电压.(引脚BAT_DET) 二.ADC通道初始化 //初始化电池检测ADC //开启ADC1的通道8 //Bat ...
- STM32学习笔记(七) ADC模数转换测电平(普通和DMA模式)
嵌入式系统在微控制领域(温度,湿度,压力检测,四轴飞行器)中占据着重要地位,这些功能的实现是由微处理器cpu(如stm32)和传感器以及控制器共同完成的,而连接他们,使它们能够互相正常交流的正是本小节 ...
- 四轴飞行diy全套入门教程(从最基础的开始)
转载:http://www.cnmox.com/thread-12460-1-1.html首先声明本人也是菜鸟,此教程就是从一个菜鸟的角度来讲解,现在论坛上的帖子都突然冒很多名词出来,又不成体系,我自 ...
- 四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法
四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法 原创文章,欢迎转载,转载请注明出处 最近时间花在最多的地方就是STM32的I2C上了.之前就知道STM32的I2C并不好用, ...
- 四轴自适应控制算法的一些尝试开源我的山猫飞控和梯度在线辨识自适应等算法—(转)
本文的最主要目的在于抛砖引玉,阿莫论坛真的是非常好的一个论坛,没有这个论坛,没有那么多这个论坛上的前人无私的奉献和热烈的讨论,我想我是怎么也无法入门四轴的控制的.只是论坛上已经很多年都没有看到过新东西 ...
- QAV250四轴穿越机安装全程详解(多图)
QAV250四轴穿越机安装全程详解 最近团队准备使用轻型穿越机QAV250做实验,本文记录了QAV250的安装过程,整理了开箱后较合理的安装顺序,以及各个步骤的注意事项,希望对有需要的朋友有所帮助.主 ...
- 逆向破解 H.Koenig 遥控器 Part 1
逆向破解 H.Koenig 遥控器(Part 1) 最近我正在尝试一研究些自动吸尘器机器人.iRobot公司的Roomba貌似是该领域的领导者,但是作为实验来讲的话这些东西真是太昂贵了,我也找不到 ...
- 四轴飞行器飞行原理与双闭环PID控制
四轴轴飞行器是微型飞行器的其中一种,相对于固定翼飞行器,它的方向控制灵活.抗干扰能力强.飞行稳定,能够携带一定的负载和有悬停功能,因此能够很好地进行空中拍摄.监视.侦查等功能,在军事和民用上具备广泛的 ...
- 四轴PID思路整理
参考资料: https://blog.csdn.net/nemol1990/article/details/45131603 https://blog.csdn.net/qq_27114397/art ...
随机推荐
- Delphi abstract error异常
今天在编译之前的一个的项目时, 退出程序时出现abstract error抽象错误的异常, 点击Continue又出现释放对象的异常, 百思不得其解, 之前还好好的,突然这样了, 经过一上午的调试, ...
- vue项目打包之后原本好的样式变得不好了的原因分析
这个主要是打包的过程将所有的css文件进行归类压缩,导致原先其他文件里的样式对当前的产生了影响,应该有同样的类名了.怎么改?要么改类名,要么用scope,scss的写法.
- win7搭建局域网时间服务器
近日,本人想在局域网内通过普通的windows 7 PC搭建一台NTP服务器,可看似简单的配置却给我捣腾了了半天.初期,参考了互联网的上相关的配置文档,可网络设备就是死活不同步NTP服务器的时间.实在 ...
- Java中static修饰类的问题
Java中static修饰类的问题 众所周知,Java中static关键字可以修饰方法与变量: 修饰变量的时候,这个变量属于类变量,可以直接通过类名.变量名来引用. 修饰方法的时候可以直接通过类名.方 ...
- 重写ArcGIS的TiledMapServiceLayer调用天地图瓦片
require(["esri/layers/TiledMapServiceLayer"], function () { dojo.declare("com.StrongI ...
- python 装饰器 第五步(2):带有返回值得装饰器
#第五步:带有返回值的装饰器 把第四步复制过来 #用于扩展基本函数的函数 def kuozhan(func): #内部函数(扩展之后的eat函数) def neweat(): #以下三步就是扩展之后的 ...
- 利用程序随机构造N个已解答的数独棋盘
高级软件工程第二次作业:利用程序随机构造N个已解答的数独棋盘,代码如下: package SudokuGame; /** * 解决这个问题使用的是回溯+剪枝的算法 * 基本思想:不断地将每个格子可填入 ...
- 用css3写出的倒三角形
<!DOCTYPE html><html><head><meta charset="gb2312" /><title>无 ...
- ABAP字符串处理
字符串中包含单引号:单引号前面再加一个单引号 例:jest~stat = 'E0002' jest~stat = 'E0003' OR jest~stat = 'E0004' IF z_stat IS ...
- HTTP面试题目
转自:http://m.blog.csdn.net/zhangliangzi/article/details/51336564 1.说一下什么是Http协议? 对器客户端和 服务器端之间数据传输的格式 ...