四轴遥控器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 ...
随机推荐
- selenium环境搭建,浏览器驱动安装
一安装Python: 1.下载Phtyon地址:https://www.python.org/getit/ 2.安装python会默认安装两个基础包setuptools,pip 也可以手动安装: ...
- DataInput接口说明及其实现类
一. DataInput接口 DataInput接口提供了一系列的方法从二进制流中读取字节,并将读取出来的字节转换成任意的java基本类型,包括转换成UTF-8类型的字符串. 该接口中主要方法介绍如下 ...
- 4412 i2c驱动
1.Linux主机驱动和外设驱动分离思想 外设驱动→API→主机驱动→板机逻辑--具体的i2c设备(camera,ts,eeprom等等) 2.主机驱动 根据控制器硬件手册,操作具体的寄存器,产生波形 ...
- PHP基于PDO实现的SQLite操作类
<?php // sqlite分页类 class SqliteDB{ public function __construct(){ // 初始化数据库,并且连接数据库 数据库配置 $this-& ...
- 使用C#登录带验证码的网站
我在上一篇文章中已经讲解了一般网站的登录原来和C#的登录实现,很多人问到对于使用了验证码的网站该怎么办,这里我就讲讲验证码的原理和对应的登录方法.验证码的由来几年前,大部分网站.论坛之类的是没有验证码 ...
- Bugku | 游戏过关
思路:绕过判断,直接跳转到算flag的函数哪里 1.找到计算flag的函数在哪里,记住 "0075e940",这是入口 2.找到一个现成的跳转指令,修改它: 3.重新运行一遍,得到 ...
- python练习题之全选框全不选反选
功能 实现分为两大部分: 第一body 部分,1,通过<li>无序列表标签实现选项的基本样式,通过input的checkbox标签实现里面的复选框功能.用到了标签的嵌套.然后选项的js方法 ...
- flask 实现简易图书管理
""" 1.配置数据库 a.导入 SQLalchemy库 b.创建db对象,并配置参数 c.创建数据库 2.添加书和作者的模型 a.模型集成db.Model b.__ta ...
- 基础复习之HTML (meta标签、块级元素与行内元素)
一.meta标签 SEO 如何在不使用JS的情况下刷新页面(http-equiv="refresh" , content="time") 设置页面缓存 移动端设 ...
- Linux vsftpd服务配置以及三种验证方式以及常见错误解决办法
文件传输协议(FTP): 文件传输协议(FTP,File Transfer Protocol),即能够让用户在互联网中上传.下载文件的文件协议,而FTP服务器就是支持FTP传输协议的主机,要想完成文件 ...