【STM32】引脚GPIO批量操作数组&for循环流水灯

简介: 【STM32】引脚GPIO批量操作数组&for循环流水灯

原理图

476ba07e32c7c23c8c95cb75fb6edbf7_6653395e894e4c66a9d5c20e50bfc9f9.png

LED宏定义

8个LED,管脚有些多,代码里不好修改

我们可以二次宏定义

#define LED   GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7

这样写比较麻烦,我们也可以先计算出上述数值

或运算:有一个为真,必定为真

  • 0 | 0 = 0
  • 1 | 0 = 1
  • 0 | 1 = 1
  • 1 | 1 = 1

4a9a7800a2bfca85cebab11616db4c6d_bab839ab26a14fa2af40a40882c1e367.png

十六进制的 F 表示成二进制就是1111,就是1+2+4+8

观察上图,最后一位是8421相加,倒数第二位也是8421相加

所以GPIO_Pin_0| ...... | GPIO_Pin_7 = 0x00FF

简化宏定义如下:

#define LED 0x00FF

这里的流水灯程序,用的是数组的方法,把每一个状态都写出来

用GPIO_Write函数写入对应的GPIO

GPIO_Write(LED_PORT, code[i]);

以下是ZET6开发板各个模块的代码

LED.c

1. #include "LED.h"
2. 
3. #define LED 0x00FF
4. #define LED_PORT GPIOF
5. 
6. uint8_t  code[] = {0xFE, 0xFD, 0xFB, 0xF7, 0XEF, 0XDF, 0XBF, 0X7F};
7. 
8. void LED_Init(void)
9. {
10. 
11.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
12. 
13.   GPIO_InitTypeDef GPIO_InitStructure;  //初始化结构体
14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
15.   GPIO_InitStructure.GPIO_Pin = LED;
16.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
17.   GPIO_Init(LED_PORT, &GPIO_InitStructure);
18. 
19.   GPIO_ResetBits(LED_PORT, LED);  //置低电平
20. }
21. 
22. void LED_Display(void)
23. {
24.   for(uint8_t i = 0; i < 8; i ++){
25.     GPIO_Write(LED_PORT, code[i]);  //直接把数组写入
26.     Delay_ms(150);
27.   }
28.   for(uint8_t i = 7; i > 0; i --) {    //反着流回来
29.     GPIO_Write(LED_PORT, code[i]);  
30.     Delay_ms(150);
31.   }
32. }
33.

LED.h

1. #ifndef __LED_H__
2. #define __LED_H__
3. 
4. #include "stm32f10x.h"                  // Device header
5. #include "Delay.h"
6. 
7. void LED_Init(void);
8. void LED_Display(void);
9. 
10. #endif
11.

main.c

1. #include "stm32f10x.h"                  // Device header
2. #include "Delay.h"
3. #include "LED.h"
4. 
5. 
6. int main(void)
7. {
8.  Delay_Init(72);
9.  LED_Init();
10. 
11.   while(1)
12.   {
13.     LED_Display();
14.   }
15. }
16. 
17. /***********************************END OF FILE***********************************/
18.

由于没有LED模块,只有散装LED灯珠,用C8T6在面包板插线更方便

流水灯接线图:

d11c9c2b720a0abf9782295cbb6b1c4b_76f3daf368f84d1da6665ebb2737c969.png

be838cf50d33ab80c79c9eebfa39c8e3_c67c560f93c24e1990ff80ed9c5db629.png

C8T6程序如下,流水灯采用for循环的写法,简洁明了!

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;        //这样也可以选择Pin0~Pin7

1. #include "stm32f10x.h"                  // Device header
2. #include "Delay.h"
3. 
4. #define LED 0x00FF
5. #define LED_PORT GPIOA
6. 
7. uint8_t  code[] = {0xFE, 0xFD, 0xFB, 0xF7, 0XEF, 0XDF, 0XBF, 0X7F};
8. 
9. int main(void)
10. {
11.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
12. 
13.   GPIO_InitTypeDef GPIO_InitStructure;  //定义结构体
14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 (高低电平都有输出能力)
15. //  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出 (低电平有输出能力)
16. //  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;   //可以用按位或操作,同时设置多个引脚
17. //  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //上一行的接续,用Pin_All,设置16个引脚,,也可以用上边那一行设置0-7引脚
18.   GPIO_InitStructure.GPIO_Pin = LED;
19.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;  
20.   //GPIOA 0号引脚 推挽输出 2MHz
21. 
22.   GPIO_Init(LED_PORT, &GPIO_InitStructure);
23. 
24. //  GPIO_ResetBits(GPIOA, GPIO_Pin_0);  //点亮一个LED
25. //  GPIO_SetBits(GPIOA, GPIO_Pin_0);    //熄灭LED
26. //  GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);//Bit_RESET清楚端口值,置低电平
27. //  GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);  //Bit_SET  设置端口值,置高电平
28. 
29.   unsigned char i =0;
30. 
31.   while(1)
32.   {
33.     //写法1(数组)
34. //    for(uint8_t i = 0; i < 8; i ++)
35. //    {
36. //      GPIO_Write(LED_PORT, code[i]);  //直接把数组写入
37. //      Delay_ms(80);
38. //    }
39. //    for(uint8_t i = 7; i > 0; i --) //反着流回来
40. //    {
41. //      GPIO_Write(LED_PORT, code[i]);  
42. //      Delay_ms(100);
43. //    }
44. 
45.     //写法2
46.     for(i=0;i<8;i++)            //用for循环 左移操作,实现循环点灯
47.     {
48.       GPIO_Write(GPIOA, ~(0x0001<<i));  //0000 0000 0000 0001  ,低电平点亮,所以取反,只点亮第一个LED
49.       Delay_ms(200);
50.     }
51.     for(i=0;i<8;i++)
52.     {
53.       GPIO_Write(GPIOA, ~(0x0080>>i));  //0000 0000 0000 0001  ,低电平点亮,所以取反,只点亮第一个LED
54.       Delay_ms(100);
55.     }
56. 
57.     //写法3,笨方法~
58. //    GPIO_Write(GPIOA, ~0x0001); //0000 0000 0000 0001  ,低电平点亮,所以取反,只点亮第一个LED
59. //    Delay_ms(500);
60. //    GPIO_Write(GPIOA, ~0x0002); //0000 0000 0000 0010
61. //    Delay_ms(500);
62. //    GPIO_Write(GPIOA, ~0x0004); //0000 0000 0000 0100
63. //    Delay_ms(500);
64. //    GPIO_Write(GPIOA, ~0x0008); //0000 0000 0000 1000
65. //    Delay_ms(500);
66. //    GPIO_Write(GPIOA, ~0x0010); //0000 0000 0001 0000
67. //    Delay_ms(500);
68. //    GPIO_Write(GPIOA, ~0x0020); //0000 0000 0010 0000
69. //    Delay_ms(500);
70. //    GPIO_Write(GPIOA, ~0x0040); //0000 0000 0100 0000
71. //    Delay_ms(500);
72. //    GPIO_Write(GPIOA, ~0x0080); //0000 0000 1000 0000
73. //    Delay_ms(500);
74. 
75.   }
76. }
77.

年前回顾一下点流水灯~


相关文章
|
3月前
|
存储
STM32F103标准外设库——GPIO 输入、输出 (五)
STM32F103标准外设库——GPIO 输入、输出 (五)
177 0
STM32F103标准外设库——GPIO 输入、输出 (五)
|
1月前
stm32f407探索者开发板(十四)——IO引脚复用和映射
stm32f407探索者开发板(十四)——IO引脚复用和映射
|
1月前
stm32f407探索者开发板(八)——按键输入实验--GPIO做输入
stm32f407探索者开发板(八)——按键输入实验--GPIO做输入
|
1月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
|
2月前
经验大分享:STM32F4寄存器初始化系列:GPIO
经验大分享:STM32F4寄存器初始化系列:GPIO
15 0
|
10月前
|
芯片
STM32速成笔记(二)—GPIO
本文介绍了STM32的GPIO的配置和使用方法,并且给出了应用实例。此外,针对使用时可能遇到的一些问题给出了解决办法。
302 0
STM32速成笔记(二)—GPIO
|
3月前
|
芯片
STM32 GPIO工作原理详解
STM32 GPIO工作原理详解
|
11月前
|
芯片
STM32F0单片机快速入门五 GPIO中断
STM32F0单片机快速入门五 GPIO中断
|
1月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
168 0
|
2月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
158 2