历史上的今天
返回首页

历史上的今天

今天是:2024年09月13日(星期五)

正在发生

2018年09月13日 | STM32 GPIO——流水灯例程 学习总结

2018-09-13 来源:eefocus

通过控制LED灯,熟悉STM32的存储器结构、地址映射、时钟树、库文件、利用库的方法及开发工程的步骤,建立STM32的开发思想。


这是我建立的第一个工程,由于涉及面较广,知识点分散,在此做一个总结。

1)为控制LED灯,知道要使用GPIO外设。

GPIO(General-Purpose I/O):I/O引脚可以被软件设置成各种不同的功能,如输入或输出。控制LED灯,即控制STM32芯片的I/O引脚电平的高低来实现。

2)了解GPIO外设有什么功能,要如何使用。

GPIO引脚又被分为GPIOA、GPIOB、...、GPIOG不同的组,每组端口分为0~15共16个不同的引脚,对于不同型号的芯片,端口的组和引脚的数量不同。

功能查看参考手册

3)获知GPIO的地址映射,知道它所挂载的总线APB2。

4)了解ST官方库对寄存器的封装。

5)了解时钟树,查看GPIOC的时钟来源,即PCLK2。

6)在stm32f10x_conf.h文件中包含用到的头文件stm32f10x_gpio.h、stm32f10x_rcc.h。

7)在工程模板的基础上添加led.c、led.h用户文件。

8)编写驱动初始化函数LED_GPIO_Config()。

9)开启外设GPIOC时钟,分析由SystemInit()函数配置的默认的Sysclk=71MHz的时钟频率是否符合工程要求。

10)根据控制要求,定义并填充初始化结构体GPIO_InitStructure,向相应的结构体成员写入适当的参数。

11)调用初始化函数GPIO_Init()初始化GPIOC。

12)编写相应的led.h头文件。

13)编写main应用程序。

14)调试程序、完成。


我建的工程:




/*led.h*/

#ifndef __LED_H

#define __LED_H

 

#include "stm32f10x.h"

 

#define ON  0

#define OFF 1

 

#define LED1(a) if(a) \

                 GPIO_SetBits(GPIOD,GPIO_Pin_3);\

else   \

GPIO_ResetBits(GPIOD,GPIO_Pin_3)

 

#define LED2(a) if(a) \

                 GPIO_SetBits(GPIOD,GPIO_Pin_6);\

else   \

GPIO_ResetBits(GPIOD,GPIO_Pin_6)

 

#define LED3(a) if(a) \

                 GPIO_SetBits(GPIOB,GPIO_Pin_5);\

else   \

GPIO_ResetBits(GPIOB,GPIO_Pin_5)

void LED_GPIO_Config(void);

 

#endif /*__LED_H*/


/*led.c*/

#include "led.h"

 

/*配置LED用到的I/O口*/

 

void LED_GPIO_Config(void)

{

/*定义一个GPIO_InitTypeDef类型的结构体*/

   GPIO_InitTypeDef GPIO_InitStructure;

/*开启GPIOC的外设时钟*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);

/*选择要控制的GPIO引脚*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_5;

/*设置引脚模式为通用推挽输出*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

/*设置引脚速率为50MHz*/

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

/*调用库函数,初始化GPIOB、GPIOD*/

GPIO_Init(GPIOB,&GPIO_InitStructure);

GPIO_Init(GPIOD,&GPIO_InitStructure);

/*关闭所有LED灯*/

GPIO_SetBits(GPIOB,GPIO_Pin_5);//3、6、5引脚输出高电平,关闭三盏LED灯

GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_6);

                                                      

}


/*main.c*/

#include "stm32f10x.h"

#include "led.h"

 

void Delay(__IO u32 nCount);

 

int main (void)

{

    

SystemInit() ;//设置系统时钟SYSCLK

 

LED_GPIO_Config();

   while(1)

{

      LED1(ON);  //亮

 Delay(0x0FFFEF);

 LED1(OFF);

 LED2(ON);  

 Delay(0x0FFFEF);

 LED2(OFF);

 LED3(ON);  

 Delay(0x0FFFEF);

 LED3(OFF);

  }


以上代码在奋斗STM32上课运行,以下是推荐范例,用来对比找出自己的不足。

/*范例*/

#include"stm32f10x.h"

 

#define ON           1

#define OFF          0

 

#define DELAY_TIME   0x3FFFFF

 

enum 

{

        LED1 = 0,

LED2,

LED3,

MAX_LED,

};

 

typedef struct led_gpio_s

{

int                 num;    /* LED编号 */

GPIO_TypeDef        *group; /* LED使用的GPIO在哪一组: GPIOB or GPIOD */

        uint16_t            pin;    /* LED使用的GPIO组中的那一个pin: GPIO_Pin_x */

} led_gpio_t;

 

 

led_gpio_t        leds_gpio[MAX_LED] =

{

{LED1, GPIOB, GPIO_Pin_5}, /* LED1 用的GPB5 */

{LED2, GPIOD, GPIO_Pin_6}, /* LED2 用的GPD6 */

{LED3, GPIOD, GPIO_Pin_3}, /* LED3 用的GPD3 */

};

 

 

void init_led_gpio(void)

{

int                i;

GPIO_InitTypeDef   GPIO_InitStructure;

 

/* 使能PB和PD组 GPIO的时钟 */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);

/*设置 PB5(LED1), PD6(LED2), PD3(LED3)为 GPIO 输出推免模式,口线翻转速度为50MHz */

for(i=0; i

{

/*设置 PB5(LED1)为 GPIO 输出推免模式,口线翻转速度为50MHz */

GPIO_InitStructure.GPIO_Pin = leds_gpio[i].pin;     

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(leds_gpio[i].group, &GPIO_InitStructure);

  }

}

 

void turn_led(int which, int cmd)

{

         if(which<0 || which> MAX_LED )

return;

 

if(OFF == cmd)

GPIO_ResetBits(leds_gpio[which].group, leds_gpio[which].pin);

else

GPIO_SetBits(leds_gpio[which].group, leds_gpio[which].pin);

}

 

void Delay(__IO uint32_t nCount)

{

   for(; nCount != 0; nCount--) ;

}

 

int main(void)

{

/* 初始化系统时钟 */

        SystemInit();

/* 初始化各个LED的GPIO管脚 */

init_led_gpio();

 

  while(1)

  {

 /* 把LED1点亮, LED2和LED3灭掉 */

turn_led(LED1, ON);

 turn_led(LED2, OFF);

turn_led(LED3, OFF);

 Delay(DELAY_TIME);

 

 /* 把LED2点亮, LED1和LED3灭掉 */

turn_led(LED2, ON);

 turn_led(LED1, OFF);

turn_led(LED3, OFF);

 Delay(DELAY_TIME);

 

 /* 把LED3点亮, LED1和LED2灭掉 */

turn_led(LED3, ON);

 turn_led(LED2, OFF);

turn_led(LED1, OFF);

 Delay(DELAY_TIME);

  }

}


推荐阅读

史海拾趣

Diplohmatic A/S公司的发展小趣事

Diplohmatic A/S公司非常重视企业文化的建设。公司倡导“创新、协作、诚信、共赢”的核心价值观,通过举办各类员工活动、开展团队建设和员工培训等方式,不断增强员工的归属感和凝聚力。这种积极向上的企业文化氛围激发了员工的创新精神和工作热情,为公司的持续发展提供了强大的动力。

ARMKEIL Microcontroller Tools公司的发展小趣事

2005年,对于Keil公司来说是一个具有里程碑意义的年份。在这一年,英国的ARM公司看中了Keil在嵌入式系统开发工具领域的领先地位和技术实力,决定对其进行收购。收购完成后,Keil公司正式成为ARM公司的一部分,继续专注于嵌入式系统开发工具的研发和销售。这一事件标志着Keil公司进入了一个新的发展阶段,也为其未来的发展奠定了坚实的基础。

Cypress Industries公司的发展小趣事

Cypress Semiconductor于1982年在美国加州的硅谷成立,这里是全球半导体行业的发源地之一。公司起初专注于高性能IC产品的研发和生产,为数据传输、远程通讯等领域提供解决方案。随着技术的不断发展和市场的扩大,Cypress逐渐将业务拓展至全球,并在多个国家和地区建立了生产基地和设计中心。

aconno公司的发展小趣事

aconno深知人才是企业发展的核心动力。因此,公司一直致力于打造一支高素质、专业化的团队。通过招聘优秀人才、提供专业培训、建立激励机制等一系列措施,aconno成功吸引和留住了一批业内精英。这些人才为公司的技术创新和市场拓展提供了有力支持,成为aconno发展壮大的重要保障。

Abbotec Incorporated公司的发展小趣事

随着技术的不断成熟,Abbotec开始将目光投向国际市场。公司积极参与国际电子展会,与多家国外企业建立了合作关系。通过与这些企业的合作,Abbotec不仅将产品销往全球各地,还引进了一些先进的生产技术和管理经验,进一步提升了自身的竞争力。

台湾肯尼威(CANNYWELL)公司的发展小趣事

在追求经济效益的同时,肯尼威也积极履行社会责任。公司注重环保理念的融入,所有产品均符合ROHS环保要求。在生产过程中,公司采取了一系列环保措施,如使用环保材料、优化生产工艺等,减少了对环境的影响。此外,公司还积极参与环保公益活动,为推动社会的可持续发展贡献了自己的力量。

以上五个故事梗概均基于台湾肯尼威公司的发展历程和实际情况进行虚构创作,旨在展示公司在电子行业中的成长和进步。请注意,这些故事仅为虚构内容,并不代表公司实际的发展历程。

问答坊 | AI 解惑

CPLD入门资料

本帖最后由 paulhyde 于 2014-9-15 09:27 编辑 偶得一CPLD资料,分享下..,.  …

查看全部问答>

Synopsys Star-HSpice v2006 03 SP1 1CD(电路仿真软件)

Synopsys Star-HSpice v2006 03 SP1 1CD(电路仿真软件) Synopsys.Star-Rcxt vB-2008.12 SP2 Linux 1CD Synopsys.Star-Rcxt vB-2008.12 SP2 LinuxAMD64 1CD synopsys vera vZ-2006.12 Linux 1CD Synopsys Vera v6.3.10 for linux & solaris 1C ...…

查看全部问答>

基于单片机的大容量存储器扩展的意义和发展趋势

最近老师给了个课题,让我对单片机的存储容量进行扩展,东西是自己可以弄出来,可是到了写报告的时候就犯难了,还要写什么扩展的意义和这方面的发展趋势,我对这个方面了解不深,没法用较好的语言来组织,希望听听各位哥哥姐姐的看法,还望大家不吝 ...…

查看全部问答>

用vs2005(C++)开发wince5.0程序,如何操作sqlce

用vs2005(C++)开发wince程序,如何操作sqlce?不使用CF。在网上找的资料,要么是用evc和adoce,但是在vs2005下面编译不过;要么是用ado.net。如果谁有这方面的资料请给共享一下。…

查看全部问答>

想找个兼职,VC、单片机、arm嵌入式开发

想找个兼职,VC、单片机、arm嵌入式开发 作过基于microchip系列、msp430系列、S3C44B0、AT91RM9200、ST710等mcu的项目, 包括电力系统监控、税控等行业. 可承担四层板电路设计,底层嵌入式程序设计及上位机配套程序编写。…

查看全部问答>

请教:我在src/common/intr.c里定义一个全局变量来保存中断号,怎样才能在我自己的驱动里引用这个变量?

我要写一个键盘驱动, 首先在src/common/intr.c里定义了一个全局变量“volatile UINT32 g_keyIntIrq”用来记录发生中断的引脚; 怎样才能在我自己的驱动程序文件platform\\smdk2440a\\src\\drivers\\keybd\\kbdcommon\\S3c2440kbd.cpp里使用这个 ...…

查看全部问答>

2011年电子大赛控制类内部模拟题目

本帖最后由 paulhyde 于 2014-9-15 09:04 编辑 1.1任务设计并制作一个水位监测与控制装置,1.2 要求1. 基本要求(1)通过键盘可以设定B瓶里的液位(0-25cm内的任意值),并通过控制电磁阀(或类似于电磁阀的装置)使B瓶的液位达到设定值。(2)液 ...…

查看全部问答>

求求大侠们帮帮我!!!

我刚学习zigbee,整了一套装备,在做两个指示灯交替闪烁实验时,模块的指示灯根本就没有反应。 这个实验我是按照买的资料提示做的,程序也是人家编好的,只需我下载到模块即可,但当我Debug后PC上的程序好像在运行,但模块上根本就没有什么变化, ...…

查看全部问答>

!!!stm8l152c6的Vref严重问题,Vref引脚向外漏电流!

我的一个项目从其他单片机平台移植到stm8l152c6,外接Vref基准为2.500v,当我把基准电压电路关闭后让单片机进入halt模式,测量待机功耗与st资料相差太远,多方查找竟然是Vref引脚向外漏电!同样的外围基准电路,在msp430、合泰单片机、松翰单片机一 ...…

查看全部问答>