灵动微电子ARM Cortex M0 MM32F0010 GPIO的配置 

目录:

1、前言

2、学习方法简要说明

3、要点提示

4、注意事项

5、MM32F0010系统时钟的配置

6、MM32F0010的GPIO初始化配置 

7、MM32F0010 GPIOA PA7驱动LED灯每隔一秒翻转一次

1、前言:

  MM32F0010是基于ARM Cortex M0核的32位微控制器(MCU)即32位的单片机,使用库函数开发,每一个片上外设都有与之对应的外设xx.c和xx.h库函数,例如:hal_rcc.c和hal_rcc.h,hal_gpio.c和hal_gpio.h等,针对外设初的初始化工程师即可参考外设对应的库函数外xx.c和外设xx.h文件。不知道大家每接触一款新的ARM Cortex核心MCU是如何快速入门的?笔者简单说一下个人的学习方法,当笔者每接触一款不同厂家的ARM Cortex M0/M3/M4核心的MCU时,笔者是这样快速入门的:

2、学习方法简要说明:

(1)访问厂家的官网下载ARM Cortex 对应型号和版本的MCU的DS数据手册(手册一般描述了GPIO管脚定义、GPIO管脚复用功能、封装信息、电气特性、各个外设工作的电气特性、工作环境等);

下载ARM Cortex对应型号和版本的MCU的UM用户手册(手册一般对MCU的每一个片上外设资源的各个寄存器及其位定义做了详细的描述)单片机工程师做编程开发时可以参考以上DS和UM手册,有些厂家还会提供该MCU的库函数编程手册指南等。

(2)从官网下载对应MCU型号版本的Demo例程,Demo例程一般包含ARM Cortex 核心片上外设各个外设的Demo的使用(包含各个外设功能的初始化和实现简单功能的演示实例具有一定参考价值)。

(3)从官网下载对应MCU型号版本系列的Pack包,简单的说Pack包里面定义了该系列MCU型号的选型,开发时需要选择对应MCU型号,笔者习惯使用MDK Keil开发环境,MDK Keil从5.0以上版本官方就对各个厂家MCU设备型号使用Pack包形式进行管理。

(4)关于程序的仿真烧录工具,笔者习惯使用JLINK进行ARM Cotex核MCU的仿真烧录,很多同行会问各个厂家的ARM Cotex核心的MCU都支持JLINK仿真烧录程序吗?答案是肯定的,为什么呢?ARM Cortex核已经形成了一个世界标准,并且研发JLINK的SEGGER公司和ARM以及各个芯片半导体公司都有深入合作已经形成了标准的生态链,各家芯片设计公司只要设计的芯片使用的是ARM Cortex核都可以支持JLINK仿真烧录的,笔者目前学习单片机开发使用的JLINK版本为V9版本,因此大家可以放心的使用JLINK作为开发仿真、调试和烧录程序。

(5)搭建开发环境,笔者针对ARM Cotex核的MCU单片机开发习惯使用MDK Keil开发环境,安装好MDK Keil开发环境,然后安装厂家提供的Pack包,再配置一个JLINK v9仿真调试器,加上官网下载的DS和UM手册或编程手册以及官网的MCU例程就可以开始进入入门开发了。

3、要点提示:

  在实现本实例之前呢,笔者已经搭建好了基于MDK Keil5.30的MM32F0010的开发环境,请事先搭建好MDK Keil开发环境。

4、注意事项:

  基于ARM Cotex M0/M3/M4等核心的MCU都有共同的特点即:系统(System Clock)时钟和片上外设时钟是独立配置的,系统时钟配置一般在加载MCU启动文件xx.s时调用了System_xx.c文件里的SystemInit函数,用户只需在System_xx.c文件里开启对应的宏定义时钟项即可,然后就是外设时钟了,ARM Cortex 核的MCU每一个片上外设都有各自独立的时钟配置使能位,因此用户对片上外初始化外设时,首先要开启使能外设时钟,再配置外设的其它成员参数(注:基于ARM Cortex核心的MCU各个外设参数的配置都是以结构体成员、联合体、枚举参数进行配置的因此用户要有一定的C语言基础)。

5、MM32F0010系统时钟的配置:

  参考官网下载的LED工程例程,Keil左边栏Project工程目录下单击MM32Series前面的加号“+”展开工程目录,单击"STARTUP"文件夹的“+”号展开文件目录,可以看到2个文件分别是system_mm32f0010.c配置时钟文件和startup_mm32f0010_keil.s启动文件(基于keil环境)如下图1所示:用户在system_mm32f0010.c里开启宏定义时钟,即去掉双斜杠用于配置系统时钟(如果需要使用外部HSE 8M时钟去掉“#define SYSCLK_FREQ_HSE    HSE_VALUE”前面的双斜杠,使用双斜杆屏蔽“#define SYSCLK_HSI_48MHz  48000000”即可)

图1

#define SYSCLK_HSI_48MHz  48000000时钟即可,程序运行启动文件时会对该宏定义的系统时钟进行初始化

6、MM32F0010的GPIO初始化配置:

(1)不知道大家平时编写外设驱动代码是什么样的风格特点,笔者有自己的一套编程风格,本实例是使用MM32F0010的GPIO外设驱动LED灯,低电平点亮,那么笔者针对该驱动会编写一个外设xx.c和外设xx.h文件即:bsp_gpio_led.c和bsp_gpio_led.h文件。

(2)关于配置MM32F0010 GPIO管脚的工作模式有以下8种模式:

输入模式:

<1>GPIO_Mode_AIN      模拟输入输入模拟量

<2>GPIO_Mode_FLOATING     浮空输入(一般会在外部接上拉或下拉电阻,否则电平状态为不确定状态)

<3>GPIO_Mode_IPD      带内部下拉电阻的下拉输入(弱下拉)

<4>GPIO_Mode_IPU      带内部上拉电阻的上拉输入(弱上拉)

输出模式:

<5>GPIO_Mode_Out_OD      开漏输出(如需启动外部电路需外接适当的上拉或下拉电阻)

<6>GPIO_Mode_Out_PP       推挽输出(最大灌电流20mA)

<7>GPIO_Mode_AF_OD   复用功能开漏输出(如果IO有配置成复用功能需在外部接适当的上拉或下拉电阻)

<8>GPIO_Mode_AF_PP      复用功能推挽输出(如果IO有配置成复用功能,可使用该模式,最大灌电流20mA)

(3)配置MM32F0010初始化GPIO的步骤:

1>使能GPIOx端口时钟(这点很重要不要忘了)

2>定义GPIO结构体变量引用GPIO结构体成员使用库函数自定义值初始化GPIO 结构体成员参数

3>配置GPIO结构体成员管脚定义;

4>配置GPIO结构体成员管脚的输出速度;

5>配置GPIO结构体成员管脚为输入或输出模式;

6>根据给定的结构体成员变量配置的参数初始化GPIOx端口和引脚参数;

(4)本实例是要用到普通的GPIO功能输出电平驱动LED1,因此无需复用IO,直接配置为推挽输出即可。在bsp_gpio_led.c文件里编辑MM32F0010的GPIO外设驱动LED灯的初始化代码函数如下所示:

 1 #include "bsp_gpio_led.h"
2
3 /**
4 ***********************************************************************************************************************
5 *@函数名称:void Bsp_LED_Init(void)
6 *@功能描述:LED Init
7 *@输入参数:None
8 *@返回参数:None
9 ***********************************************************************************************************************
10 */
11 void Bsp_LED_Init(void)
12 {
13 //定义GPIO 初始化结构体成员变量
14 GPIO_InitTypeDef GPIO_InitStructure;
15 //使能GPIO外设GPIOA端口时钟
16 RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
17 //使用库函数自定义值初始化GPIO 结构体成员参数
18 GPIO_StructInit(&GPIO_InitStructure);
19 //GPIOA PA7管脚配置
20 GPIO_InitStructure.GPIO_Pin = LED1_PIN;
21 //GPIOA PA7输出速度
22 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
23 //GPIOA PA7推挽输出
24 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
25 //根据以上配置的的参数初始化GPIOA PA7成员参数
26 GPIO_Init(LED1_PORT, &GPIO_InitStructure);
27
28 //初始化熄灭LED1
29 LED1_OFF();
30 }

(5)在bsp_gpio_led.h文件里编辑MM32F0010的GPIO外设驱动LED灯的头文件代码如下所示,编辑头文件宏定义的好处是方便代码维护,当需要更换IO只需修改宏定义即可;

 1 #ifndef __BSP_GPIO_LED_H__
2 #define __BSP_GPIO_LED_H__
3
4 #include "mm32_device.h"
5 #include "hal_conf.h"
6
7 //GPIOA LED1端口宏定义
8 #define LED1_PORT GPIOA
9 //GPIOA LED1管脚宏定义
10 #define LED1_PIN GPIO_Pin_7
11
12 //GPIOA PA7输出低电平 LED1 ON
13 #define LED1_ON() GPIO_ResetBits(LED1_PORT,LED1_PIN)
14 //GPIOA PA7输出高电平 LED1 OFF
15 #define LED1_OFF() GPIO_SetBits(LED1_PORT,LED1_PIN)
16 //根据读取的GPIOA PA7电平状态,按当前状态翻转
17 #define LED1_TOGGLE() (GPIO_ReadOutputDataBit(LED1_PORT,LED1_PIN))?(GPIO_ResetBits(LED1_PORT,LED1_PIN)):(GPIO_SetBits(LED1_PORT,LED1_PIN))
18 void Bsp_LED_Init(void);
19 #endif

7、MM32F0010 GPIOA PA7驱动LED灯每隔一秒翻转一次:

(1)在main.c文件里包含bsp_gpio_led.h头文件,然后包含官方写好的“delay.h”头文件,调用bsp_gpio_led.h头文件里声明的void Bsp_LED_Init(void)函数初始化GPIOA PA7端口引脚,初始化为驱动LED1,main函数初始化时同时也调用“delay.h”头文件声明的SysTick函数初始化即void DELAY_Init(void);最后在while(1)主循环里调用bsp_gpio_led.h头文件里宏定义的LED1状态翻转代码并调用“delay.h”头文件声明的SysTick毫秒级别延时函数,实现LED1每隔一秒LED1灯状态翻转一次,以此循环,main函数代码如下所示:

 1 #include "delay.h"
2 #include "bsp_gpio_led.h"
3
4 /**
5 ***********************************************************************************************************************
6 *@函数名称:int main(void)
7 *@功能描述:main函数,主函数入口代码在这里开始执行
8 *@输入参数:None
9 *@返回参数:int:0(和编译器有关)
10 ***********************************************************************************************************************
11 */
12 int main(void)
13 {
14 //SysTick Init
15 DELAY_Init();
16 //LED Init
17 Bsp_LED_Init();
18
19 while(1)
20 {
21 //LED1 Toggle
22 LED1_TOGGLE();
23 //Delay 1000ms
24 DELAY_Ms(1000);
25 }
26 }

(2)在MDK Keil IDE集成开发环境中编译代码,GPIOA PA7硬件连接LED1,可用MM32F0010开发板或核心板(PA7连接到LED负极)或用户自己设计的板子即可,MCU支持DC2~5.5V宽电压供电,一般选择VDD 3.3V或VDD5.0V给MCU供电,本实例使用VDD3.3V给MCU供电,最后使用JLINK v9把编译好的代码烧录到板子上,可看到板子实物LED1灯每隔1000ms即1s状态翻转一次,看到LED1周期2s点亮和熄灭一次,以此循环。

结束语:

(1)有些读者可能会问我怎么知道GPIOA PA7是怎么初始化的呢?问的好,其实在博客开篇笔者已经提到关于ARM Cortex 核的MCU每一个片上外设都有与之对应的外设xx.c和xx.h库函数,例如:hal_rcc.c和hal_rcc.h,hal_gpio.c和hal_gpio.h等;

(2)头文件一般声明了可供main函数初始化调用的外设初始化函数以及参数,以及外设结构体成员,外设枚举参数等,C文件一般描述了使用该外设的功能配置可供初始化的函数;

(3)比如hal_rcc.c描述了系统时钟和总线时钟以及各个外设时钟的配置,hal_rcc.h描述了可被主函数调用的外设初始化的时钟参数等,hal_gpio.c和hal_gpio.h描述了GPIO口初始化函数,各端口、管脚宏定义,通过GPIO结构体成员、GPIO的枚举参数,以及有些以函数声明的形式给出,这样我们使用每个外设时一方面可参考官网例程,另一方面参考库函数外设的xx.c和外设xx.h文件结合UM手册寄存器的描述以及DS手册IO口复用,即可去初始化每一个需要使用的外设,因此掌握良好的方法规律对MCU外设底层初始化配置非常重要,尤其是在没有专门的库函数编程手册的情况下,该方法是最优的方法之一。

  

灵动微电子ARM Cortex M0 MM32F0010 GPIO 的配置驱动LED灯的更多相关文章

  1. 灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据

    灵动微电子ARM Cortex M0 MM32F0010 UART1和UART2中断接收数据 目录: 1.MM32F0010UART简介 2.MM32F0010UART特性 3.MM32F0010使用 ...

  2. 灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置

    灵动微电子ARM Cortex M0 MM32F0010 Timer定时器中断定时功能的配置 目录: 1.Timer1高级定时器Timer3通用定时器Timer14基本定时器简介 2.Timer1高级 ...

  3. stm32开发笔记(三):stm32系列的GPIO基本功能之输出驱动LED灯、输入按键KEY以及Demo

    前言   stm32系列是最常用的单片机之一,不同的版本对应除了引脚.外设.频率.容量等'不同之外,其开发的方法是一样的.  本章讲解使用GPIO引脚功能驱动LED灯和接收Key按钮输入.   STM ...

  4. MM32F0020 GPIO驱动LED灯(MM32F0020 GPIO Toggle)

    目录: 1.MM32F0020简介 2.MM32F0020系统时钟配置 3.MM32F0020的GPIO外设配置及其初始化 4.使用官网的Systick定时器做延时 5.MM32F0020 GPIO驱 ...

  5. MM32F0140 GPIO驱动LED灯(MM32F0140 GPIO)

    目录: 1.MM32F0140简介 2.MM32F0140系统时钟配置 3.MM32F0140的GPIO外设配置及其初始化 4.使用官网的Systick定时器做延时 5.MM32F0140 GPIO驱 ...

  6. ARM Cortex M3系列GPIO口介绍(工作方式探讨)

    一.Cortex M3的GPIO口特性    在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图     从图中可以看出 ...

  7. Beaglebone Black–GPIO 高低电平控制 LED 灯

    上一篇,运用 Linux 的 sysfs,控制本机上的 LED 灯,usr0 至 usr3,这次用 GPIO 控制外部的电路,点亮 LED 灯. 这次的全部材料: BBB 一台 购买 BBB 自带的 ...

  8. 树莓派GPIO控制RGB彩色LED灯

    树莓派GPIO通过PWM来控制RGB彩色LED灯,可以显示任何我们想要的颜色. RGB模块简介 这个RGB彩色LED里其实有3个灯,分别是红灯.绿灯和蓝灯.控制这三个灯分别发出不同强度的光,混合起来就 ...

  9. ARM Cortex M0 程序映像和启动流程

随机推荐

  1. Magicodes.IE.ASPNETCore之多样化接口使用

    1.安装包 Install-Package Magicodes.IE.AspNetCore 2.开始配置 在Startup.cs的Configure()方法中,在UseRouting()中间件之后,注 ...

  2. SQL Server 审计(Audit)

    审计(Audit)用于追踪和记录SQL Server实例,或者单个数据库中发生的事件(Event),审计运作的机制是通过捕获事件(Event),把事件包含的信息写入到事件日志(Event Log)或审 ...

  3. 【CPU100%排查】CPU100%问题排查方案

    1.使用top -c 查看CPU 占用情况 ,按P(大写)可以倒序查看占CPU占用率  2.找到占用率高的进程以后,再定位到具体线程 比如 此时进程ID 14724 CPU占用高,进一步使用top - ...

  4. C/C++ 手工实现IAT导入表注入劫持

    DLL注入有多种方式,今天介绍的这一种注入方式是通过修改导入表,增加一项导入DLL以及导入函数,我们知道当程序在被运行起来之前,其导入表中的导入DLL与导入函数会被递归读取加载到目标空间中,我们向导入 ...

  5. Python中sys模块的使用

    目录 sys模块 sys.argv() sys.exit(0) sys.path sys.modules sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的 ...

  6. IDS入侵检测系统

    目录 IDS入侵检测系统 入侵检测系统的作用 入侵检测系统功能 入侵检测系统的分类 入侵检测系统的架构 入侵检测工作过程 数据检测技术 误用检测 异常检测 IDS的部署 基于网络的IDS 基于主机的I ...

  7. Sublime text3 的破解

    下载sublimeText3的安装包并安装(已经安装的可以忽略) 在hosts文件中添加:127.0.0.1 license.sublimehq.com(hosts文件地址:C:\Windows\Sy ...

  8. 如何在centos上配置802.1Q VLAN标记,linux单网卡多vlan多网段Ip配置案例

    介绍 VLAN使将大型网络分成较小且易于管理的网络成为可能.802.1Q是所有供应商都在其网络设备中实施的标准.某些交换机能够将多个VLAN分配给单个网络端口.使用此功能,您可以将多个VLAN分配给单 ...

  9. 进程间IPC通信-stop waiting for thing to happen,go out and make them happen!!!

    进程间通信: System V IPC对象: ipcs -q:查看消息队列   ipcs -m:查看共享内存 ipcs -s:查看信号灯集 ipcrm -q:删除消息队列   ipcrm -m:删除共 ...

  10. 5分钟让你理解K8S必备架构概念,以及网络模型(中)

    写在前面 在这用XMind画了一张导图记录Redis的学习笔记和一些面试解析(源文件对部分节点有详细备注和参考资料,欢迎关注我的公众号:阿风的架构笔记 后台发送[导图]拿下载链接, 已经完善更新): ...