当前位置:文档之家› STM32学习笔记

STM32学习笔记

STM32学习笔记整理
端口复用配置过程
引脚具体可以复用为啥功能,参考芯片手册STM32F103ZET6.Pdf
具体每个引脚配置成什么模式,参考STM32中文参考手册,第八章,通用IO和复用。

NVIC中断
假定设置中断优先级组为2,然后设置
中断3(RTC中断)的抢占优先级为2,响应优先级为1。

中断6(外部中断0)的抢占优先级为3,响应优先级为0。

中断7(外部中断1)的抢占优先级为2,响应优先级为0。

那么这3个中断的优先级顺序为:中断7>中断3>中断6
特别说明:
一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。

随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

首先,系统运行后先设置中断优先级分组。

调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
整个系统执行过程中,只设置一次中断分组。

然后,中断初始化函数
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器
结构体内容NVIC_InitTypeDef
typedef struct
{
uint8_t NVIC_IRQChannel; //设置中断通道
uint8_t NVIC_IRQChannelPreemptionPriority;//设置响应优先级
uint8_t NVIC_IRQChannelSubPriority; //设置抢占优先级
FunctionalState NVIC_IRQChannelCmd; //使能/使能
} NVIC_InitTypeDef;
串口部分
常用寄存器
USART_SR状态寄存器
USART_DR数据寄存器
USART_BRR波特率寄存器
常用库函数
void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能void USART_Cmd();//使能串口
void USART_ITConfig();//使能相关中断
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
FlagStatus USART_GetFlagStatus();//获取状态标志位SR
void USART_ClearFlag();//清除状态标志位SR
ITStatus USART_GetITStatus();//获取中断状态标志位SR
void USART_ClearITPendingBit();//清除中断状态标志位SR
配置步骤
1串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd(); ++++++复位时钟
2串口复位:USART_DeInit(); 这一步不是必须的
3GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF_PP //复用,具体查表
4串口参数初始化:USART_Init();
5开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
NVIC_Init();
USART_ITConfig();
6使能串口:USART_Cmd();
7编写中断处理函数:USARTx_IRQHandler();
8串口数据收发:
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
9串口传输状态获取:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
外部中断配置步骤
初始化IO口为输入。

GPIO_Init();
开启IO口复用时钟。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
设置IO口与中断线的映射关系。

void GPIO_EXTILineConfig();
初始化线上中断,设置触发条件等。

EXTI_Init();
配置中断分组(NVIC),并使能中断。

NVIC_Init();
编写中断服务函数。

EXTIx_IRQHandler();
清除中断标志位
EXTI_ClearITPendingBit();
独立看门狗
常用库函数
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消写保护:0x5555使能void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//设置预分频系数:写PR
void IWDG_SetReload(uint16_t Reload);//设置重装载值:写RLR
void IWDG_ReloadCounter(void);//喂狗:写0xAAAA到KR
void IWDG_Enable(void);//使能看门狗:写0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);//状态:重装载/预分频更新
配置步骤
取消寄存器写保护:
IWDG_WriteAccessCmd();
设置独立看门狗的预分频系数,确定时钟:
IWDG_SetPrescaler();
设置看门狗重装载值,确定溢出时间:
IWDG_SetReload();
使能看门狗
IWDG_Enable();
应用程序喂狗:
IWDG_ReloadCounter()
溢出时间计算:
Tout=((4×2^prer) ×rlr) /40 (M3)
通用定时器Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk
Tclk时钟频率默认72M (PSC+1)/Tclk一个周期时间
使能定时器时钟。

RCC_APB1PeriphClockCmd();
初始化定时器,配置ARR,PSC。

TIM_TimeBaseInit();
开启定时器中断,配置NVIC。

void TIM_ITConfig();
NVIC_Init();
使能定时器。

TIM_Cmd();
编写中断服务函数。

TIMx_IRQHandler();
TIM_TimeBaseInit()部分简介
TIM_TimeBaseStructure.TIM_Period = 4999; TIM_TimeBaseStructure.TIM_Prescaler =7199;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
通用定时器产生PWM
1使能定时器3和相关IO口时钟。

使能定时器3时钟:RCC_APB1PeriphClockCmd();
使能GPIOB时钟:RCC_APB2PeriphClockCmd();
2 初始化IO口为复用功能输出。

函数:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
3这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,
所以需要开启AFIO时钟。

同时设置重映射。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
4 初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
5 初始化输出比较参数:TIM_OC2Init();
6 使能预装载寄存器:TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
7 使能定时器。

TIM_Cmd();
8 不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();。

相关主题