1、调试现象
这个问题是在调试一个产品的LED显示的功能,LED嘛无非就是配置好GPIO然后拉高或者拉低就行了,这个在嵌入式工作中也很常见想必各位大佬觉得,调个LED能有啥强度,,Emmmmm,一开始我也是这么想的,所以很快把驱动配置好了;然而程序烧录后居然没点亮,啪啪打脸,让我们先看看代码(本文代码基于stm32F103C8T6平台):
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_InitStructrue; GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOB,&GPIO_InitStructrue); while(1) { GPIO_ResetBits(GPIOB,GPIO_Pin_4); vTaskDelay(200); GPIO_SetBits(GPIOB,GPIO_Pin_4); vTaskDelay(200); }这一看跟平常没有任何区别是吧;按道理LED应该上电就立马闪烁起来。然而一动不动,像是无声的嘲讽(具体调试过程这里就不赘述了,,,我们之间看问题所在)
2、问题原因
其实导致LED的无法点亮的原因很简单,那就是PB4这个引脚比较特殊,MCU上电复位后默认这个引脚就是上拉的(我们这里的硬件电路是低电平点亮);并且如上的代码配置PB4为推挽输出模式后还无法控制这个引脚,原因如下图所示:(图片取自MCU用户手册)
首先回答上文说的问题,PB4为什么特殊?
因为这个引脚默认配置为JTAG调试口的JNTRST脚(GPIO的复用功能);并如图所示上电复位后置于上拉模式;类似的还有图中所示的PA15、PA14和PA13这三个IO口。
3、解决问题
OK那么问题找到了,我们就开始解决问题,首先我们看用户手册的描述,如下图:
上图显示,如果需要使用PB4引脚,我们至少需要将SWJ_CFG这个寄存器配置为001;其他的010和100根据工程实际情况来进行配置。除此之外因为涉及GPIO复用功能,所以我们在使用特殊引脚的时候,需要将AFIO的时钟使能,这样才能正常使用GPIO的复用功能。
修改后的代码如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIO_InitStructrue; GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_4; GPIO_PinRemapConfig( GPIO_Remap_SWJ_NoJTRST, ENABLE); GPIO_Init(GPIOB,&GPIO_InitStructrue); while(1) { GPIO_ResetBits(GPIOB,GPIO_Pin_4); vTaskDelay(200); GPIO_SetBits(GPIOB,GPIO_Pin_4); vTaskDelay(200); }