你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于stm32的流水灯简单入门分享

[复制链接]
攻城狮Melo 发布时间:2023-3-26 17:59
前言
解决了驱动问题以后终于可以开始学习STM32了。学习过程中参考的资料是《STM32库开发实战指南》,板子用的是正点原子的NANO开发板,具体型号是STM32F103RBT6。废话不多说,记录一下自己写的流水灯实验。

一、开始前的准备——初步了解STM32时钟系统、学习GPIO工作模式及初始化的过程
1、STM32时钟系统
STM32有四个时钟源,具体为HSE(高速外部时钟)、LSE(低速外部时钟)、HSI(高速内部时钟)、LSI(低速内部时钟)。其中,HSE由外部晶振提供,一般作为STM32主时钟;内部时钟(HSI&&LSI)均由内部RC振荡器产生,HSI一般为8MHz,STM32启动时默认使用HSI;LSI主要给看门狗提供时钟源,一般是40KHz;LSE一般给RTC模块(实时时钟)提供时钟源,频率为32.768KHz。


2、GPIO工作模式

GPIOx工作于输入模式:

模拟输入模式、高阻输入模式、上拉/下拉输入模式;

GPIOx工作于输出模式:
推挽输出模式、开漏输出模式、复用推挽输出模式、复用开漏输出模式。

注:
推挽输出即输出真正的高低电平,外设于IO之间不加上拉电阻;
开漏输出即输出高电平时无驱动能力,需加上上拉电阻才可驱动外设。


3、GPIO初始化流程
定义一个GPIO_InitTypeDef结构体变量(若定义为结构体指针变量,需自己开辟内存空间!!!!)--->调用库函数开启GPIO外设时钟(GPIO挂在APB2总线上,因此需找到APB2上的GPIO时钟)--->初始化结构体变量(选择待控制的引脚、设置引脚模式、设置引脚速率)--->调用库函数GPIO_Init完成初始化

注:
若需同时使用多个引脚,则应直接给 GPIO_InitTypeDef.GPIO_Pin赋16进制值,确定该值的方法是写出一个16位二进制数,将待使用的引脚号对应的二进制数置1(如需使用引脚2,4,8,9;则该值为0000 0011 0001 0000B)。


二、明确硬件资源

0e3432c94c340d014c092c04bce53974.jpg

开发板附赠的LED原理图如下,是一个非常简单的电路。

如上图所示,8个LED灯的阳极已经接在了3.3V电源上,它们经过限流电阻后分别引出了8根线:LED0~7;想要某个LED亮起来,那就必须使引线输出低电平(二极管单向导电性);同时我们知道STM32上是没有这8根同名引脚的,因此我们需要查看MCU的引脚分配图,如下所示。

d76f0395886438ee65ff042211a55d95.jpg

简单明了

可以看出来,LED0~7分别连接在PC0~7上。


三、程序编写
有了以上的分析和学习,下面的内容就是水到渠成了。

1、辅助函数
GPIO初始化函数
  1. void LED_Config(void){
  2.         GPIO_InitTypeDef LED;//定义该类型结构体
  3.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能GPIOC外设时钟
  4.         LED.GPIO_Pin = 0x00ff;//选择引脚PC0~7
  5.         LED.GPIO_Mode = GPIO_Mode_Out_PP;//选择工作模式为推挽输出
  6.         LED.GPIO_Speed = GPIO_Speed_50MHz;//设置GPIO速度为50MHz
  7.         GPIO_Init(GPIOC, &LED);//调用库函数进行初始化
  8. }
复制代码

引脚选择函数
考虑到流水灯是要不断选择下一个引脚的,我觉得不如设计一个函数把选择引脚的操作封装进去(不过位操作更简洁,直接左移)。
  1. uint16_t ChoosePin(int n){
  2.         uint16_t pin;
  3.         switch(n){
  4.                         case 0:
  5.                                 pin = GPIO_Pin_0;
  6.                                 break;
  7.                         case 1:
  8.                                 pin = GPIO_Pin_1;
  9.                                 break;
  10.                         case 2:
  11.                                 pin = GPIO_Pin_2;
  12.                                 break;
  13.                         case 3:
  14.                                 pin = GPIO_Pin_3;
  15.                                 break;
  16.                         case 4:
  17.                                 pin = GPIO_Pin_4;
  18.                                 break;
  19.                         case 5:
  20.                                 pin = GPIO_Pin_5;
  21.                                 break;
  22.                         case 6:
  23.                                 pin = GPIO_Pin_6;
  24.                                 break;
  25.                         case 7:
  26.                                 pin = GPIO_Pin_7;
  27.                                 break;
  28.                 }
  29.         return pin;
  30. }
复制代码

延时函数
还没学定时器,所以就粗略延时了,调用一次大约延时1s
  1. void Delay(unsigned int time){
  2.         for(;time!=0;time--);
  3. }
复制代码

2、流水灯主函数
  1. void Run(void){
  2.         int i;
  3.         for(i=0;i<8;i++){
  4.                 GPIO_SetBits(GPIOC, 0x00ff);    //灭所有灯
  5.                 GPIO_ResetBits(GPIOC, ChoosePin(i));  //点亮指定灯
  6.                 Delay(10000000); //延时大约1s
  7.         }
  8. }
复制代码

四、结语
第一天的学习还是比较轻松的,除了时钟那一块,看的我眼都花了。一开始犯了个大错,我想着GPIO_Init既然接受指针,那我刚开始的结构体也定义为结构体指针多好,然后忘了给这个结构体指针分配内存空间,直接就用了......盯着没量灯的板子发呆,突然反应过来指针是NULL哈哈哈。
————————————————
版权声明:被大佬糊弄的只会点灯的小菜鸡
如有侵权请联系删除

收藏 评论0 发布时间:2023-3-26 17:59

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版