S5PV210 | 裸机蜂鸣器实验
S5PV210 | 裸机蜂鸣器实验
目录
- S5PV210 | 裸机蜂鸣器实验
- 电路原理
DATASHEET
(相关寄存器设置详解)- 2.2.7 GPD0控制寄存器组
- 2.2.7.1 Port Group GPD0 Control Register (GPD0CON, R/W, Address = 0xE020_00A0)
- 2.2.7.2 Port Group GPD0 Control Register (GPD0DAT, R/W, Address = 0xE020_00A4)
- 2.2.7.3 Port Group GPD0 Control Register (GPD0PUD, R/W, Address = 0xE020_00A8)
- 2.2.7.4 Port Group GPD0 Control Register (GPD0DRV, R/W, Address = 0xE020_00AC)
- 2.2.7.5 Port Group GPD0 Control Register (GPD0CONPDN, R/W, Address = 0xE020_00B0)
- 2.2.7.6 Port Group GPD0 Control Register (GPD0PUDPDN, R/W, Address = 0xE020_00B4)
- 2.2.7 GPD0控制寄存器组
- 代码编写
-
电路原理
电路中通过一个
NPN
的三级管控制蜂鸣器的停止与蜂鸣。
GPIO
口GPD0_2
输出高电平,蜂鸣器鸣叫;反之,停止鸣叫。
-
DATASHEET
(相关寄存器设置详解)
2.2.7 GPD0控制寄存器组
GPD0
控制寄存器组包含六组控制寄存器,分别叫做:GPD0CON
,GPD0DAT
,GPD0PUD
,GPD0DRV
,GPD0CONPDN
和
GPD0PUDPDN
。
2.2.7.1 Port Group GPD0 Control Register (GPD0CON, R/W, Address = 0xE020_00A0)
2.2.7.2 Port Group GPD0 Control Register (GPD0DAT, R/W, Address = 0xE020_00A4)
2.2.7.3 Port Group GPD0 Control Register (GPD0PUD, R/W, Address = 0xE020_00A8)
2.2.7.4 Port Group GPD0 Control Register (GPD0DRV, R/W, Address = 0xE020_00AC)
2.2.7.5 Port Group GPD0 Control Register (GPD0CONPDN, R/W, Address = 0xE020_00B0)
2.2.7.6 Port Group GPD0 Control Register (GPD0PUDPDN, R/W, Address = 0xE020_00B4)
-
代码编写
-
启动代码
/**********************************************************
* > File Name: start.S
* > Author: fly
* > Create Time: 2020年07月17日 星期五 07时56分19秒
*********************************************************/
#define PS_HOLD_CONTORL 0xE010E81C
#define WTCON 0xE2700000
#define SVC_STACK 0xD0037D80
//#define CONFIG_SYS_ICACHE_OFF 1
.global _start
_start:
// 给5v电源置锁
// LDR指令:从内存中将1个32位的字读取到目标寄存器中
// STR指令:将1个32位的字数据写入到指令中指定的内存单元中
// ORR指令:逻辑或
// BIC指令:位清零
ldr r0,=PS_HOLD_CONTORL // r0 = 0xE010E81C
ldr r1,[r0] // 将r0地址处的数据读出,保存到r1中(零偏移)
orr r1,r1,#0x300 // 设置r1的第8、9位,其他位保持不变
orr r1,r1,#0x1 // 设置r1的第1位,其他位保持不变
str r1,[r0] // 将r1中的内容传输到r0中数指定的地址内存中去
// 关看门狗
ldr r0, =WTCON // r0 = 0xE2700000
mov r1, #0 // r1 = 0
str r1, [r0] // 将r1中的内容传输到r0中数指定的地址内存中去
// 开/关iCache
// MRC指令:从协处理器寄存器传数据到ARM寄存器
// MCR指令:从ARM寄存器传数据到协处理器寄存器
mrc p15, 0, r0, c1, c0, 0
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-Cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
#endif
mcr p15, 0, r0, c1, c0, 0
//设置栈,以便调用c函数
ldr sp, =SVC_STACK
bl main /* 跳转到main函数 */
b . /* 死循环 */
-
BEEP控制代码
/******************************************************
* > File Name: beep.c
* > Author: fly
* > Create Time: 2021-07-01 4/26 14:52:31 +0800
*==================================================*/
typedef struct{
unsigned int GPD0CON;
unsigned int GPD0DAT;
unsigned int GPD0PUD;
unsigned int GPD0DRV;
unsigned int GPD0CONPDN;
unsigned int GPD0PUDPDN;
}gpd0;
#define GPD0 (*(volatile gpd0*)0xE02000A0)
void delay(volatile unsigned int i)
{
while(i--);
}
void beep_init(void)
{
GPD0.GPD0CON = (GPD0.GPD0CON & ~(0xf<<8)) | (0x1<<8);
GPD0.GPD0DAT = (GPD0.GPD0DAT & ~(0x1<<2)) | (0x0<<2);
}
void beep_set(unsigned int value)
{
if (value){
GPD0.GPD0DAT = (GPD0.GPD0DAT & ~(0x1<<2)) | (0x1<<2);//ON
}else{
GPD0.GPD0DAT = (GPD0.GPD0DAT & ~(0x1<<2)) | (0x0<<2);//OFF
}
}
void tester_beep(void)
{
beep_init();
for(;;){
beep_set(1);
delay(900000);
beep_set(0);
delay(900000);
}
}
int main(int argc, char* argv[])
{
tester_beep();
return 0;
}
-
Makefile文件
# 将所有的.o文件链接成.elf文件,“-Ttext 0x0”
# 表示程序的运行地址是0x0,由于目前编写的是位置
# 无关码,可以在任一地址运行
# 将elf文件抽取为可在开发板上运行的bin文件
# 将elf文件反汇编保存在dis文件中,调试程序会用
# 添加文件头
.PHONY: all clean tools
CROSS ?= arm-linux-
NAME := BEEP
LD := $(CROSS)ld
OC := $(CROSS)objcopy
OD := $(CROSS)objdump
CC := $(CROSS)gcc
MK := ../../tools/mk_image/mkv210_image
CFLAGS := -nostdlib -Wall
all:$(NAME).bin
$(NAME).bin : start.o beep.o
$(LD) -Ttext 0x0 -o $(NAME).elf $^
$(OC) -O binary $(NAME).elf $(NAME).bin
$(OD) -D $(NAME).elf > $(NAME)_elf.dis
$(MK) $(NAME).bin
# 将当前目录下存在的汇编文件及C文件编译成.o文件
%.o : %.S
$(CC) -o $@ $< -c $(CFLAGS)
%.o : %.c
$(CC) -o $@ $< -c $(CFLAGS)
clean:
$(RM) *.o *.elf *.bin *.dis *.sd
tools:
make -C ../../tools/mk_image/