历史上的今天
今天是: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); } }
史海拾趣
|
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嵌入式开发 作过基于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里使用这个 ...… 查看全部问答> |
|
本帖最后由 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、合泰单片机、松翰单片机一 ...… 查看全部问答> |




