S5PV210 | 裸机蜂鸣器实验

S5PV210 | 裸机蜂鸣器实验


  • 电路原理

HW-BEEP

电路中通过一个NPN的三级管控制蜂鸣器的停止与蜂鸣。

GPIOGPD0_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)

GPD0CON

2.2.7.2 Port Group GPD0 Control Register (GPD0DAT, R/W, Address = 0xE020_00A4)

GPD0DAT

2.2.7.3 Port Group GPD0 Control Register (GPD0PUD, R/W, Address = 0xE020_00A8)

GPD0PUD

2.2.7.4 Port Group GPD0 Control Register (GPD0DRV, R/W, Address = 0xE020_00AC)

GPD0DRV

2.2.7.5 Port Group GPD0 Control Register (GPD0CONPDN, R/W, Address = 0xE020_00B0)

GPD0PUDPDN

2.2.7.6 Port Group GPD0 Control Register (GPD0PUDPDN, R/W, Address = 0xE020_00B4)

GPD0PUDPDN

  • 代码编写

  • 启动代码


/**********************************************************
 *   > 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/
posted @ 2023-05-11 20:20  hello,123456  阅读(91)  评论(0编辑  收藏  举报