可能有些朋友在别的论坛看到我发过类似的帖子,但这并不是一个帖子发多个论坛,因为某些原因,那个论坛我并不打算继续更帖;而是借着STM32社区这个平台继续完成。
在学校学习期间,曾遇到很多问题,有幸遇到了一些老师和朋友为我解答。现在看到一些学弟学习STM32的时候感觉很困难,遂在此写下个人浅显的见解,希望在他们遇到困难的时候能帮上一点忙。
如果大家发现有错误,希望大家能够指出,别让我误导大家了,哈哈。
我对STM32也并不精通,在这一过程中大家一起学习。
说说为什么用寄存器,现在有大量工具帮助大家建立工程,生成初始化代码,但是个人感觉学单片机这类东西还是要了解一下它的大致结构的,反正我不习惯用CubeMX这一类工具,这类工具让我觉得像是站在棉花上,没有脚踏实地的感觉,虚虚的。
大部分人写的第一个程序应该是“hello world”,第一个单片机程序应该是“点亮LED”,那我们就继续这种老套路。
我们先点个灯。
先说下,平台是STM32F469DIS板卡。
看看原理图中有关LED那部分 图中LED1—LED4分别是接在PG6、PD4、PD5、PK3引脚上,我们先点亮LED2试试。 贴出代码: - /*
- 开启GPIOD的时钟
- */
- RCC->AHB1ENR |= 0x01<<3;
- /*
- 将GPIOD->MODER寄存器中PIN4对应的位清零
- (在这里,这一步其实可以省略,单片机复位之后便是0)
- 并不是所有端口复位之后都是清零的
- */
- GPIOD->MODER &=~(0x03<<(2*4));
- /*
- 将GPIOD->PIN4设置为输出模式
- */
- GPIOD->MODER |= 0x01<<(2*4);
- /*
- 设置输出速度为中速(25MHz)
- */
- GPIOD->OSPEEDR |= 0x01<<(2*4);
- /*
- 设置输出类型为通用推挽输出
- */
- GPIOD->OTYPER &=~(0x01<<4);
- /*
- 设置引脚输出低电平
- */
- GPIOD->ODR &=~(0x01<<4);
复制代码
RCC->AHB1ENR |= 0x01<<3; 这条语句是开启GPIOD这个端口的时钟,STM32(其实不只是STM32)为了降低功耗,将外设的驱动时钟层层细化,并且可以单独控制,大部分外设的时钟默认是关闭的,所以我们如果要这个外设工作,第一件事便是打开它的驱动时钟。 这张图便是STM32的时钟树,可能现在看起来有点懵逼,但是随着深入之后慢慢就理解了。 为什么是操作AHB1总线上的寄存器呢,我们看下面这张图 这张图清晰的描述了部分外设的地址分布,GPIO端口正是挂载在AHB1总线上;所以,我们要操作GPIO外设就要配置AHB1中控制GPIO外设的寄存器,哪个寄存器呢,当然是使能寄存器 寄存器第三位便是GPIOD端口时钟的使能位,我们往里面写入1即可。 所以RCC->AHB1ENR |= 0x01<<3; 这条语句便是将AHB1ENR寄存器中的值先读出来,再在第三位(相对于第零位)上或上1,再写回去。
打开了GPIOD端口的时钟,我们再配置好GPIOD的相应寄存器,相应引脚便可以输出高低电平了。 这就列出了GPIO的寄存器 我们并不需要配置所有的寄存器,可以视情况而定,有些寄存器可以保持它复位后的状态即可。这里没有用上的寄存器或是对某些寄存器功能仍有疑惑,可以查看参考手册第7章通用IO
GPIOD->MODER &=~(0x03<<(2*4)); GPIOD->MODER |= 0x01<<(2*4); MODER寄存器两个位控制了一个引脚,我们先将PD4对应的MODER寄存器清零(清零是为了防止运行这段代码之前对相应位进行了操作),MODERx中x便是标识这个位控制的第几个引脚; GPIOD->MODER &=~(0x03<<(2*4)); 清零之后,我们需要将其设置成相应模式,图中可以看到01是通用输出模式。
GPIOD->MODER |= 0x01<<(2*4);
GPIOD->OSPEEDR |= 0x01<<(2*4); 这句是设置引脚输出速度。没有清零是因为在这之前并没有对相应位进行操作,复位值便是‘00’,我们将其设置为了‘01’中速模式(25MHz);
GPIOD->OTYPER &=~(0x01<<4); 这句便是只清零,没有置位,是因为我们保持‘0’即可,即下图所示的推挽模式。
我们并没有将GPIOD对应的寄存器全部配置一遍,因为有些寄存器在这个程序中并没有用上,像AFR寄存器、IDR寄存器。
配置完这些之后,PD4这个引脚基本就可以使用了 GPIOD->ODR &=~(0x01<<4); 我们往ODR寄存器中的相应位置为0,LED灯就亮了。 为什么是写‘0’亮LED?逻辑有些颠倒。 写‘0’,引脚输出低电平,根据原理图可知,只有引脚输出低电平LED才能导通。
配个效果图
最终的代码我做了一些修改,但是应该能看懂(有同学说看不懂我的代码,嗯~~我要面壁反思一下)
|