STM32 标准库 ————学习笔记

1 篇文章 0 订阅
1 篇文章 0 订阅

STM32 标准库 ————学习笔记

By:weixiaozxk
基于江科大自协整理
以STM32F4系列为例
ps:强制类型转换方式:uint16_t (value*100)%100;

一、GPIO
1.八大模式

在这里插入图片描述

2.GPIO配置
	GPIO_InitTypeDef  GPIO_InitStructure;   //初始化GPIO结构体
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);   //初始化引脚时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;   //初始化GPIO引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   //配置GPIO为输出模式  
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  //配置GPIO为推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  //配置GPIO传输速度
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    //配置上下拉电阻
	GPIO_Init(GPIOB, &GPIO_InitStructure);      //GPIO总初始化

常用函数

    /**
      * GPIO_TypeDef* GPIOx 
      * GPIO_Pin
      * BitAction BitVal: Bit_RESET 低电平
                         Bit_SET 高电平
    **/
    GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
    /**
     * 函数功能:GPIO输出高电平
     * GPIO_TypeDef* GPIOx
     * uint16_t GPIO_Pin:引脚
     **/
    GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    /**
     * 函数功能:GPIO输出低电平
     * GPIO_TypeDef* GPIOx
     * uint16_t GPIO_Pin:引脚
     **/
     GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    /**
     * 函数功能:GPIO翻转电平
     * GPIO_TypeDef* GPIOx
     * uint16_t GPIO_Pin:引脚
     **/  
     GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
二、LED
1.led.c
//LED初始化
void LED_init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;   //初始化GPIO结构体
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);   //初始化引脚时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;   //初始化GPIO引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   //配置GPIO为输出模式  
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  //配置GPIO为推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  //配置GPIO传输速度
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    //配置上下拉电阻
	GPIO_Init(GPIOB, &GPIO_InitStructure);      //GPIO总初始化    
}

//开启LED
void LED_ON(void)
{
    GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
//关闭LED
void LED_OFF(void)
{
    GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
//翻转LED
void LED_Turn(void)
{
    if(GPIO输出寄存器(GPIO_ReadOutputDataBit)==0)
    {
        GPIO_ToggleBits(GPIOA, uint16_t GPIO_Pin_1)}
}
2.led.h
#ifndef __LED_H
#define __LED_H

void LED_init(void);
void LED_ON(void);
void LED_OFF(void);
void LED_Turn(void);
#endif
三、KEY(高低电平版)
1.key.c
#include "stm32f40x.h"

void Key_init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;   //初始化GPIO结构体
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);   //初始化引脚时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;   //初始化GPIO引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   //配置GPIO为输出模式  
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  //配置GPIO为推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  //配置GPIO传输速度
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    //配置上下拉电阻
	GPIO_Init(GPIOB, &GPIO_InitStructure);      //GPIO总初始化       
}   
uint8_t Key_GetNum(void)
{
    uint8_t KeyNum=0;
    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5==0))
    {
        delay_ms(20);
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==0);
        delay_ms(20);
        KeyNum=1;
    }

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6==0))
    {
        delay_ms(20);
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)==0);
        delay_ms(20);
        KeyNum=2;
    }

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7==0))
    {
        delay_ms(20);
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==0);
        delay_ms(20);
        KeyNum=3;
    }
    return KeyNum;
}
2.key.h
#ifndef __KEY_H
#define __KEY_H

void Key_init(void);
uint8_t Key_GetNum(void);
#endif
3.main.h
#include "key.h"
#include "led.h"
uint8_t KeyNum;

int main()
{
        Key_init();
        Key_GetNum();

    while(1)
    {
        KeyNum=Key_GetNum();
        if(KeyNum==1)   //按键1
        {
            LED_ON();
        }
        if(KeyNum==2)   //按键2
        {
            LED_OFF();
        }
        if(KeyNum==3)   //按键3
        {
            LED_Turn();
        }
    }
}
四、EXTI

RCC->AFIO(复用功能重映射)->EXTI->NVIC->CPU
F4系列中没有AFIO需要配置SYSCFG存储器
EXIT函数

        EXTI_InitTypeDef EXTI_InitStructure;//结构体类型名EXTI_InitTypeDef,变量名EXTI_InitStructure
	EXTI_InitStructure.EXTI_Line = EXTI_Line14; //根据所配置的GPIO引脚选择EXIT_Line数字
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//GPIO_Mode_IPU设置为高电平,触发中断是下降
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

    //检查外部中断状态
    EXTI_GetITStatus(uint32_t EXTI_Line);
    // 清除中断标志位
    EXTI_ClearITPendingBit(uint32_t EXTI_Line);
1.EXTI.c

带有AFIO板卡中断函数的编写

#include "stm32f10x.h"

void EXTI_init(void)
{
	//第一步,时钟配置
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//开启AFIO时钟
	//EXTI和NVIC两个外设的时钟是一直开的 ,NVIC内核外设都是不需要开启时钟
 
	//第二步,配置GPIO
	//首先定义结构体
	GPIO_InitTypeDef GPIO_InitStructure;  //结构体名字GPIO_InitStructure
	//将结构体成员引出来
	//对于EXTI来说,模式为浮空输入|上拉输入|下拉输入;不知该写什么模式,可以看参考手册中的外设GPIO配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //由于GPIO为输入模式传输速度无限制
	//最后初始化GPIO
	GPIO_Init(GPIOB,&GPIO_InitStructure);	
	
	//第三步,配置AFIO外设中断引脚选择
	//AFIO的库函数是和GPIO在一个文件里,可以查看Library文件中的gpio.h查看函数
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//代表连接PB14号口的第14个中断线路
	
	//第四步,配置EXTI,这样PB14的电平信号就能够通过EXTI通向下一级的NVIC了
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//因为上面是GPIO_Mode_IPU设置为高电平,所以触发中断是下降
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	//第五步,配置NVIC,NVIC是内核外设,所以它的库函数在misc.h
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //分组方式,整个芯片只能用一种。如放在模块中进行分组,要确保每个模块分组都选的是同一个;或者将这个代码放在主函数的最开始
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//查询中断向量表获得
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);	
}

void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line14) == SET)
    {

        //事件

        EXTI_ClearITPendingBit(EXTI_Line14);
    }
}

F4为例不带有AFIO

#include "stm32f40x.h"

void EXTI_init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//开启中断时钟

    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_D;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //配置中断
    NVIC_InitTypeDef   NVIC_InitStructure;
    EXTI_InitTypeDef   EXTI_InitStructure;
        
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource0);

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);    
}

void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) == SET)
    {
        
        //事件

        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}
5.EXTI.h
#ifndef __EXTI_H
#define __EXTI_H
void EXTI_init(void);
#endif
五、TIM

常用函数

/*定时器结构体定义*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* 配置定时器参数 */
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 10000;
TIM_TimeBaseStructure.TIM_Prescaler = 8400 - 1; // TIMER3时钟频率84MHz
/*定时器初始化*/
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/*使能中断*/
TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE);
/***使能计数器***/
TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

计算公式:
定时频率=主频/(PSC+1)/(ARR+1)

1.timer.c
void Timer_init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  //初始化结构体
	NVIC_InitTypeDef NVIC_InitStructure;    //初始化NVIC结构体
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); 
	
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    //设置向上计数
	TIM_TimeBaseStructure.TIM_Period = 10000;   //自动重装载值
	TIM_TimeBaseStructure.TIM_Prescaler = 8400 - 1;     //预分频系数
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);     //初始化定时器
	
	TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE);   //使能中断
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
	NVIC_Init(&NVIC_InitStructure); 
	
	TIM_Cmd(TIM3,ENABLE);   //使能定时器
}

void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //获取中断标志位
	{ 
        // {}中为中断处理
	}
	TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除更新中断
}
2.timer.h
#ifndef __TIMER_H
#define __TIMER_H
void Timer_init(void);
#endif
六、PWM

常用函数

    /*结构体*/
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    //初始化TIM3 Channel2 PWM模式         
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性
    TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器

PWM频率=定时频率
PWM占空比=CCR/(ARR+1)

1.PWM.c
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,  ENABLE);	//使能定时器3时钟
 	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);   //使能GPIO外设
	   
 
   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOB5
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
	
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3); //复用
 
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc - 1; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM3 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
 
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
 
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
	
}  

输出函数

    void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); //(TIMx,CRR)
2.PWM.h
#ifndef __PWM_H
#define __PWM_H
void TIM3_PWM_Init(u16 arr,u16 psc);
#endif
七、ADC

ADC采样通道分为规则组与注入组,规则组有16个通道,一般ADC采样选择规则组,注入组有4个通道,不常用。
规则组:用于设置和转换一组指定通道的组。这些通道按照预定义的顺序和参数逐个进行转换。规则组的转换通常是连续的,且可以循环进行。规则组适用于需要持续监测或周期性采样的场景。
注入组:注入组则用于在规则组转换过程中临时插入对某些通道的转换。当需要中断规则组的转换,对某些特定通道进行快速采样时,可以使用注入组。注入组的转换可以看作是规则组转换过程中的一个中断或插入操作。

ADC规则组的四种转换模式

单次转换非扫描模式
单次转换扫描模式
连续转换非扫描模式
连续转换扫描模式

常用配置函数

/*ADC时钟开启函数*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/*ADC公共配置*/
    ADC_CommonInitTypeDef ADC_CommonInitStruct; //ADC初始化公共配置结构体

    ADC_DeInit();//ADC复位

    ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;  //禁用DMA访问模式
    ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;     //设置ADC为独立模式
    ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div4;  //预分频:设置四分频
    ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles; //采样时钟周期

    ADC_CommonInit(&ADC_CommonInitStruct);  //启用ADC公共配置
/*ADC特定配置*/
    ADC_InitTypeDef ADC_InitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);    //ADC初始化特定配置结构体

    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;    //禁用连续转换,使用单次转换
    ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;   //使用右对齐方式
    ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;  //禁用外部触发转换,使用软件触发转换
    ADC_InitStruct.ADC_NbrOfConversion=1;   //设置转换数量(采集通道数量)单采集设置1,不采用扫描模式
    ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;   //设置ADC分辨率
    ADC_InitStruct.ADC_ScanConvMode = DISABLE;  //禁用or使用扫描模式(单or多)

    ADC_Init(ADC1, &ADC_InitStruct);    //启用ADC特定配置

/*ADC1使能*/
    ADC_Cmd(ADC1, ENABLE);
(单通道)AD.c
void Adc_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStruct;
    ADC_InitTypeDef ADC_InitStruct;

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

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    //不上拉不下拉电阻
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_DeInit();//ADC复位

    ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;  //禁用DMA访问模式
    ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;     //设置ADC为独立模式
    ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div4;  //预分频:设置四分频
    ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles; //采样时钟周期

    ADC_CommonInit(&ADC_CommonInitStruct);


    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;    //禁用连续转换,使用单次转换
    ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;   //使用右对齐方式
    ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;  //禁用外部触发转换,使用软件触发转换
    ADC_InitStruct.ADC_NbrOfConversion=1;   //设置转换数量(采集通道数量)单采集设置1,不采用扫描模式
    ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;   //设置ADC分辨率
    ADC_InitStruct.ADC_ScanConvMode = DISABLE;  //禁用or使用扫描模式(单or多)

    ADC_Init(ADC1, &ADC_InitStruct);

    ADC_Cmd(ADC1, ENABLE);
}

/**********************************************************
 * 函 数 名 称:Get_ADC_Value
 * 函 数 功 能:读取ADC值
 * 传 入 参 数:ADC_CHANNEL_x=要采集的通道
**********************************************************/
unsigned int Get_ADC_Value(uint8_t  ADC_CHANNEL_x)
{
    unsigned int adc_value = 0;
    //设置采集通道
    ADC_RegularChannelConfig(ADC1, CHx, 1, ADC_SampleTime_480Cycles );
    //开始软件转换
    ADC_SoftwareStartConv(ADC1);
    // 等待转换结束
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
    
    //读取采样值
    adc_value = ADC_GetConversionValue(ADC1);
    
    //返回采样值
    return adc_value;
}

 /**********************************************************
 * 函 数 名 称:Get_Adc_Average
 * 函 数 功 能:计算得出某个通道给定次数采样的平均值 
 * 传 入 参 数:CHx                :通道数字
 *             times              :采集次数
**********************************************************/
uint16_t Get_Adc_Average(uint8_t CHx,uint8_t times)
{
         
        uint32_t value = 0;
        uint8_t t;
        
        for(t=0;t<times;t++)
        {
            value += Get_Adc(CHx);
            delay_ms(5);
        }
        return value/times;
}
(单通道)AD.h
#ifndef __AD_H
#define __AD_H
void Adc_Init(void);
unsigned int Get_ADC_Value(uint8_t  ADC_CHANNEL_x);
uint16_t Get_Adc_Average(uint8_t CHx,uint8_t times)
#endif
(单通道)main.c
int main(void)
{
	Adc_Init();
	
	while(1)
	{
		uint16_t value = Get_Adc_Average(ADC_Channel_0,20);
		

	}
	

}
(多通道)AD.c
void Adc_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStruct;
    ADC_InitTypeDef ADC_InitStruct;

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

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    //不上拉不下拉电阻
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_DeInit();//ADC复位

    ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;  //禁用DMA访问模式
    ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;     //设置ADC为独立模式
    ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div4;  //预分频:设置四分频
    ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles; //采样时钟周期

    ADC_CommonInit(&ADC_CommonInitStruct);


    ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;    //禁用连续转换,使用单次转换
    ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;   //使用右对齐方式
    ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;  //禁用外部触发转换,使用软件触发转换
    ADC_InitStruct.ADC_NbrOfConversion=1;   //设置转换数量(采集通道数量)单采集设置1,不采用扫描模式
    ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;   //设置ADC分辨率
    ADC_InitStruct.ADC_ScanConvMode = DISABLE;  //禁用or使用扫描模式(单or多)

    ADC_Init(ADC1, &ADC_InitStruct);

    ADC_Cmd(ADC1, ENABLE);
}

/**********************************************************
 * 函 数 名 称:Get_ADC_Value
 * 函 数 功 能:读取ADC值
 * 传 入 参 数:ADC_CHANNEL_x=要采集的通道
**********************************************************/
unsigned int Get_ADC_Value(uint8_t  ADC_CHANNEL_x)
{
    unsigned int adc_value = 0;
    //设置采集通道
    ADC_RegularChannelConfig(ADC1, CHx, 1, ADC_SampleTime_480Cycles );
    //开始软件转换
    ADC_SoftwareStartConv(ADC1);
    // 等待转换结束
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
    
    //读取采样值
    adc_value = ADC_GetConversionValue(ADC1);
    
    //返回采样值
    return adc_value;
}

 /**********************************************************
 * 函 数 名 称:Get_Adc_Average
 * 函 数 功 能:计算得出某个通道给定次数采样的平均值 
 * 传 入 参 数:CHx                :通道数字
 *             times              :采集次数
**********************************************************/
uint16_t Get_Adc_Average(uint8_t CHx,uint8_t times)
{
         
        uint32_t value = 0;
        uint8_t t;
        
        for(t=0;t<times;t++)
        {
            value += Get_Adc(CHx);
            delay_ms(5);
        }
        return value/times;
}
(多通道)AD.h
#ifndef __AD_H
#define __AD_H
void Adc_Init(void);
unsigned int Get_ADC_Value(uint8_t  ADC_CHANNEL_x);
uint16_t Get_Adc_Average(uint8_t CHx,uint8_t times)
#endif
(多通道)main.c
int main(void)
{
	Adc_Init();
	
	while(1)
	{
		uint16_t value1  = Get_Adc_Average(ADC_Channel_0,20);
		uint16_t value2  = Get_Adc_Average(ADC_Channel_1,20);
        uint16_t value3  = Get_Adc_Average(ADC_Channel_2,20);
        uint16_t value3  = Get_Adc_Average(ADC_Channel_3,20);       
	}
}
八、DMA
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值