最近学习STM32F103 I/O编程的过程中,尝试用按钮上拉输入来出发PORTC13的LED,根据芯片手册,开启PORTC时钟,选择PORTC13为最大速度2MHz的通用推挽输出模式(GPIOC_CRH 23:20位置为“0010”),测试Blink,成功。
进一步加入按键控制功能,选择PORTB11口(离GND比较近),开启PORTB始终,选择PORTB11为上拉输入模式(GPIOB_CRH 15:12位置为“1000”,GPIOB_ODR 11位置为“1”),烧录测试,PORTB11电压没有拉高,与GND短接无反应。
void led_init(){
*(unsigned int *)0x40021018 |= ((1) << 4);//开启PORTC时钟
*(unsigned int *)0x40011004 |= ((2) << (4*5));//配置PORTC13
}
void key_init(){
*(unsigned int *)0x40021018 |= ((1) << 3);//开启PORTB时钟
*(unsigned int *)0X40010C04 |= ((8) << 4*3);//配置PORTB11
*(unsigned int *)0X40010C0C |= ((1) << 11);//配置PORTB11为上拉
}
检查编译无数次快要放弃的时候,偶然注意到芯片手册“5.2 GPIO寄存器描述”中“端口配置寄存器”的复位值为0x44444444,即GPIOx_CRH的四位从高到低为0100(浮空输入模式),与我们所,而代码中用|=配置并未清除默认配置,导致实际配置的功能与期望不符,我的做法是在配置功能前先清除复位默认配置,即在初始化代码中加入一行,编译烧录测试成功!
void led_init(){
*(unsigned int *)0x40021018 |= ((1) << 4);//开启PORTC时钟
*(unsigned int *)0x40011004 &= ~((15) << 4*5);//清除PORTC13复位默认配置
*(unsigned int *)0x40011004 |= ((2) << (4*5));//配置PORTC13
}
void key_init(){
*(unsigned int *)0x40021018 |= ((1) << 3);//开启PORTB时钟
*(unsigned int *)0X40010C04 &= ~((15) << 4*3);//清除PORTB11复位默认配置
*(unsigned int *)0X40010C04 |= ((8) << 4*3);//配置PORTB11
*(unsigned int *)0X40010C0C |= ((1) << 11);//配置PORTB11为上拉
}
完整代码:
#include "stm32f10x.h"
void led_reverse(){
*(unsigned int *)0x4001100C ^= ((1) << 13);
}
void delay(uint32_t nCount)
{
nCount *= 10;
for(; nCount != 0; nCount--);
}
void led_init(){
*(unsigned int *)0x40021018 |= ((1) << 4);//开启PORTC时钟
*(unsigned int *)0x40011004 &= ~((15) << 4*5);//清除PORTC13复位默认配置
*(unsigned int *)0x40011004 |= ((2) << (4*5));//配置PORTC13
}
void key_init(){
*(unsigned int *)0x40021018 |= ((1) << 3);//开启PORTB时钟
*(unsigned int *)0X40010C04 &= ~((15) << 4*3);//清除PORTB11复位默认配置
*(unsigned int *)0X40010C04 |= ((8) << 4*3);//配置PORTB11
*(unsigned int *)0X40010C0C |= ((1) << 11);//配置PORTB11为上拉
}
int main()
{
led_init();
key_init();
while(1)
{
if (((*(unsigned int *)0X40010C08) >> (11) & 1) == 0)
{
led_reverse();
while(((*(unsigned int *)0X40010C08) >> (11) & 1) == 0);
delay(0xFFFF);//加入延时去抖动
}
else
delay(0xFFFF);
}
}