[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
2017-01-09 16:16
1066 查看
原文地址:STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)作者:Nao2Mo2
控制GPIO输出点亮LED灯——直接操作存储器
一.预备知识
使用51单片机控制IO口相对来说要简单得多,最小系统搭建完毕后直接通过软件往各IO口写“1”或者写“0”即可。但使用STM32控制IO口输入输出却远没有这么容易,经过一个下午的查阅文献及探索后,略微有了头绪。
个人所使用的STM32F103VBT6有100个引脚,其中有五组GPIO(GPIOA…GPIOE),每组有16个GPIO端口(GPIOx_Pin0…GPIOx_Pin15)共80个,每个GPIO端口都有:
两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH);
两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR);
一个32位置位/复位寄存器(GPIOx_BSRR);
一个16位复位寄存器(GPIOx_BRR);
和一个32位锁定寄存器(GPIOx_LCKR)。
其中各个寄存器的作用:
每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。
输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。因此,要控制GPIOC端口,必须先使能APB2时钟。此外,STM32初始化外设第一步就是开启APB时钟。(时钟部分知识暂时知道该如此,往后再学习。)
关于GPIO各寄存器的描述:
端口配置低寄存器(GPIOx_CRL) (x=A..E):
端口配置高寄存器(GPIOx_CRH) (x=A..E):
端口输入数据寄存器(GPIOx_IDR) (x=A..E):
端口输出数据寄存器(GPIOx_ODR) (x=A..E):
端口位设置/复位寄存器(GPIOx_BSRR)
(x=A..E):
端口位复位寄存器(GPIOx_BRR) (x=A..E):
端口配置锁定寄存器(GPIOx_LCKR) (x=A..E):
当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。
每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。
RCC_APB2ENR:0x40021018
二.点亮LED灯
外部LED灯原理图:
编程思路:
1. 定义各寄存器地址
2. 使能APB2时钟
3. 配置GPIOC各端口输出模式
4. 利用BRR、BSRR、ODR寄存器点亮LED灯并循环流水灯
具体编程:
新建工程并设置好环境,添加c文件,键入如下程序:
//**********************************************
//* 通过直接操作存储器控制GPIO输出点亮LED灯 *
//* LED1=GPIOC_Pin6; *
//* LED2=GPIOC_Pin7; *
//* LED3=GPIOC_Pin8; *
//* LED4=GPIOC_Pin9; *
//* ------------------Sah_Pah----------------- *
//**********************************************
#include<stdio.h>
//定义各寄存器地址
#define GPIOC_CRL (* (volatile unsigned long *)(0x40011000))
#define GPIOC_CRH (* (volatile unsigned long *)(0x40011004))
#define GPIOC_ODR (* (volatile unsigned long *)(0x4001100C))
#define GPIOC_BSRR (* (volatile unsigned long *)(0x40011010))
#define GPIOC_BRR (* (volatile unsigned long *)(0x40011014))
#define RCC_APB2ENR (*(volatile unsigned long *)(0x40021018))
//设置GPIOC_Pin6,Pin7,Pin8,Pin9为推挽输出模式,最大速度50MHz
#define _GPIOC_CRL 0x33000000
#define _GPIOC_CRH 0x00000033
void delay(void);
void main(void)
{
volatile int i;
//使能APB2的PORTC时钟
RCC_APB2ENR |=(1<<4);
//设置GPIOC_Pin6,Pin7,Pin8,Pin9为推挽输出模式,最大速度50MHz
GPIOC_CRL = _GPIOC_CRL;
GPIOC_CRH = _GPIOC_CRH;
while(1)
{
delay();
//利用端口位复位寄存器BRR清除GPIOC各端口的ODR位为0
GPIOC_BRR=0xFFFF;
delay();
//利用端口位设置/复位寄存器BSRR将P6、P7、P8、P9口置1,点亮LED灯
GPIOC_BSRR=0x000003C0;
delay();
//重复三次,偷懒就不写循环了
GPIOC_BRR=0xFFFF;
delay();
GPIOC_BSRR=0x000003C0;
delay();
GPIOC_BRR=0xFFFF;
delay();
GPIOC_BSRR=0x000003C0;
delay();
GPIOC_BRR=0xFFFF;
//利用端口输出数据寄存器ODR进行流水灯循环
for(i=0;i<3;i++)
{
//P6脚置1
GPIOC_ODR=0x0040;
delay();
//清0
GPIOC_ODR=0x0000;
//P7脚置1
GPIOC_ODR=0x0080;
delay();
GPIOC_ODR=0x0000;
//P8脚置1
GPIOC_ODR=0x0100;
delay();
GPIOC_ODR=0x0000;
//P9脚置1
GPIOC_ODR=0x0200;
delay();
}
}
}
//定义延迟函数
void delay(void)
{
unsigned long j,n=100000;
while(n--)
{
j=12;
while(j--);
}
}
最终结果:
保存编译后,将程序烧写到开发板上,板上四个LED等闪烁三次后以流水灯形式循环三次。
三.参考文献
[1]半壶水,《STM32 菜鸟学习手册-罗嗦版》,
http://wenku.baidu.com/view/fc7c7d20ccbff121dd3683da.html, 2012-08-19.
[2]电脑圈圈.自己动手创建一个基于万利STM32板的IAR工程[EB/OL].http://blog.21ic.com/user1/2198/archives/2008/48929.html
,2008-07-02/2012-08-19.
[3]Changing.用stm32点个灯[操作寄存器+库函数][EB/OL]. http://www.ichanging.org/stm32_gpio_led.html, 2012-06-29/2012-08-19.
控制GPIO输出点亮LED灯——直接操作存储器
一.预备知识
使用51单片机控制IO口相对来说要简单得多,最小系统搭建完毕后直接通过软件往各IO口写“1”或者写“0”即可。但使用STM32控制IO口输入输出却远没有这么容易,经过一个下午的查阅文献及探索后,略微有了头绪。
个人所使用的STM32F103VBT6有100个引脚,其中有五组GPIO(GPIOA…GPIOE),每组有16个GPIO端口(GPIOx_Pin0…GPIOx_Pin15)共80个,每个GPIO端口都有:
两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH);
两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR);
一个32位置位/复位寄存器(GPIOx_BSRR);
一个16位复位寄存器(GPIOx_BRR);
和一个32位锁定寄存器(GPIOx_LCKR)。
其中各个寄存器的作用:
名称 | 寄存器 | 意义 |
端口配置寄存器 | GPIOx_CRL GPIOx_CRH | 配置GPIO工作模式 |
端口输入数据寄存器 | GPIOx_IDR | 读取GPIO输入状态 |
端口输出数据寄存器 | GPIOx_ODR | 控制GPIO输出状态 |
端口位设置/复位寄存器 | GPIOx_BSRR | 用于位操作GPIO的输出状态的:设置端口为0或1 |
端口位复位寄存器 | GPIOx_BRR | 用于位操作GPIO的输出状态的:设置端口为0 |
端口配置锁定寄存器 | GPIOx_LCKR | 端口锁定后下次系统复位之前将不能再更改端口位的配置 |
输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。因此,要控制GPIOC端口,必须先使能APB2时钟。此外,STM32初始化外设第一步就是开启APB时钟。(时钟部分知识暂时知道该如此,往后再学习。)
关于GPIO各寄存器的描述:
端口配置低寄存器(GPIOx_CRL) (x=A..E):
端口配置高寄存器(GPIOx_CRH) (x=A..E):
端口输入数据寄存器(GPIOx_IDR) (x=A..E):
端口输出数据寄存器(GPIOx_ODR) (x=A..E):
端口位设置/复位寄存器(GPIOx_BSRR)
(x=A..E):
端口位复位寄存器(GPIOx_BRR) (x=A..E):
端口配置锁定寄存器(GPIOx_LCKR) (x=A..E):
当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。
每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。
各寄存器地址:
GPIOC_CRL:0x40011000
GPIOC_CRH:0x40011004
GPIOC_ODR:0x4001100C
GPIOC_BSRR:0x40011010
GPIOC_BRR:0x40011014
RCC_APB2ENR:0x40021018
二.点亮LED灯
外部LED灯原理图:
编程思路:
1. 定义各寄存器地址
2. 使能APB2时钟
3. 配置GPIOC各端口输出模式
4. 利用BRR、BSRR、ODR寄存器点亮LED灯并循环流水灯
具体编程:
新建工程并设置好环境,添加c文件,键入如下程序:
//**********************************************
//* 通过直接操作存储器控制GPIO输出点亮LED灯 *
//* LED1=GPIOC_Pin6; *
//* LED2=GPIOC_Pin7; *
//* LED3=GPIOC_Pin8; *
//* LED4=GPIOC_Pin9; *
//* ------------------Sah_Pah----------------- *
//**********************************************
#include<stdio.h>
//定义各寄存器地址
#define GPIOC_CRL (* (volatile unsigned long *)(0x40011000))
#define GPIOC_CRH (* (volatile unsigned long *)(0x40011004))
#define GPIOC_ODR (* (volatile unsigned long *)(0x4001100C))
#define GPIOC_BSRR (* (volatile unsigned long *)(0x40011010))
#define GPIOC_BRR (* (volatile unsigned long *)(0x40011014))
#define RCC_APB2ENR (*(volatile unsigned long *)(0x40021018))
//设置GPIOC_Pin6,Pin7,Pin8,Pin9为推挽输出模式,最大速度50MHz
#define _GPIOC_CRL 0x33000000
#define _GPIOC_CRH 0x00000033
void delay(void);
void main(void)
{
volatile int i;
//使能APB2的PORTC时钟
RCC_APB2ENR |=(1<<4);
//设置GPIOC_Pin6,Pin7,Pin8,Pin9为推挽输出模式,最大速度50MHz
GPIOC_CRL = _GPIOC_CRL;
GPIOC_CRH = _GPIOC_CRH;
while(1)
{
delay();
//利用端口位复位寄存器BRR清除GPIOC各端口的ODR位为0
GPIOC_BRR=0xFFFF;
delay();
//利用端口位设置/复位寄存器BSRR将P6、P7、P8、P9口置1,点亮LED灯
GPIOC_BSRR=0x000003C0;
delay();
//重复三次,偷懒就不写循环了
GPIOC_BRR=0xFFFF;
delay();
GPIOC_BSRR=0x000003C0;
delay();
GPIOC_BRR=0xFFFF;
delay();
GPIOC_BSRR=0x000003C0;
delay();
GPIOC_BRR=0xFFFF;
//利用端口输出数据寄存器ODR进行流水灯循环
for(i=0;i<3;i++)
{
//P6脚置1
GPIOC_ODR=0x0040;
delay();
//清0
GPIOC_ODR=0x0000;
//P7脚置1
GPIOC_ODR=0x0080;
delay();
GPIOC_ODR=0x0000;
//P8脚置1
GPIOC_ODR=0x0100;
delay();
GPIOC_ODR=0x0000;
//P9脚置1
GPIOC_ODR=0x0200;
delay();
}
}
}
//定义延迟函数
void delay(void)
{
unsigned long j,n=100000;
while(n--)
{
j=12;
while(j--);
}
}
最终结果:
保存编译后,将程序烧写到开发板上,板上四个LED等闪烁三次后以流水灯形式循环三次。
三.参考文献
[1]半壶水,《STM32 菜鸟学习手册-罗嗦版》,
http://wenku.baidu.com/view/fc7c7d20ccbff121dd3683da.html, 2012-08-19.
[2]电脑圈圈.自己动手创建一个基于万利STM32板的IAR工程[EB/OL].http://blog.21ic.com/user1/2198/archives/2008/48929.html
,2008-07-02/2012-08-19.
[3]Changing.用stm32点个灯[操作寄存器+库函数][EB/OL]. http://www.ichanging.org/stm32_gpio_led.html, 2012-06-29/2012-08-19.
相关文章推荐
- STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
- (17/06/25)STM32学习->GPIO输出控制LED
- STM32学习笔记——使用函数库编程控制GPIO口输出
- 第11章 GPIO输出-使用固件库点亮LED—零死角玩转STM32-F429系列
- stm32学习笔记:新建工程流程,点亮led灯
- 【stm32】学习笔记(2)12月28号----------点亮一位LED
- STM32学习笔记-点亮第一个led
- 用C#控制TQ2440开发板上的LED小灯(C# GPIO学习笔记)
- 用C#控制TQ2440开发板上的LED小灯(C# GPIO学习笔记)
- stm32笔记:GPIO的的配置和操作(1)推挽输出方式
- 用C#控制TQ2440开发板上的LED小灯(C# GPIO学习笔记)
- AndroidThings学习笔记--gpio控制Led和Button
- GPIO输出操作—使用固件库点亮LED--- 调试总结
- 第11章 GPIO输出-使用固件库点亮LED—零死角玩转STM32-F429系列
- STM32学习笔记1:点亮第一盏LED灯
- stm32学习的日子-构建库函数雏形(第1节)—寄存器结构体定义控制点亮G0Kitv2.1 LED2和LED4
- STM32学习笔记之点亮LED灯
- STM32学习笔记1-点亮LED
- jQuery学习笔记--JqGrid相关操作 方法列表 备忘 重点讲解(超重要) (转载)
- Perl学习笔记(7) --控制结构和目标操作