打印
[其他ST产品]

STM32F1常用外设介绍

[复制链接]
楼主: 范德萨发额
手机看帖
扫描二维码
随时随地手机跟帖
181
范德萨发额|  楼主 | 2023-2-28 20:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
ADC规则组通道配置函数

它的作用是给序列每个位置填写的指定的通道,就是填写点菜点菜的过程

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

使用特权

评论回复
182
范德萨发额|  楼主 | 2023-2-28 20:37 | 只看该作者
外部触发转换控制函数
是否允许外部触发转换

void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

使用特权

评论回复
183
范德萨发额|  楼主 | 2023-2-28 20:37 | 只看该作者
ADC获取转换值函数

获取AD转换的数据寄存器,读取转换结构就需要使用这个函数

uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);

使用特权

评论回复
184
范德萨发额|  楼主 | 2023-2-28 20:38 | 只看该作者
ADC获取双模式转换值

读取双ADC模式转换结果的函数

uint32_t ADC_GetDualModeConversionValue(void);

使用特权

评论回复
185
范德萨发额|  楼主 | 2023-2-28 20:38 | 只看该作者
注入组相关函数

void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);

使用特权

评论回复
186
范德萨发额|  楼主 | 2023-2-28 20:38 | 只看该作者
配置模拟看门狗相关函数

void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);//是否启动模拟看门狗
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);//配置高低阈值
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);//配置看门的通道

使用特权

评论回复
187
范德萨发额|  楼主 | 2023-2-28 20:38 | 只看该作者
用来控制开启内部的两个通道函数

用来控制开启内部的两个通道(ADC温度传感器,内部参考电压控制),如果要用到这两个通道需要调用这个函数

void ADC_TempSensorVrefintCmd(FunctionalState NewState);

使用特权

评论回复
188
范德萨发额|  楼主 | 2023-2-28 20:38 | 只看该作者
获取标志位状态函数

FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);

使用特权

评论回复
189
范德萨发额|  楼主 | 2023-2-28 20:39 | 只看该作者
清除标志位函数

void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);

使用特权

评论回复
190
范德萨发额|  楼主 | 2023-2-28 20:40 | 只看该作者
获取中断状态函数

ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);

使用特权

评论回复
191
范德萨发额|  楼主 | 2023-2-28 20:40 | 只看该作者
清除中断挂起位

void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);

使用特权

评论回复
192
范德萨发额|  楼主 | 2023-2-28 20:46 | 只看该作者
ADC程序实例
void AD_Init(void)
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
       
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);
       
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
               
        ADC_InitTypeDef ADC_InitStructure;
        ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
        ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续模式
        ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描模式
        ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数
        ADC_Init(ADC1, &ADC_InitStructure);
       
        ADC_Cmd(ADC1, ENABLE);//开启ADC
       
        ADC_ResetCalibration(ADC1);//开始复位校准
        while (ADC_GetResetCalibrationStatus(ADC1) == SET);//获取复位校准状态
        ADC_StartCalibration(ADC1);//开始校准
        while (ADC_GetCalibrationStatus(ADC1) == SET);//获取校准状态
}

uint16_t AD_GetValue(uint8_t ADC_Channel)
{
        ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);//设置规则组的函数
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发
        while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//获取校准完成标志位
        return ADC_GetConversionValue(ADC1);//返回转换完的AD值
}

使用特权

评论回复
193
范德萨发额|  楼主 | 2023-2-28 20:47 | 只看该作者
DMA

    DMA(Direct Memory Access)直接存储器存取,主要是用来协助CPU,完成数据转运的工作

    DMA可以提供外设(外设寄存器,一般是外设的数据寄存器DR,Data Register,比如ADC的数据寄存器,串口的数据寄存器)和存储器(运行内存(SRAM)和程序存储器(Flash)是存储变量数组和程序代码的地方)或者存储器与存储器之前的高速数据传输,无须CPU干预,节省了CPU的资源

    12个独立可配置的通道(数据转运的路径):DMA1(7个通道),DMA2(5个通道)

    每个通道都支持软件触发和特定的硬件触发,存储器到存储器的数据转运,一般用软件触发,外设到存储器的转运一般用硬件触发

    STM32F103C8T6 DMA资源:DMA1(7个通道)

使用特权

评论回复
194
范德萨发额|  楼主 | 2023-2-28 20:47 | 只看该作者
存储器映像

计算机系统的5大组成部分:运算器、控制器、存储器、输入设备和输出设备,运算器和控制器一般合在一起叫做CPU,计算机的核心关键部分就是CPU和存储器,存储器最重要的是存储器的内容和存储器的地址。

使用特权

评论回复
195
范德萨发额|  楼主 | 2023-2-28 20:47 | 只看该作者
存储器分为两大类:ROM和RAM,ROM就是只读存储器,是一种非易失性、掉电不丢失的存储器,RAM就是随机存储器,是一种易失性、掉电丢失的存储器,ROM分为三块,第一块是程序存储器,Flash,也就是主闪存,用途就是存储C语言编译后的程序代码,也就是下载程序的位置,运行程序一般也是从主闪存中开始运行的,系统存储器和选项字节,这两块存储器也是ROM的一种,掉电不丢失,实际上它们的存储介质也是Flash,非主闪存Flash,系统存储器是用来存储BootLoader,BootLoader程序一般是芯片出厂自动写入的,一般不允许修改,选项字节存的主要是Flash的读保护、写保护,还有看门狗等等的配置,运行内存SRAM存储我们程序中定义变量、数组、结构体的地方,外设寄存器存储的是我们初始化各个外设,最终读写的东西,外设寄存器起始也是SRAM,存储内核外设NVIC和SysTick。

使用特权

评论回复
196
范德萨发额|  楼主 | 2023-2-28 20:47 | 只看该作者
DMA的框图

使用特权

评论回复
197
范德萨发额|  楼主 | 2023-2-28 20:48 | 只看该作者
左上角是Cortex-M3内核,里面包含了CPU和内核外设,剩下的所有东西都可以看成是存储器,Flash是主闪存,SRAM是运行内存,各个外设都可以看成是寄存器,也是一种SRAM存储器,寄存器是一种特殊的存储器,一方面,CPU可以对寄存器进行读写,就像读写运行内存一样,另一方面,寄存器的每一位背后,都连接了一根导线,这些导线可以控制外设电路的状态,比如置引脚的高低电平,导通和断开、切换数据寄存器,或者多位结合起来,当做计数器、数据寄存器,寄存器是连接软件和硬件的桥梁,软件读写寄存器,就相当于在控制硬件的执行,使用DMA进行数据转运,就相当于从某个地址取内容,再放到另一个地址去。

使用特权

评论回复
198
范德萨发额|  楼主 | 2023-2-28 20:48 | 只看该作者
为了高效有条理地访问存储器,设计了一个总线矩7阵,总线矩阵的左端,是主动单元,也就是拥有存储器的访问权,右边这些,就是被动单元,它们的存储器只能被左边的主动单元读写,主动单元内核有DCode和系统总线,可以访问右边的存储器,其中DCode总线是专门访问Flash的,系统总线是访问其他东西的,由于DMA要转运数据,所以DMA也必须要有访问的主动权,主动单元除了内核、CPU剩下的就是DMA总线了,DMA1和DMA2都各自有一条总线,下面以太网外设自己也私有一个DMA总线,DMA1有7个通道,DMA2有5个通道,各个通道可以分别设置它们转运数据的源地址和目的地址,下面的仲裁器,由于DMA只有一条总线,仲裁器可以根据通道的优先级决定哪个通道谁先用,在总线矩阵里,也有一个仲裁器,如果DMA和CPU都要访问同一个目标,那么DMA就会暂停CPU的访问,以防止冲突,不过总线仲裁器,仍然会保证CPU得到一半的总线带宽,使CPU也能正常工作,下面的AHB从设备,也就是DMA自身的寄存器,DMA作为一个外设,也会有自己相应的配置寄存器,连接上了总线右边的AHB总线上,所以DMA既是总线矩阵的主动单元,可以读写各种存储器,也是AHB总线上的被动单元,DMA请求就是DMA的硬件触发源,比如说ADC转换完成、串口接收到数据需要触发DMA转运数据的时候,就会通过这条线路,向DMA发出硬件触发信号,之后DMA就可以执行数据转运的工作了,这就是DMA请求的作用。15

使用特权

评论回复
199
范德萨发额|  楼主 | 2023-2-28 20:48 | 只看该作者
Flash是ROM只读存储器的一种,如果通过总线直接访问的话,无论是CPU,还是DMA,都是只读的,只能读取数据,而不能写入,如果DMA的目的地址,填写了Flash的区域,那转运时就会出错。也可以配置Flash接口控制器,对Flash进行写入,先对Flash进行擦除,再写入数据。

使用特权

评论回复
200
范德萨发额|  楼主 | 2023-2-28 20:49 | 只看该作者
DMA的基本结构图

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则