四轴遥控器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 ...
随机推荐
- 媲美5G的Wifi网速、“备战”资产一键领……揭秘双11小二背后的保障力量
如今,双11不光是购物狂欢节,更是对技术的一次“大考”,对于阿里巴巴企业内部运营的基础保障技术而言,亦是如此. 回溯双11历史,这背后也经历过“小米加步枪”的阶段:作战室从随处是网线,交换机放地上的“ ...
- exists 的简单介绍
准备数据: CREATE TABLE Books( BookID number, BookTitle VARCHAR2(20) NOT NULL, Copyright varchar2(20) ) I ...
- 七、单例设计模式共享数据分析、解决、call_once
一.设计模式大概谈 代码的一些写法,与常规的写法不太一样,程序灵活,维护起来很方便,但是别人接管.阅读代码很痛苦. 用设计模式理念写出来的代码很晦涩.<< head first>&g ...
- 原生 js 实现 vue 的某些功能
1.数据双向绑定:https://www.cnblogs.com/yuqing-o605/p/6790709.html?utm_source=itdadao&utm_medium=referr ...
- 20175120彭宇辰 《Java程序设计》第十周学习总结
教材内容总结 十二章 Java多线程机制 一.进程与线程.操作系统与进程 -线程不是进程,是比进程更小的执行单位.但与进程不同的是,线程的中断和恢复可以更加节省系统的开销. -线程可以共享进程中的某些 ...
- nginx启动、关闭、重启及常用的命令
nginx常用命令 启动:cd /usr/local/nginx/sbin./nginxnginx服务启动后默认的进程号会放在/usr/local/nginx/logs/nginx.pid文件cat ...
- vijos 1243 生产产品
貌似两年前联赛复习的时候就看过这题 然而当时大概看看了 感觉太难 便没有去做 如今再去做的时候 发现其实也并不容易 ------------------------------------------ ...
- jq与js获取值操作
jq与js获取值操作 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...
- linux远程管理器 - xshell和xftp使用教程(zhuan)
准备好连接linux服务器的工具,推荐用xshell和xftp. xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET ...
- 浅析java设计模式(一)----异构容器,可以存储任何对象类型为其他类提供该对象
最近在着手重构一个java UI桌面项目,发现这个项目在一开始的时候由于需求不明确,以及开发人员对swing框架不熟悉等问题造成了页面代码混乱的情况:为了能够在各个类里都可以拿到其他类的引用去进行相应 ...