这篇文章主要介绍在
海思SS528
开发板,去操作某个 GPIO 寄存器输出高、低电平,来熄灭或点亮 LED 灯。
首先,了解一下
ARM裸机编程
,也就是在一块没有移植操作系统的ARM开发板去编程,相当于把它当成单片机去使用,很多与硬件相关的操作都需要直接读写该硬件的寄存器。
然后,了解一下点亮 LED 灯需要查阅哪些资料 :
- 海思SS528芯片手册
《22AP30 H.265编解码处理器用户指南.pdf》
;- 海思SS528芯片管脚寄存器文档
22AP30_PINOUT_CN.xlsx
;- 你的开发板原理图,需要找到 LED 灯对应的管脚。
然后,了解一下在ARM裸板点亮 LED 灯的几个步骤:
- 看原理图,找到要点亮的 LED 灯的 GPIO 管脚,并弄清楚点亮该 LED 需要高电平还是低电平;
- 使能 GPIO 管脚功能;
- 配置 GPIO 管脚为输出;
- 设置 GPIO 管脚输出高电平或低电平,熄灭或点亮 LED 灯。
从我板子的原理图中找到接在
LINK_LED1
管脚的一个 LED 灯,从原理图可以看出 LED 灯另一端是接在3V3
的电源的,所以我们操作连接 LED 灯的 GPIO 管脚为低电平
就可以点亮这个LED灯。如图所示:
注意: 要根据你自己开发板的原理图来,我这里是低电平,你的不一定是高电平。
找到 LED 灯后,只看到它接在
LINK_LED1
管脚,需要在原理图中,继续查找LINK_LED1
是接在哪个GPIO的,通过查找,发现LINK_LED1
是接在GPIO20_6
的管脚。
小结:完成上面步骤,可以确定,
GPIO20_6
管脚输出低电平就可以点亮 LED 灯,GPIO20_6
管脚输出高电平就可以熄灭 LED 灯。
使能 GPIO 管脚功能,需要查阅文档
22AP30_PINOUT_CN.xlsx
(文档路径:SS528ReleaseDoc\hardware\chip
),打开文档后,在下面选择表格管脚控制寄存器,按Ctrl+F
搜索GPIO20_6
,找到我们要配置的管脚寄存器,如下图:
根据表格信息知道,将寄存器地址为0x17c701d0寄存器的值设置为0x0
,就可以使能GPIO功能
、IO6挡位8
、关闭上拉
、关闭下拉
。用C语言来设置这个寄存器,可以粗略地用下面代码表示:
#define GPIO20_6_FUNC (*((volatile unsigned int *)0x17c701d0))
GPIO20_6_FUNC = 0x0;
GPIO 管脚要配置为输出,需要设置GPIO对应的方向寄存器
GPIO_DIR
,该寄存器是采用 基地址+偏移地址 的方式来获得的。
通过查阅芯片手册《22AP30 H.265编解码处理器用户指南.pdf》
(文档路径:SS528ReleaseDoc\hardware\chip
),得知 GPIO_20 的基地址为:0x110a_4000
:
上面分析可以粗略地用C语言来表示:
#define GPIO20_6_DIR (*((volatile unsigned int *)0x110a4400)) // 基地址0x110a4000 + 偏移地址0x400
GPIO20_6_DIR = 0x40;
GPIO管脚要输出高电平或低电平,需要配置
GPIO_DATA
寄存器,GPIO_DATA
寄存器也是采用 基地址+偏移地址 的方式来获得的。从上一小节知道,GPIO_20 的基地址为:0x110a_4000
;再查芯片手册选择偏移地址为0x3FC
;同时也可以知道,GPIO_DATA
的第6位是GPIO20_6
的输出值,1为高电平、0为低电平。
上面分析可以粗略地用C语言来表示:
#define GPIO20_6_DATA (*((volatile unsigned int *)0x110a43fc)) // 基地址0x110a4000 + 偏移地址0x3fc
GPIO20_6_DATA = 0x40; //高电平
GPIO20_6_DATA = 0x0; //低电平
// led.h
#ifndef __LED_H__
#define __LED_H__
#define GPIO20_6_FUNC (*((volatile unsigned int *)0x17c701d0))
#define GPIO20_6_DIR (*((volatile unsigned int *)0x110a4400)) // 基地址0x110a4000 + 偏移地址0x400
#define GPIO20_6_DATA (*((volatile unsigned int *)0x110a43fc)) // 基地址0x110a4000 + 偏移地址0x3fc
//将常量直接转换成指针,然后再对指针取值
#endif //__LED_H__
// led.c
#include "led.h"
void delay(unsigned int n);
void led_main(void)
{
//1.配置 GPIO20_6 管脚为 GPIO 功能
GPIO20_6_FUNC = 0x0;//(GPIO20_6_FUNC & 0xFFFF0FFF) | 0x00001000;
//2.配置 GPIO20_6 输出
GPIO20_6_DIR = 0x40;
//3.操作GPIO20_6_DATA bit为1
while(1)
{
GPIO20_6_DATA = 0x40;
delay(0x100000);
GPIO20_6_DATA = 0x0;
delay(0x100000);
}
}
void delay(unsigned int n)
{
while(n)
{
n--;
}
}
# Makefile
led:led.o
aarch64-mix210-linux-ld -nostartfiles -nostdlib -Ttext=0x42000000 -e led_main -o led led.o
aarch64-mix210-linux-objcopy -O binary led led.bin
led.o:led.c
aarch64-mix210-linux-gcc -nostdlib -c -o led.o led.c
clean:
rm -vf led.o led led.bin
如果文章有帮助的话,点赞、收藏⭐,支持一波,谢谢