第十六篇,STM32中的ADC模数转换,CAD数模转换和DMA直接内存访问

1.ADC概念

    ADC,叫做模数转换(Analog-to-Digtal Converter)。我们把连续变化的信号叫模拟信号,离散的非连续的信号叫做数字信号,现实生活中所有的信号属于模拟信号,比如声音,电压,压强,温度......,但是计算机只能存储和处理数字信号,ADC就是将模拟信号转换成数字信号的硬件,DAC就是将数字信号转换成模拟信号。    

2.ADC的转换过程

采样 ===> 量化 ===> 编码

3.ADC类型

    ADC有积分型和逐次逼近型的区分,积分型电路简单,成本低,转换时间比较长。逐次逼近型成本相对高,转换速度相对快。

3.6V = 2.5V + 0.625V + 0.3125V +......

4.stm32f4的内部ADC

 

ADC测量电路:

滑动变阻器的分压引脚连接到了PA5,PA5具有ADC12通道5的复用功能。

5.ADC的库函数编程

    工程中添加ADC的库函数源码:

(1)开启GPIOA和ADC1的时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

(2)将GPIO配置成模拟功能

GPIO_Init(...);

(3)复位ADC

ADC_DeInit(...);

(4)初始化ADC的分频系数(通用)

void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
//参数就是ADC通用初始化结构

typedef struct 
{
  uint32_t ADC_Mode;
/*!< 模式选择 多重/独立 @ref ADC_Common_mode */                                              
  uint32_t ADC_Prescaler;                 
/*!< 分频系数 4分频 @ref ADC_Prescaler */
  uint32_t ADC_DMAAccessMode;             
/*!< DMA模式选择 @ref ADC_Direct_memory_access_mode_for_multi_mode */
  uint32_t ADC_TwoSamplingDelay;          
/*!< 2次采样时间间隔 5时钟周期  @ref ADC_delay_between_2_sampling_phases */
  
}ADC_CommonInitTypeDef;

(5)初始化ADC1,设置工作模式,规则序列(专用配置)

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); 
参数:     ADCx - 哪个ADC     
ADC_InitStruct - ADC初始化结构   
typedef struct 
{   uint32_t ADC_Resolution; /*!< 分辨率 12位 @ref ADC_resolution */                       
    FunctionalState ADC_ScanConvMode; /*!< 扫描使能 ENABLE or DISABLE */  
    FunctionalState ADC_ContinuousConvMode; /*!< 连续转换使能 ENABLE or DISABLE. */ 
    uint32_t ADC_ExternalTrigConvEdge;      
    /*!< 外部触发信号选择 @ref ADC_external_trigger_edge_for_regu  
    lar_channels_conversion */ uint32_t ADC_ExternalTrigConv;          
   /*!< 外部触发选择 @ref ADC_extrenal_trigger_sources_for_regul  ar_channels_conversion */   uint32_t ADC_DataAlign; /*!< 数据对齐选择 @ref ADC_data_align */   uint8_t  ADC_NbrOfConversion; /*!< 规则序列长度 1 to 16. */ 
}ADC_InitTypeDef;    

(6)使能ADC

ADC_Cmd(ADC1,ENABLE);

(7)配置规则通道参数(哪个通道,采样周期)

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

 参数:    
 ADCx - 哪个ADC     
ADC_Channel - 哪个通道    
 Rank - 规则组的编号    
 ADC_SampleTime - 采样周期

(8)使用软件信号启动转换

void ADC_SoftwareStartConv(ADC_TypeDef* ADCx);

(9)等待转换完成

while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)!=SET);

(10)获取转换结果

uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);

_____________________________________________________________________________

_____________________________________________________________________________

1.概念和特性

 DAC就是将数字信号转换成模拟信号,程序给定数字值,通过DAC输出模拟信号。

可以选择PA4作为DAC的输出引脚,连接到了P8的5号引脚上。

    需要添加DAC库函数源码:

(1)开启GPIO和DAC时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

(2)将GPIO配置为模拟功能

GPIO_Init(...);

(3)初始化DAC

void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct); 
参数:    
 DAC_Channel - 哪个通道    
DAC_InitStruct - DAC初始化结构      
 typedef struct {   
  uint32_t DAC_Trigger;/*!< 外部触发选择 @ref DAC_trigger_selection */   
  uint32_t DAC_WaveGeneration;  
 /*!< 产生波形配置 @ref DAC_wave_generation */   uint32_t DAC_LFSRUnmask_TriangleAmplitude;
  /*!< 噪声波形相关 @ref DAC_lfsrunmask_triangleamplitude */   uint32_t DAC_OutputBuffer;
  /*!< 输出缓冲开关 @ref DAC_output_buffer */ 
  }DAC_InitTypeDef;    

(4)使能DAC转换通道

DAC_Cmd(DAC_Channel_1,ENABLE);

(5)设置DAC的输出值

void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data);

参数:     DAC_Align - 输出数据对齐方式 

                 DAC_Align_12b_R     Data - 输出值

——————————————————————————————————————————————————————————————————————————————————————

1.DMA概念

    DMA,叫做直接内存访问(Direct Memory Access),是内存和外设之间直接交互数据的一种方式,无需CPU的参与。只是通过硬件为内存和I/O设备开辟一条直接传输数据的通道,完全脱离了CPU的操作,大大提高了效率。

2.stm32的DMA

DMA数据流的映射关系:

DMA1:

转存失败重新上传取消

DMA2:

3.DMA的工作流程

    当外设产生事件后,向DMA控制器发送请求信号,DMA控制器根据优先级处理该请求。当DMA控制器访问外设时,DMA控制器会向外设发送确认信号,外设释放该请求。完成DMA请求后外设可以继续下一个动作。

4.stm32的ADC - DMA编程

    添加DMA库函数源码:

(1)和轮询一样配置ADC(开启连续转换)

(2)开启DMA的时钟

(3)使能ADC的DMA请求

ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

ADC_DMACmd(ADC1, ENABLE);

(4)初始化DMA对ADC1的处理

void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct); 
参数:DMAy_Streamx - 哪个DMA的哪个数据流     
     DMA_InitStruct - DMA初始化结构      typedef struct { uint32_t DMA_Channel;            
/*!< 哪个通道 @ref DMA_channel */   
uint32_t DMA_PeripheralBaseAddr; 
/*!< 外设数据寄存器地址. */ 
uint32_t DMA_Memory0BaseAddr;    
/*!< 目标内存地址 */ 
uint32_t DMA_DIR;                
/*!< 数据传输方向 @ref DMA_data_transfer_direction */ 
uint32_t DMA_BufferSize;         
/*!< 一次传输的数据量 */ 
uint32_t DMA_PeripheralInc;      
/*!< 外设地址是否递增 @ref DMA_peripheral_incremented_mode */ 
uint32_t DMA_MemoryInc;          
/*!< 内存地址是否递增 @ref DMA_memory_incremented_mode */ 
uint32_t DMA_PeripheralDataSize; 
/*!< 外设的数据量大小 @ref DMA_peripheral_data_size */ 
uint32_t DMA_MemoryDataSize;     
/*!< 内存的数据量大小 @ref DMA_memory_data_size */ 
uint32_t DMA_Mode;               
/*!< DMA模式选择 循环/单次 @ref DMA_circular_normal_mode */ 
uint32_t DMA_Priority;           
/*!< DMA通道优先级 @ref DMA_priority_level */ 
uint32_t DMA_FIFOMode;          
/*!< DMA FIFO选择 @ref DMA_fifo_direct_mode */ 
uint32_t DMA_FIFOThreshold;      
/*!< DMA FIFO配置 @ref DMA_fifo_threshold_level */ 
uint32_t DMA_MemoryBurst;        
/*!< 内存单次/多次传输选择 @ref DMA_memory_burst */ 
uint32_t DMA_PeripheralBurst;    
/*!< 外设单次/多次传输选择 @ref DMA_peripheral_burst */   
}DMA_InitTypeDef;

(5)使能DMA

void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState); 参数:     DMAy_Streamx - 哪个DMA的哪个数据流     NewState - 使能/禁止

(6)直接从内存上获取ADC转换的结果

猜你喜欢

转载自blog.csdn.net/weixin_44651073/article/details/125861896