智能小车手柄ADC采集(三)

一、简介

ADC(analog to digital converter)即模数转换器,它可以将模拟信号转换为数字信号。按照其转换原理主要分为逐次逼近型、双积分型、电压频率转换型三种。

STM32F1xx ADC特性:
● 12 位分辨率
● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
● 单次和连续转换模式
● 从通道 0 到通道 n 的自动扫描模式
● 自校准
● 带内嵌数据一致性的数据对齐
● 采样间隔可以按通道分别编程
● 规则转换和注入转换均有外部触发选项
● 间断模式
● 双重模式(带 2 个或以上 ADC 的器件)
● ADC 转换时间

【注意:】

STM32F1 的 ADC 是 12 位转换精度,而数据寄存器是 16 位,所以 ADC在存放数据的时候就有左对齐和右对齐区分。如果是左对齐,AD 转换完成数据存放在 ADC_DR 寄存器的[4:15]位内;如果是右对齐,则存放在 ADC_DR 寄存器的[0:11]位内。

使用PB0与PB1采集两个电位器模拟信号、此两脚分别对ADC12_IN8\ADC12_IN9。
1、通过 ADC1_2 通道 8 采样外部电压值。
2、通过 ADC1_2通道 9 采样外部电压值。

输入电压范围

ADC 输入范围为:VREF- ≤ VIN ≤ VREF+。由 VREF-、VREF+ 、VDDA 、VSSA、这四个外部
引脚决定。
一般把 VSSA 和 VREF-接地,把 VREF+和 VDDA 接 3V3

ADC时钟

ADC 输入时钟 ADC_CLK 由 PCLK2 经过分频产生,最大是 14M。
APB1:SystemClock=HCLK/4=PCLK1=18M
APB2:SystemClock=HCLK/4=PCLK2=18M


时钟树.PNG

Tconv = 采样时间 + 12.5 个周期。(Tconv 为 ADC 总转换时间/采样周期为:1/ADC_CLK)
当 ADCLK = 14MHZ (最高),采样时间设置为 1.5 周期(最快),那么总的转换时间(最短)Tconv = 1.5 周期 + 12.5 周期 = 14 周期 = 1us(即ADC 最大的转换速率为 1Mhz)。

二、编码

2.1、DMA配置

// 1、DMA_Chx  DMA通道  2、Dpba  外设地址  3、Dmba  存储器地址  4、Dbse  DMA通道的缓冲区大小
void DMA_Config(DMA_Channel_TypeDef* DMA_Chx,uint32_t Dpba,uint32_t Dmba,uint32_t Dbs)
{
    DMA_InitTypeDef DMA_InitStructure; 
  //  使能时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
    //  复位DMA控制器
    DMA_DeInit(DMA_Chx);
    
    //  配置结构体
    DMA_InitStructure.DMA_PeripheralBaseAddr=Dpba;  //  外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr=Dmba;      //  存储器地址
    DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//  数据传输方向:从内存读发送到外设
    DMA_InitStructure.DMA_BufferSize=Dbs;           //  DMA缓冲区大小=数据目的地的大小
    
    DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;             //   指定外设地址寄存器是否递增.只有一个不递增
    DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;                      //   内存地址寄存器递增
    DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;  //   外设数据宽度为半字,即两个字节
    DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;          //   内存数据宽度为半字
    DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;                              //   DMA工作模式  循环输出模式    正常工作模式DMA_Mode_Normal
    DMA_InitStructure.DMA_Priority=DMA_Priority_High;                          //   优先级 DMA 传输通道优先级为高,当使用一个 DMA 通道时,优先级设置不影响 
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                               //   禁用内存到内存的传输模式   外设->内存
    DMA_Init(DMA_Chx,&DMA_InitStructure);
    DMA_Cmd(DMA_Chx,ENABLE);
}

2.2、ADC配置

void ADC_IN_x_Config(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    
      //  使能ADC时钟
    RCC_APB2PeriphClockCmd(ADC_RCC,ENABLE);
      
     //  ADC结构体配置
     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;   //  独立模式   每个ADC接口独立工作
     ADC_InitStructure.ADC_ScanConvMode = DISABLE;        //  非扫描模式 单通道
     ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;     //  连续转换   一次转换  多次转换
     ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;  // 定时器一触发ADC_ExternalTrigConv_T1_CC1   禁止触发检测、使用软件触发  ADC_ExternalTrigConv_None
     ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right; //   右对齐
     ADC_InitStructure.ADC_NbrOfChannel=2;                //  2个转换在规则序列中
     ADC_Init(ADC1,&ADC_InitStructure);

     //  配置ADC时钟分频因子  不超过14M     RCC_PCLK2_Div2: ADC clock = PCLK2/2=9M
      RCC_ADCCLKConfig(RCC_PCLK2_Div2);
    
     // 配置ADC通道的转换顺序和采样时间  第三个参数:通道的转换顺序
     //  
   ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); // 配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 55.5 个时钟周期 
  
     ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_55Cycles5); 
    
   //ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);              // ADC 转换结束产生中断,在中断服务程序中读取转换值 
     ADC_DMACmd(ADC1,ENABLE);                               // 使能ADC DMA请求
     
     //  使能ADC并开始转换
     ADC_Cmd(ADC1,ENABLE);
     
     //  初始化并校准寄存器
     ADC_ResetCalibration(ADC1);
     
     //  等待校准寄存器初始化完成
     while(ADC_GetResetCalibrationStatus(ADC1));
     
     //  ADC开始校准
     ADC_StartCalibration(ADC1);
     
     //  等待校准完成
     while(ADC_GetCalibrationStatus(ADC1));
     
     //  软件触发ADC转换
     ADC_SoftwareStartConvCmd(ADC1, ENABLE);
      
}

2.3、初始化配置

void ADC_XY_Init(void)
{
    //  使能ADC时钟
  //RCC_APB2PeriphClockCmd(ADC_RCC,ENABLE);
    
    //  x轴 引脚初始化                         模拟输入
    GPIOxInit(ADC_PORT_RCC,ADC_PORT,ADC_X_PIN|ADC_Y_PIN,GPIO_Mode_AIN);
    
    //  DMA配置    1、DMA通道   2、外设地址  3、存储器地址  4、缓冲区大小,应该等于数据目的地的大小
    DMA_Config(ADC_DMA_CHANNEL,(u32)(&( ADC1->DR )),(u32)DMA_Buff,NOFCHANEL);
    
    //  ADC配置
     ADC_IN_x_Config();
}

2.4、逻辑代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容