一、前言

        STM32芯片组成

        ARM内核+ST设计的外围电路

         系统结构

        工程架构 

二、GPIO 

1、GPIO简介

1、GPIO通用输入输出口

2、引脚电平:0~3.3V

3、输出模式:输出高低电平、驱动LED、蜂鸣器等

4、输入模式:读取端口电平、ADC电压采集、读取按键输入等

2、GPIO基本结构

GPIO挂载在APB2总线上

3、GPIO八种模式 

4、GPIO程序步骤 

 1、使用RCC开启GPIO的时钟

作用:使能(开启)或失能(关闭)APB2外设时钟

RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
参数 说明 示例
RCC_APB2Periph 指明需要开启的是哪一个APB2外设

RCC_APB2Periph_AFIO,

RCC_APB2Periph_GPIOA,

RCC_APB2Periph_GPIOB,
RCC_APB2Periph_GPIOC,

RCC_APB2Periph_GPIOD,

RCC_APB2Periph_GPIOE,

RCC_APB2Periph_GPIOF,

RCC_APB2Periph_GPIOG,

RCC_APB2Periph_ADC1,
RCC_APB2Periph_ADC2,

RCC_APB2Periph_ADC3,

RCC_APB2Periph_USART1,

RCC_APB2Periph_SPI1,

RCC_APB2Periph_TIM1,
 RCC_APB2Periph_TIM8,
RCC_APB2Periph_TIM15,

RCC_APB2Periph_TIM16,

RCC_APB2Periph_TIM17,
RCC_APB2Periph_TIM9,

RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 

NewState NewState:指定外设时钟的新状态 

ENABLE(打开) 

DISABLE(关闭)

2、使用GPIO_Init函数初始化GPIO

作用:根据GPIO_InitStruct中的指定参数初始化GPIOx外设

GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
参数 说明 示例
GPIOx 其中x可以为(A…G)选择GPIO外设。

GPIOA,

GPIOB,
GPIOC,

GPIOD,

GPIOE,

GPIOF,

GPIOG,

GPIO_InitStruct 指向GPIO InitTypeDef结构的指针,该结构包含指定GPIO外设的配置信息。

typedef struct

{
   GPIO_Pin;           
   GPIO_Speed;      
   GPIO_Mode;   
}GPIO_InitTypeDef;

参数说明:

3、使用输出或者输入的函数控制GPIO口

写引脚:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);    //可以对16个端口同时写入

读引脚:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);  //读取某一位
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);      //读取整个寄存器

翻转:

if(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5)==0)   //读输出引脚
	{
		GPIO_SetBits(GPIOB, GPIO_Pin_5);           //翻转
	}
	else
	{
		GPIO_ResetBits(GPIOB, GPIO_Pin_5);
	}

三、外部中断EXIT

1、中断简介

        主程序运行中,发生中断时,使CPU暂停当前正在运行的程序,转去处理中断程序,处理完后又返回原来被暂停的位置继续运行

        有68个可屏蔽中断源,包括了EXIT、TIM、ADC、USART、SPI、I2C、RTC等多个外设

2、NVIC简介

NVIC:嵌套向量中断控制器。用来管理中断

NVIC基本结构:

NVIC优先级分组:

3、EXIT简介

外部中断,检测GPIO口的电平,当指定的GPIO发生变化,向NVIC发送中断信号,产生中断

触发方式:1、上升沿

                  2、下降沿

                  3、双边沿

                  4、软件触发

支持的GPIO口:所有GPIO口。但不同组的相同Pin不能同时触发。例如:PA0、PB0、PC0等

触发方式:中断响应(触发中断)   /    事件响应(不触发中断,中断信号不传给CPU处理,而是触发其他外设)

4、EXIT基本结构

5、AFIO复用IO口

作用:复用引脚重映射、中断引脚选择 

6、EXIT程序步骤

1、配置RCC,将程序涉及外设的时钟都打开(有GPIO和AFIO)

RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)

2、使用GPIO_Init函数初始化GPIO

GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

3、配置AFIO

作用:选择硬件所用的那一路GPIO,连接到后面的EXTI作用。

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
参数 说明 示例
GPIO_PortSource 选择要用作EXTI线路源的GPIO端口

GPIO_PortSourceGPIOA,

GPIO_PortSourceGPIOB,
GPIO_PortSourceGPIOC,

GPIO_PortSourceGPIOD,

GPIO_PortSourceGPIOE,

GPIO_PortSourceGPIOF,

GPIO_PortSourceGPIOG,

GPIO_PinSource GPIO_PinSource:要配置的EXTI线路

GPIO_PinSource0

GPIO_PinSource1

……

GPIO_PinSource15

4、配置EXTI

作用:1、选择边沿触发方式,比如上升沿、下降沿或者双边沿,还有选择触发响应方式,可以选择中断响应和事件响应

          2、根据EXTI InitStruct中的指定参数初始化EXTI外设

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)

参数说明:

参数 说明 示例
EXTI_InitStruct 指向EXTI InitTypeDef结构体的指针包含EXTI外设的配置信息。

typedef struct

{
  EXTI_Line;          
  EXTI_Mode;    
  EXTI_Trigger; 
  EXTI_LineCmd;  
}EXTI_InitTypeDef;

5、配置NVIC

1.1、配置优先级分组,抢占优先级和响应优先级

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

参数说明:

参数 说明 示例
NVIC_PriorityGroup 指定优先级分组位长度。

NVIC_PriorityGroup_0(0位抢占,4位响应)

NVIC_PriorityGroup_1(1位抢占,3位响应)

NVIC_PriorityGroup_2(2位抢占,2位响应)

NVIC_PriorityGroup_3(3位抢占,1位响应)

NVIC_PriorityGroup_4(4位抢占,0位响应)

1.2、初始化NVIC

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

参数说明:

6、实现中断函数 

中断向量表:

         根据中断向量表,找到所需中断函数,这里面以IRQHandler结尾的字符串就是中断函数的名字,再根据名字写中断函数。

void EXTI3_IRQHandler(void)
{
    if(EXTI_GetITStatus(uint32_t EXTI_Line)==1)  //判断中断标志位是否设置
    {
        /*
        中断执行的任务
       */
    }
    EXTI_ClearITPendingBit(uint32_t EXTI_Line); //最后要清除中断标志位,结束中断
}

常用的EXIT函数: 

EXTI_GetITStatus(uint32_t EXTI_Line);  //检查指定的外部中断上的中断标志是否被设置。
EXTI_ClearITPendingBit(uint32_t EXTI_Line); //清除中断标志位,结束中断

四、TIM定时中断

1、TIM简介

        STM32的定时器拥有16位计数器、预分频器、自动重装载寄存器的时基单元,在72MHZ计数时钟下可以实现最大59.65s的定时

        不仅具备基本定时中断功能,还包括内外时钟源选择、输入捕获、输出比较、主从触发等模式

        通用、基本、高级定时器基本频率都是72MHZ

  2、定时器类型

 3、定时器中断基本结构

 4、时钟树

 5、定时器中断程序步骤

1.1、定时器内部时钟

1、开启定时器的RCC时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   //开启TIM2时钟
2、选择时基单元的时钟源为内部时钟源

        对于定时中断,我们就选择内部时钟源

        函数作用:定时器TIMx配置内部时钟

TIM_InternalClockConfig(TIM_TypeDef* TIMx)
参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

3、配置时基单元

作用:设置预分频器、自动重装器、计数模式等等,这些参数用一个结构体就可以配置好了。

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

参数说明: 

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_TimeBaseInitStruct 指向结构 TIM_TimeBaseInitTypeDef 的指针,包含了 TIMx 时间基数单位的配置信息

typedef struct
{
  TIM_Prescaler;  

  TIM_CounterMode;

  TIM_Period; 
  TIM_ClockDivision;                  TIM_RepetitionCounter;

}

TIM_TimeBaseInitTypeDef; 

4、配置输出中断控制

作用:允许更新中断输出到NVIC(开启更新中断到NVIC的通路) 

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)

参数说明:

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_IT TIM 中断类型

TIM_IT_Update(更新中断)

TIM_IT_CC1(捕获/比较中断)

TIM_IT_CC2(捕获/比较中断)

TIM_IT_CC3(捕获/比较中断)

TIM_IT_CC4(捕获/比较中断)
TIM_IT_COM(换向中断)
TIM_IT_Trigger(触发中断)
TIM_IT_Break(制动中断)

NewState TIMx 中断的新状态

ENABLE

DISABLE

5、配置NVIC

作用:在NMC中打开定时器中断的通道,并分配一个优先级


	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_InitStruct);
6、启动定时器

作用:整个模块配置完成后,需要使能计数器。要不然计数器是不会运行的。当定时器使能后,计数器就会开始计数了,当计数器更新时,触发中断

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

 参数说明:

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

NewState TIMx 中断的新状态

ENABLE

DISABLE

7、实现定时中断函数
void TIM2_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update)==1)  //判断中断标志位是否设置
    {
        /*
        中断执行的任务
       */
    }
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //最后要清除中断标志位,结束中断
}

常用函数:

1.2、定时器外部时钟 

1、开启GPIO的RCC时钟

将定时器的ETR引脚对应的GPIO设置为输入模式

2、时基单元的时钟源设置为外部模式2
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_ExtTRGPrescaler 外部触发预分频

TIM_ExtTRGPSC_OFF

TIM_ExtTRGPSC_DIV2

TIM_ExtTRGPSC_DIV4

TIM_ExtTRGPSC_DIV8

TIM_ExtTRGPolarity 设置外部触发信号的极性

TIM_ExtTRGPolarity_Inverted(低电平或下降沿)

TIM_ExtTRGPolarity_NonInverted(高电平或上升沿)

ExtTRGFilter 设置外部触发信号的滤波器 0x00~0x0F

五、TIM输出比较

1、输出比较简介

        OC(输出比较)

        通过比较CNT(计数器)与CCR寄存器(捕获/比较寄存器)的值,来对输出电平进行置1、0或翻转,用于输出一定频率和占空比的PWM波形

        每个高级和通用定时器都拥有4个输出比较通道

2、输出比较通道

3、输出比较模式

 4、PWM基本结构

5、参数计算 

6、输出比较程序步骤 

1、RCC开启时钟

        把我们要用的TIM外设和GPIO外设的时钟打开

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

2、配置时基单元

TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

3、配置输出比较单元

作用:主要配置包括CCR的值、输出比较模式、极性选择、输出使能等参数

void TIM_OCXInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)  //通道X

参数说明:

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_OCInitStruct 指向结构 TIM_OCInitTypeDef 的指针,包含了 TIMx 时间基数单位的配置信息

typedef struct
{
  TIM_OCMode;  

  TIM_OCPolarity;

  TIM_OutputState; 
  TIM_Pulse;

}TIM_OCInitTypeDef 

注意:通用定时器一般只使用TIM_OCInitStruct结构体部分成员,另一些是高级定时器专属,但是必须初始化,然后在修改结构体成员,所以使用结构体初始化函数

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct)

4、配置定时器某个通道所使用的GPIO引脚

 作用:把PWM对应的GPIO口,初始化为复用推挽输出的配置

只有把GPIO设置成复用推挽输出,引脚的控制权才能交给片上外设,PWM波形才能通过引脚输出

5、启动定时器 

TIM_Cmd(TIM2, ENABLE);

6、实现PWM 

作用:更改CCR的值

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)  //通道1
参数 说明
TIMx 所选择的TIM外设,对于通用定时器来说是2、3、4
Compare1 指定捕获比较程序寄存器的新值

7、引脚重映射

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //开启AFIO
	
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);   //引脚重映射

六、TIM输入捕获

1、输入捕获简介        

        输入捕获模式下,当通道输入引脚发生指定电平跳变,当前CNT的值将锁存到CCR中,可用于测量PWM波形的频率、占空比、电平持续时间等参数

        配置为PWMI模式,同时测量频率和占空比

        可配合主从触发模式,实现硬件全自动测量

2、输入捕获通道

3、主从触发模式 

4、输入捕获基本结构 

 5、输入捕获程序步骤

1、RCC开启时钟,把GPIO和TIM的时钟打开

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

2、GPIO初始化,把GPIO设置成输入模式

GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);

3、配置时基单元

作用:让CNT计数器在内部时钟的驱动下自增运行

TIM_InternalClockConfig(TIM3);
	
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=65536-1;
TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);

4、配置输入捕获单元

作用:设置滤波器、极性、直连通道还是交叉通道、分频器等参数

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);   //配置一个通道
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);  //配置两个通道

参数说明:

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_ICInitStruct 指向结构 TIM_ICInitTypeDef 的指针,包含了 TIMx 输入捕获的配置信息

typedef struct
{
  TIM_Channel;  

  TIM_ICFilter;

  TIM_ICPolarity; 
  TIM_ICPrescaler;

  TIM_ICSelection;

}TIM_ICInitTypeDef 

5、选择从模式的触发源

作用:配置TRGI的触发源为TI1FP1

void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

参数说明:

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_InputTriggerSource 选择触发源

TIM_TS_ITR0
 TIM_TS_ITR1 

 TIM_TS_ITR2

 TIM_TS_ITR3
  TIM_TS_TI1F_ED

  TIM_TS_TI1FP1

TIM_TS_TI2FP2

TIM_TS_ETRF

6、设置从模式执行的操作

作用:选择触发之后执行的操作。执行Reset操作

void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);

参数说明:

参数 说明 示例
TIMx 所选择的 TIM 外设

TIM1

TIM8

TIM_SlaveMode 从模式执行的操作

TIM_SlaveMode_Reset
 TIM_SlaveMode_Gated

 TIM_SlaveMode_Trigger

 TIM_SlaveMode_External1

7、开启定时器

TIM_Cmd(TIM4, ENABLE);

 8、读取CCR值

TIM_GetCapture1(TIM_TypeDef* TIMx);     //获取通道1的计数值

9、PWMI模式

         通道1是直连,上升沿触发,把通道2设置成交叉连接,下降沿触发,有专门函数

可实现频率与占空比同时测量

TIM_PWMIConfig(TIM3, &TIM_ICInitStruct);

七、ADC

1、ADC简介

12位逐次逼近型ADC,1us转换时间

输入电压范围:0~3.3V,转换结果:0~4095

18个输入通道,16个GPIO和2个内部信号源

规则组和注入组两个转换单元

2、ADC框图

3、ADC基本结构

 3、输入通道

 4、转换模式

5、转换时间 

STM32 ADC总转换时间:T=采样时间+12.5个ADC周期

ADC最大频率14MHZ,最短转换时间为 T=1.5+12.5=14个ADC周期=1us

6、ADC单通道程序步骤

1、开启RCC时钟,包括ADC和GPIO的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

2、配置ADCCLK

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)    //ADCCLK最大14MHZ

参数说明:

参数 说明 示例
RCC_PCLK2 ADC的频率

RCC_PCLK2_Div2

RCC_PCLK2_Div4

RCC_PCLK2_Div6

RCC_PCLK2_Div8

3、配置GPIO

作用:将GPIO配置成模拟输入模式

	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

4、配置多路开关,将指定的外部通道接入规则组

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
参数 说明 示例
ADCx 指定的ADC

ADC1

ADC2

ADC3

ADC_Channel 指定ADC的通道

ADC_Channel_0

ADC_Channel_17

Rank 规则组序列里的次序 1~16
SampleTime 指定通道的采样时间

ADC_SampleTime_1Cycles5

ADC_SampleTime_7Cycles5

ADC_SampleTime_13Cycles5

ADC_SampleTime_28Cycles5

ADC_SampleTime_41Cycles5

ADC_SampleTime_55Cycles5

ADC_SampleTime_71Cycles5

ADC_SampleTime_239Cycles5

5、配置ADC转换器

作用:配置ADC是单次转换或连续转换,扫描或非扫描模式、通道个数、触发源、数据对齐方式

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);

参数说明:

参数 说明 示例
ADCx 指定的ADC

ADC1

ADC2

ADC3

ADC_InitStruct 指向结构 ADC_InitTypeDef 的指针,包含了ADC的配置信息

typedf struct

{

   ADC_Mode;

   ADC_ScanConvMode;

   ADC_ContinuousConvMode;

   ADC_ExternalTrigConv;

   ADC_DataAlign;

   ADC_NbrOfChannel;

}ADC_InitTypeDef

6、开启ADC

ADC_Cmd(ADC1,ENABLE);

7、校准ADC

void ADC_ResetCalibration(ADC_TypeDef* ADCx);      //开启复位校准
ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);  //获取复位校准的状态
ADC_StartCalibration(ADC_TypeDef* ADCx);           //启动校准
ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);       //获取校准状态

 8、获取转换值

 ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);  //软件触发转换
ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);   //获取状态标志位

 参数说明:

参数 说明 示例
ADCx 指定的ADC

ADC1

ADC2

ADC3

ADC_FLAG 想获取的标志位

ADC_FLAG_AWD(模拟看门狗标志位)

ADC_FLAG_EOC(规则组转换完成标志位,为1时转换完成)

ADC_FLAG_JEOC(注入组转换完成标志位)

ADC_FLAG_JSTRT(注入组开始转换标志位)

ADC_FLAG_STRT(规则组开始转换标志位) 

ADC_GetConversionValue(ADC_TypeDef* ADCx);   //获取ADC转换值

八、DMA 

1、DMA简介

DMA提供外设和存储器,存储器和存储器之间的高速数据传输,无需CPU干预

12个独立可配置的通道:DMA1(7个通道)、DMA2(5个通道)

每个通道都支持软件触发和特定的硬件触发

2、存储器映像

DMA虽然有多个 通道,但是一次只能转运一个通道

3、DMA基本结构 

 注意:写传输计数器时,先关闭DMA,在进行

4、DMA工作方式

 5、DMA存储器到存储器程序步骤

1、RCC开启DMA的时钟

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 2、配置DMA

作用:初始化外设和存储器的起始地址、数据宽度、地址是否自增、方向、传输计数器、选择触发源等

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);

 参数说明:

参数 说明 示例
DMAy_Channelx 指定的DMA和通道

DMA1_Channel1

DMA1_Channel7

DMA2_Channel1

DMA2_Channel5

DMA_InitStruct 指向结构 DMA_InitTypeDef 的指针,包含了DMA的配置信息

typedf struct

{

   DMA_PeripheralBaseAddr;

   DMA_PeripheralDataSize;

   DMA_PeripheralInc;

   DMA_MemoryBaseAddr;

   DMA_MemoryDataSize;

   DMA_MemoryInc;

   DMA_BufferSize;

   DMA_DIR;

   DMA_M2M;

   DMA_Mode;

   DMA_Priority;

}DMA_InitTypeDef 

3、给指定DMA通道使能

DMA_Cmd(DMA1_Channel1,ENABLE);

4、再次DMA转运

DMA_Cmd(DMA1_Channel1,DISABLE);   //关闭DMA
DMA_SetCurrDataCounter(DMA1_Channel1,MySize);   //给传输计时器赋值
DMA_Cmd(DMA1_Channel1,ENABLE);   //打开DMA
DMA_GetFlagStatus(uint32_t DMAy_FLAG)  //查看标志位,等待转运完成

参数说明:

参数 说明 示例
DMAy_FLAG 需要查看的标志位

DMA1_FLAG_GL1(全局标志位)

DMA1_FLAG_TC1(转运完成标志位)

DMA1_FLAG_HT1(转运过半标志位)

DMA1_FLAG_TE1(转运错误标志位)

DMA_ClearFlag(uint32_t DMAy_FLAG)   //清除转运完成标志位,转运完成置1

6、DMA外设到存储器程序步骤

1、失能外设地址自增

DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;

2、选择硬件触发

DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;

3、ADC开启DMA触发信号

ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState)

九、USART串口通信

1、通信接口

2、电平标准 

3、串口参数及时序 

 4、USART简介

        USART是STM32内部集成的硬件外设,可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)、校验位(无/偶/奇)

5、串口发送程序步骤

1、开启USART和GPIO的RCC时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //USART1是APB2的外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

2、GPIO初始化,把TX配置成复用输出,RX配置成输入

GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;         //PA9是TX引脚
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitTypeDef GPIO_InitStruct1;
GPIO_InitStruct1.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct1.GPIO_Pin=GPIO_Pin_10;        //PA10是RX引脚
GPIO_InitStruct1.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct1);

3、配置USART

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);

参数说明:

参数 说明 示例
USARTx 指定的USART

USART1

USART2

USART3

USART_InitStruct 指向结构 USART_InitTypeDef 的指针,包含了USART的配置信息

typedf struct

{

   USART_BaudRate;

   USART_HardwareFlowControl 

   USART_Mode;

   USART_Parity;

   USART_StopBits;

   USART_WordLength;

}USART_InitTypeDef 

4、使能USART 

USART_Cmd(USART1,ENABLE);

5、串口常用函数

USART_SendData(USART_TypeDef* USARTx, uint16_t Data);   //串口发送
USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);  //获取标志位

 参数说明:

参数 说明 示例
USARTx 指定的USART

USART1

USART2

USART3

USART_FLAG 指定的标志位

USART_FLAG_CTS

USART_FLAG_LBD

USART_FLAG_TXE(发送寄存器的值转入移位寄存器)

USART_FLAG_TC

USART_FLAG_RXNE(读寄存器值转入移位寄存器)

USART_FLAG_IDLE

USART_FLAG_ORE

USART_FLAG_NE

USART_FLAG_FE

USART_FLAG_PE

USART_ReceiveData(USART1)   //接收数据
USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
//串口开启中断

6、USART串口数据包

十、WDG

1、WDG简介

        WDG看门狗,当程序出现卡死或跑飞时,看门狗能及时复位程序,保证系统的可靠性和安全性。

        看门狗本质上是一个定时器,指定时间范围内,程序没有执行喂狗操作时,即定时器到时间,看门狗硬件就会产生复位信号。

        STM32包含:独立看门狗(IWDG):独立工作,对时间精度要求较低

                                窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用

2、IWDG框图

3、 IWDG键寄存器

4、IWDG超时时间 

5、WWDG 框图

6、WWDG工作特性 

7、WWDG超时时间 

8、IWDG和WWDG对比 

9、IWDG程序步骤 

1、开启LSI时钟

        STM32的LSI时钟通常会在看门狗使能时自动开启,而无需手动干预

2、解除寄存器的写保护

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)

参数说明:

参数 说明 示例
IWDG_WriteAccess 使能或失能IWDG

IWDG_WriteAccess_Enable

IWDG_WriteAccess_Disable

3、写入预分频和重装值

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)

参数说明:

参数 说明 示例
IWDG_Prescaler 配置预分频

IWDG_Prescaler_4

IWDG_Prescaler_8

IWDG_Prescaler_16

IWDG_Prescaler_32

IWDG_Prescaler_64

IWDG_Prescaler_128

IWDG_Prescaler_256

void IWDG_SetReload(uint16_t Reload)

参数说明:

参数 说明 示例
Reload 配置重装值

0~0FFF

4、启动独立看门狗

IWDG_Enable(void)

5、喂狗

IWDG_ReloadCounter(void)

 10、WWDG程序步骤

1、开启窗口看门狗APB1时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);

2、配置预分频器、窗口值寄存器

void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);  //设置预分频

 参数说明:

参数 说明 示例
Prescaler 配置预分频

WWDG_Prescaler_1

WWDG_Prescaler_2

WWDG_Prescaler_4

WWDG_Prescaler_8

void WWDG_SetWindowValue(uint8_t WindowValue);   //配置上窗口值

参数说明: 

参数 说明 示例
WindowValue 配置窗口上限

>0x3F

<0x80

3、使能WWDG

WWDG_Enable(uint8_t Counter);

参数说明:

参数 说明 示例
Counter 配置计数器值

>0x3F

<0x80

4、喂狗

void WWDG_SetCounter(uint8_t Counter)

十一、RTC实时时钟 

1、Unix时间戳

        unix时间戳是一个从1970年1月1日0时0分0秒开始到现在经过的秒数

2、BKP简介

        BKP(备份寄存器),当主电源VDD断电,可以由VBAT(备用电源)维持供电。当系统在待机模式下被唤醒,或系统复位,BKP的值不会复位。

3、BKP基本结构

4、RTC简介 

• RTC(实时时钟),是一个独立定时器,为系统提供时钟和日历

• RTC和时钟配置系统处于后备区域,系统复位数据不清零。

• 32位的可编程计数器,对应Unix时间戳的秒计数器

• 20位的可编程预分频器,适配不同频率的输入时钟 

• 可选择三种RTC时钟源:

                                                HSE时钟/128  (8MHZ/128)

                                                 LSE振荡器时钟(32.768KHZ)

                                                 LSI振荡器时钟(40KHZ)

5、RTC框图

6、RTC基本结构

7、读写BKP寄存器程序步骤

1、开启PWR和BKP时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);

2、使用PWR的函数,使能对BKP和RTC的访问

void PWR_BackupAccessCmd(FunctionalState NewState);

3、写入BKP函数

void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);

参数说明:

参数 说明 示例
BKP_DR 需要写入的BKP的DR寄存器

BKP_DRx

4、读取BKP函数

uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);

8、RTC实时时钟程序步骤 

1、开启PWR和BKP时钟,使能对BKP和RTC的访问

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);
	
	PWR_BackupAccessCmd(ENABLE);

2、启动RTC的时钟

作用:开启LSE时钟

void RCC_LSEConfig(uint8_t RCC_LSE)
RCC_GetFlagStatus(RCC_FLAG_LSERDY)  //获取LSE标志位

参数说明:

参数 说明 示例
RCC_LSE 开启或关闭LSE外部晶振

RCC_LSE_OFF

RCC_LSE_ON

RCC_LSE_Bypass

3、配置RTCCLK数据选择器,指定LSE为RTCCLK

void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)

参数说明:

参数 说明 示例
RCC_RTCCLKSource 指定RTC的时钟源

RCC_RTCCLKSource_LSE

RCC_RTCCLKSource_LSI

RCC_RTCCLKSource_HSE_Div128

 4、使能时钟

RCC_RTCCLKCmd(ENABLE);

5、等待时钟同步

void RTC_WaitForSynchro(void)

5、等待RTC寄存器上一次写操作完成

RTC_WaitForLastTask();

6、设置预分频器

void RTC_SetPrescaler(uint32_t PrescalerValue)

7、配置CNT计数器的值

void RTC_SetCounter(uint32_t CounterValue)

8、读取计数器值

RTC_GetCounter()

9、时间戳转换

​​​​​​

作者:qq_52885172

物联沃分享整理
物联沃-IOTWORD物联网 » STM32技术详解

发表回复