stm32mini串口笔记

一,端口复用

  stm32的很多内置外设都是和GPIO复用的。如串口一的引脚对应IO为PA9和PA10,这两个IO口默认为GPIO引脚,而当我们将其作为串口一的RX和TX引脚使用的时候,就称为端口复用。

  复用端口初始化有几个步骤:

1) GPIO 端口时钟使能。

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

2) 复用的外设时钟使能。

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

3) 端口模式配置。 在 IO 复用位内置外设功能引脚的时候,必须设置 GPIO 端口的模式。

要初始化GPIO和复用外设功能。

串口模式和GPIO模式的对应关系是:

USART引脚配置GPIO配置
USARTx_TX全双工模式推挽复用输出
USARTx_TX半双工同步模式推挽复用输出
USARTx_RX全双工模式浮空输入或带上拉输入
USARTx_RX半双工同步模式未用,可作为通用IO

 例如:

//USART1_TX PA.9 复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX PA.10 浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); 

二,重映射

  一个 外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚 映射到其它的端口。

例如,我们由重映射表可知,串口复用的TX和RX可以重映射到PB6和PB7上。

所以我们在重映射时不仅要使能GPIO时钟和串口时钟(复用的外设),还要使能AFIO时钟,然后调用重映射函数。

1)使能 GPIOB 时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

2)使能串口 1 时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

3)使能 AFIO 时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

4)开启重映射: GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);

三,中断优先级管理

中断寄存器:

1)ISER[8]这是一个中断使能寄存器组。

CM3 内核由256个中断,由8个32位寄存器控制,但STM32F103只用了其中的60个,则我们只需用到ISER[0],ISER[1].我们可以设置对应的ISER位为1,给对应的中断使能.

2)ICER[8]:,是一个中断除能寄存器组。作用与ISER相反,给对应的ICER位置1,则取消相应位的使能。

注意:NVIC的寄存器都是写1有效,写0无效。

3)ISPR[8]:是一个中断挂起控制寄存器组。每个位 对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别 的中断。

4)ICPR[8]:是一个中断解挂控制寄存器组。其作 用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断接挂.

5)IABR[8]:,是一个中断激活标志位寄存器组。对应位 所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄 存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。

6)IP[240]:是一个中断优先级控制的寄存器组。STM32 的中断分组与这个寄存器组密切相关。IP 寄存器组由 240 个 8bit 的寄 存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32 只用到 了其中的前 60 个。IP[59]~IP[0]分别对应中断 59~0。而每个可屏蔽中断占用的 8bit 并没有全部 使用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先 级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。

stm32中断分组:

AIRCR[10:8]bit[7:4]分配情况分配结果
0111

0:4

0 位抢占优先级,4 位响应优先级
11101:31位抢占优先级,3位响应优先级
21012:22位抢占优先级,2位响应优先级
31003:13 位抢占优先级,1 位响应优先级
40114:04 位抢占优先级,0 位响应优先级

例如组设置为 3,那么此时 所有的 60 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是 响应优先级。每个中断,你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。抢占优先级的 级别高于响应优先级。而数值越小所代表的优先级就越高。

这里需要注意两点:第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看 哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级 中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。

之后是库函数的讲解,首先要讲解的是中断优先级分组函数 NVIC_PriorityGroupConfig,其函数申明如下: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次,一旦分组确定就最好不要更改。这个函数唯一目的就是通过设置 SCB->AIRCR 寄存器来设置中断优先级分组。

比如我们设置整个系统的中断优先级分组值 为 2,那么方法是: NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)

这样就确定了一共为“2 位抢占优先级,2 位响应优先级”。

确定中断优先级占位后,之后就是确定每个中断的抢占优先级和响应优先级。

我们需要用到中断初始化函数 NVIC_Init,其函数申明为:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 其中 NVIC_InitTypeDef 是一个结构体,我们可以看看结构体的成员变量:

typedef struct
{
 uint8_t NVIC_IRQChannel; 
 uint8_t NVIC_IRQChannelPreemptionPriority;
 uint8_t NVIC_IRQChannelSubPriority; 
 FunctionalState NVIC_IRQChannelCmd; 
} NVIC_InitTypeDef:

NVIC_InitTypeDef结构体中间有三个成员变量,这三个成员变量的作用是:

NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到 每个中断对应的名字。例如 USART1_IRQn。

NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。 NVIC_IRQChannelSubPriority:定义这个中断的子优先级别。

NVIC_IRQChannelCmd:该中断是否使能。

比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,子优先级位 2,初始化的方法是:

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 寄存

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值