通过汇编来点亮LED1
查看底板原理图和芯片手册 知道,LED1-4分别对应
下面是汇编语言写的点亮led4的start.S程序及说明:
//启动代码:关看门狗
.globl _start
_start:
/* 硬件相关的设置 */
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
/* 关看门狗 */
/* 往WTCON(0x7E004000)写0 */
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
/* 设置GPMCON让GPM3作为输出引脚 */
ldr r1, =0x7F008820
mov r0, #0x1000
str r0, [r1]
/* 设置GPMDAT让GPM3输出0 */
ldr r1, =0x7F008824
mov r0, #0
str r0, [r1]
halt:
b halt
将编写好的程序放到Linux下编译后将得到bin文件改为u-boot.bin放到已经制作好了的sd启动的sd卡里,设置启动方式为sd卡,系统会自动的将u-boot.bin烧写到nanflash上,也就是我们的点亮led4的程序。
通过C语言点亮led
修改start.S ,设置好栈地址为8*1024,在调用C程序,修改后的start.S
//启动代码:关看门狗
.globl _start
_start:
/* 硬件相关的设置 */
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
/* 关看门狗 */
/* 往WTCON(0x7E004000)写0 */
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
/* 设置栈 */
ldr sp, =1024*8
//调用C函数
bl main
halt:
b halt
在添加一个led子目录,在目录中新建led.c,led.h,实现led的初始化,点亮led,熄灭led,内容如下:
//led.h
#ifndef __LED_H_
#define __LED_H_
void delay(int count);
void led_all_off();
void led_all_on();
void led_on(int nLed);
void led_off(int nLed);
void led_init();
void led_test();
#endif //__LED_H_
//led.c
#include "../s3c6410.h"
void delay(int count)
{
while (count--);
}
void led_all_off()
{
GPMDAT_REG |= 0xf;
}
void led_all_on()
{
GPMDAT_REG &= ~(0xf);
}
void led_on(int nLed)
{
/* 设置GPMDAT让GPM0~3输出0 点亮led*/
if (nLed < 1 || nLed > 4)
return;
GPMDAT_REG &= ~(1<<(nLed-1));
}
void led_off(int nLed)
{
if (nLed < 1 || nLed > 4)
return;
GPMDAT_REG |= (1<<(nLed-1));
}
void led_init()
{
/* led1,led2,led3,led4==>GPM0[3:0] GPM1[7:4] GPM2[11:8] GPM3[15:12] */
/* 设置GPMCON让GPM0~3作为输出引脚 */
//0-15位清0
GPMCON_REG &= ~(0xffff);
GPMCON_REG |= 0x1111;
}
void led_test()
{
led_init();
while (1)
{
led_all_off();
led_on(1);
delay(20000);
led_all_off();
led_on(2);
delay(20000);
led_all_off();
led_on(3);
delay(20000);
led_all_off();
led_on(4);
delay(20000);
led_all_off();
led_all_on();
delay(20000);
}
}
在led上级目录添加main.c 在main函数中调用led_test()。
对应的Makefile文件
objs = start.o main.o
objs += led/led.o
all: $(objs)
arm-linux-ld -Ttext 0 $^ -o led.elf
arm-linux-objcopy -O binary -S led.elf led.bin
arm-linux-objdump -D led.elf > led.dis
%.o: %.c
arm-linux-gcc -c -o $@ $<
%.o: %.S
arm-linux-gcc -c -o $@ $<
clean:
rm *.bin *.o *.elf *.dis */*.o
通过按键点亮led,S2,S3,S4,S5对应按键1,2,3,4,S6,S7对应所有灯
查看底板原理图和芯片手册
新建key目录,在新建key.c,key.h,实现key_init和key_test.
//key.h
#ifndef __KEY_H_
#define __KEY_H_
void key_init();
void key_test();
#endif //__KEY_H_
//key.c
#include "../s3c6410.h"
#include "../led/led.h"
void key_init()
{
//S2-7对应KEYINT1-6对应引脚为GPN0-5
//配置gpn0-5为输入
GPNCON_REG &= ~(0xfff);
}
void key_test()
{
unsigned int val;
key_init();
led_init();
//读引脚的值1为松开,0位按下
while (1)
{
val = GPNDAT_REG & 0x3f;
if ( (val & (1<<0)) )
{
//S2松开,熄灭led1
led_off(1);
}
else
{
//S2按下,点亮led1
led_on(1);
}
if ( (val & (1<<1)) )
{
//S3松开,熄灭led2
led_off(2);
}
else
{
//S3按下,点亮led2
led_on(2);
}
if ( (val & (1<<2)) )
{
//S4松开,熄灭led3
led_off(3);
}
else
{
//S4按下,点亮led3
led_on(3);
}
if ( (val & (1<<3)) )
{
//S5松开,熄灭led4
led_off(4);
}
else
{
//S5按下,点亮led4
led_on(4);
}
if ( (val & (1<<4)) )
{
//S6松开,熄灭
led_all_off();
}
else
{
//S6按下,点亮
led_all_on();
}
if ( (val & (1<<5)) )
{
//S7松开,熄灭
led_all_off();
}
else
{
//S7按下,点亮
led_all_on();
}
}
}
在main函数中调用key_test。修改Makefile,添加key.c。
通过按键S7来控制蜂鸣器响
查看原理图和芯片手册
添加buzzer目录,在目录下新建buzzer.c,buzzer.h。实现buzzer_init(),buzzer_on(),buzzer_off(),函数。
#include "../s3c6410.h"
void buzzer_init()
{
//GPF15 PWM_TOUT1
//[31:30] 01
//设置GPF15为输出引脚
GPFCON_REG &= ~(3<<30);
GPFCON_REG |= (1<<30);
//GPF15输出0,不响
GPFDAT_REG &= ~(1<<15);
}
void buzzer_on()
{
//GPF15输出1,响
GPFDAT_REG |= (1<<15);
}
void buzzer_off()
{
GPFDAT_REG &= ~(1<<15);
}
修改key.c里key_test(),添加buzzer_init(),按下S7时让蜂鸣器响,松开关闭。
void key_test()
{
unsigned int val;
key_init();
led_init();
buzzer_init();
//读引脚的值1为松开,0位按下
while (1)
{
val = GPNDAT_REG & 0x3f;
//.......
if ( (val & (1<<5)) )
{
//S7松开,蜂鸣器停
buzzer_off();
}
else
{
//S7按下,蜂鸣器响
buzzer_on();
}
}
}