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转换的结果