当前位置: 首页 > news >正文

四轴遥控器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:
  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.     
  46.     /* Enable DMA1 channel1 */
  47.     DMA_Cmd(DMA1_Channel1, ENABLE);
  48.     /* ADC1 configuration ------------------------------------------------------*/
  49.     ADC_DeInit(ADC1);                                                                //先复位一下
  50.     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                                //各通道独立模式
  51.     ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                    //打开扫描
  52.     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                                //关闭连续转换
  53.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;            //使用TIM4的CC4(外部触发)
  54.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                            //数据右对齐
  55.     ADC_InitStructure.ADC_NbrOfChannel = 4;                                            //一共要采样的通道数
  56.     ADC_Init(ADC1, &ADC_InitStructure);    
  57.     
  58.     ADC_Cmd(ADC1, ENABLE);                                                            //开启ADC
  59.     ADC_DMACmd(ADC1, ENABLE);                                                        //开启ADC--DMA数据传输通道
  60.     
  61.     RCC_ADCCLKConfig(RCC_PCLK2_Div8);                                                //配置ADC采样参考时钟的预分频值
  62.     
  63.     ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_71Cycles5);        //71.5个ADC时钟
  64.     ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_71Cycles5);        
  65.     ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_71Cycles5);        
  66.     ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_71Cycles5);

  67.     ADC_ResetCalibration(ADC1);                                                        //重置ADC采样校准器
  68.     while(ADC_GetCalibrationStatus(ADC1));                                            //等待校准成功
  69.     ADC_StartCalibration(ADC1);                                                        //开启ADC采样状态
  70.     while(ADC_GetCalibrationStatus(ADC1));                                            //等到开启成功
  71.   
  72.     ADC_ExternalTrigConvCmd(ADC1, ENABLE);                                            //使能外部触发ADC采样

  73. }

  74. void DMA1_Channel1_IRQHandler(void)
  75. {
  76.     u8 i=0;
  77.     if(DMA_GetITStatus(DMA1_IT_TC1) == SET)
  78.     {
  79.         for(i=0;i<4;i++)
  80.             printf("adc value is %d .\n",ADC_ConvertedValue[i]);
  81.         DMA_ClearITPendingBit(DMA1_IT_TC1);
  82.     }    
  83. }
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.     
  10.     u16 period = 60000;                                //设置周期值
  11.     u16 pluse = 30000;                                //设置CRR值
  12.     
  13.     //失能TIM4的时钟,TIM4时挂在APB1总线上的,注意TIM4的时钟是72M的
  14.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  15.     
  16.     TIM_timeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                    //预分频因子
  17.     TIM_timeBaseStructure.TIM_Prescaler = 120-1;                            //预分频
  18.     TIM_timeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                //向上计数
  19.     TIM_timeBaseStructure.TIM_Period = period;                                //设置周期,给ARR赋值
  20.     TIM_TimeBaseInit(TIM4, &TIM_timeBaseStructure);
  21.     
  22.     //配置TIM4通道4的输出比较
  23.     TIM_ocInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                        //PWM输出模式为PWM1
  24.     TIM_ocInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;                //设置有效电平的极性
  25.     TIM_ocInitStructure.TIM_OutputState = TIM_OutputState_Enable;            //使能通道输出
  26.     TIM_ocInitStructure.TIM_Pulse = pluse;                                    //设置PWM的脉冲宽度值,即CRR值
  27.     TIM_OC4Init(TIM4, &TIM_ocInitStructure);
  28.     
  29.     TIM_ARRPreloadConfig(TIM4, ENABLE);                                        //使能TIM4寄存器ARR的预装载功能
  30.     TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);                        //使能TIM4通道1的CCR的预装载功能
  31.     
  32.     //使能TIM4定时器
  33.     TIM_Cmd(TIM4, ENABLE);    
  34. }

教训总结:在设置DMA时钟时错把  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
写成了                                         RCC_APB1 PeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
DMA是AHB上的外设。。。。


转载于:https://www.cnblogs.com/ch122633/p/7363254.html

相关文章:

  • 代码备忘, TODO宏实现
  • html2canvas页面截图图片不显示
  • 4.5 以卫语句取代嵌套条件式
  • 最近面试js部分试题总结
  • DP 网易内推:合唱团
  • Concatenated Words
  • 差异表达基因分析:差异倍数(fold change), 差异的显著性(P-value) | 火山图
  • js引用类型
  • windows多线程应用编程注意事项
  • python的md5和base64加密
  • 【Spring】DispatcherServlet源码分析
  • Hive架构
  • 解决warning: LF will be replaced by CRLF in **(filename)
  • python 初学习 模拟用户登录
  • CSS选择器
  • Angularjs之国际化
  • Median of Two Sorted Arrays
  • windows-nginx-https-本地配置
  • 安卓应用性能调试和优化经验分享
  • 番外篇1:在Windows环境下安装JDK
  • 给github项目添加CI badge
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 技术胖1-4季视频复习— (看视频笔记)
  • 聚类分析——Kmeans
  • 人脸识别最新开发经验demo
  • 实战|智能家居行业移动应用性能分析
  • 我的zsh配置, 2019最新方案
  • Python 之网络式编程
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​学习一下,什么是预包装食品?​
  • #laravel 通过手动安装依赖PHPExcel#
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (42)STM32——LCD显示屏实验笔记
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (Note)C++中的继承方式
  • (搬运以学习)flask 上下文的实现
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)EXC_BREAKPOINT僵尸错误
  • .Net CoreRabbitMQ消息存储可靠机制
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • .net知识和学习方法系列(二十一)CLR-枚举
  • .net专家(高海东的专栏)
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • ?
  • @Query中countQuery的介绍
  • @RestControllerAdvice异常统一处理类失效原因