6.1 led/key/beep裸机驱动
day6.txt
汇编程序的编译:
1.arm-linux-gcc -c led.S -o led.o (只编译不链接)
2.arm-linux-ld -Ttext=0x40008000 led.o -o led (指定text从0x40008000开始链接)
3.arm-linux-objcopy -O binary led led.bin(格式转换)
==================================================================
led (例如:4个灯全亮)
Makefile
1 .PHONY:clean 2 3 CROSS_COMPILE=arm-linux- 4 #指定交叉工具链 5 TARGET=arm 6 #指定目标,都是变量定义,引用变量使用 $(变量名) 7 BIN=$(TARGET).bin 8 OBJS=./src/start.o ./src/led.o 9 CC=$(CROSS_COMPILE)gcc 10 LD=$(CROSS_COMPILE)ld 11 #字符拼接 12 OBJCOPY=$(CROSS_COMPILE)objcopy 13 #arm.bin依赖于arm,使用如下规则 14 $(BIN):$(TARGET) 15 $(OBJCOPY) -O binary $^ $@ 16 17 18 $(TARGET):$(OBJS) 19 $(LD) -Ttext=0x40008000 $^ -o $@ 20 21 22 %.S:%.c 23 $(CC) -c $< -o $@ 24 %.o:%.c 25 $(CC) -c -I./include $< -o $@ 26 27 # $<(第一个依赖) $^(所有依赖) $@(目标文件)%(通配符代表所有) 28 clean: 29 rm ./src/*.o $(TARGET) $(BIN) -f
led.h
1 #ifndef __LED_H__ 2 #define __LED_H__ 3 #define GPM4CON *((unsigned int *)0x110002e0) 4 #define GPM4DAT *((unsigned int *)0x110002e4) 5 extern int main(); 6 7 #endif
start.S
1 .align 2 2 .global _start 3 .text 4 _start: 5 b main 6 .end
led.c
1 #include <led.h> 2 int main() 3 { 4 GPM4CON = 0x1111; 5 GPM4DAT = 0x0; 6 }
===================================================================
beep (例如:喇叭间断循环响)
Makefile
1 .PHONY:clean 2 3 CROSS_COMPILE=arm-linux- 4 #指定交叉工具链 5 TARGET=arm 6 #指定目标,都是变量定义,引用变量使用 $(变量名) 7 BIN=$(TARGET).bin 8 OBJS=./src/start.o ./src/main.o ./src/beep.o 9 10 CC=$(CROSS_COMPILE)gcc 11 LD=$(CROSS_COMPILE)ld 12 #字符拼接 13 OBJCOPY=$(CROSS_COMPILE)objcopy 14 #arm.bin依赖于arm,使用如下规则 15 $(BIN):$(TARGET) 16 $(OBJCOPY) -O binary $^ $@ 17 18 19 $(TARGET):$(OBJS) 20 $(LD) -Ttext=0x40008000 $^ -o $@ 21 22 23 %.S:%.c 24 $(CC) -c $< -o $@ 25 %.o:%.c 26 $(CC) -c -I./include $< -o $@ 27 28 # $<(第一个依赖) $^(所有依赖) $@(目标文件)%(通配符代表所有) 29 clean: 30 rm ./src/*.o $(TARGET) $(BIN) -f
common.h
1 #ifndef __COMMON_H__ 2 #define __COMMON_H__ 3 typedef unsigned int u32; 4 typedef unsigned char u8; 5 typedef unsigned short u16; 6 7 8 #endif
led.h
1 #ifndef __LED_H__ 2 #define __LED_H__ 3 #define GPM4CON *((unsigned int *)0x110002e0) 4 #define GPM4DAT *((unsigned int *)0x110002e4) 5 extern int main(); 6 7 #endif
beep.h
1 #ifndef __BEEP_H__ 2 #define __BEEP_H__ 3 4 #include <common.h> 5 #define GPD0CON (*(u32 *)0x114000a0) 6 #define GPD0DAT (*(u32 *)0x114000a4) 7 8 extern void beep_off(); 9 extern void beep_on(); 10 extern void beep_init(); 11 12 #endif
start.S
1 .align 2 2 .global _start 3 .text 4 _start: 5 b main 6 .end
led.c
1 #include <led.h> 2 int led() 3 { 4 GPM4CON = 0x1111; 5 GPM4DAT = 0x0; 6 }
beep.c
1 #include <beep.h> 2 3 void beep_init() 4 { 5 GPD0CON &= ~0xf; 6 GPD0CON |= 0x1; 7 } 8 9 void beep_on() 10 { 11 GPD0DAT |= 0x1; 12 } 13 14 void beep_off() 15 { 16 GPD0DAT &= ~0x1; 17 }
main.c
1 #include <led.h> 2 #include <beep.h> 3 4 void delay(int count) 5 { 6 while(count--); 7 } 8 9 int main() 10 { 11 beep_init(); 12 while(1) { 13 beep_on(); 14 delay(0xfffff); 15 beep_off(); 16 delay(0xfffff); 17 } 18 19 return 0; 20 }
====================================================================
key (例如:按键1,喇叭响,4个灯全亮)
Makefile
1 .PHONY:clean 2 3 CROSS_COMPILE=arm-linux- 4 #指定交叉工具链 5 TARGET=arm 6 SRC=./src 7 #指定目标,都是变量定义,引用变量使用 $(变量名) 8 BIN=$(TARGET).bin 9 OBJS=$(SRC)/start.o $(SRC)/main.o $(SRC)/beep.o 10 OBJS += $(SRC)/led.o $(SRC)/key.o 11 CC=$(CROSS_COMPILE)gcc 12 LD=$(CROSS_COMPILE)ld 13 #字符拼接 14 OBJCOPY=$(CROSS_COMPILE)objcopy 15 #arm.bin依赖于arm,使用如下规则 16 $(BIN):$(TARGET) 17 $(OBJCOPY) -O binary $^ $@ 18 19 20 $(TARGET):$(OBJS) 21 $(LD) -Ttext=0x40008000 $^ -o $@ 22 23 24 %.S:%.c 25 $(CC) -c $< -o $@ 26 %.o:%.c 27 $(CC) -c -I./include $< -o $@ 28 29 # $<(第一个依赖) $^(所有依赖) $@(目标文件)%(通配符代表所有) 30 clean: 31 rm ./src/*.o $(TARGET) $(BIN) -f
common.h
1 #ifndef __COMMON_H__ 2 #define __COMMON_H__ 3 typedef unsigned int u32; 4 typedef unsigned char u8; 5 typedef unsigned short u16; 6 7 8 #endif
led.h
1 #ifndef __LED_H__ 2 #define __LED_H__ 3 #define GPM4CON *((unsigned int *)0x110002e0) 4 #define GPM4DAT *((unsigned int *)0x110002e4) 5 extern int main(); 6 7 #endif
beep.h
1 #ifndef __BEEP_H__ 2 #define __BEEP_H__ 3 4 #include <common.h> 5 #define GPD0CON (*(u32 *)0x114000a0) 6 #define GPD0DAT (*(u32 *)0x114000a4) 7 8 extern void beep_off(); 9 extern void beep_on(); 10 extern void beep_init(); 11 12 #endif
key.h
1 #ifndef __KEY_H__ 2 #define __KEY_H__ 3 #include <common.h> 4 #define GPX3CON (*(u32 *)0x11000c60) 5 #define GPX3DAT (*(u32 *)0x11000c64) 6 void key_init(); 7 8 9 10 #endif
start.S
1 .align 2 2 .global _start 3 .text 4 _start: 5 b main 6 .end
led.c
1 #include <led.h> 2 int led_init() //设置引脚为输出功能 3 { 4 GPM4CON &= ~0xffff; 5 GPM4CON |= 0x1111; 6 7 return 0; 8 } 9 10 void led_on()//引脚输出低电平 11 { 12 GPM4DAT &= ~0xf; 13 } 14 15 void led_off()//引脚输出高电平: 16 { 17 GPM4DAT |= 0xf; 18 }
beep.c
1 #include <beep.h> 2 3 void beep_init() 4 { 5 GPD0CON &= ~0xf; 6 GPD0CON |= 0x1; 7 } 8 9 void beep_on() 10 { 11 GPD0DAT |= 0x1; 12 } 13 14 void beep_off() 15 { 16 GPD0DAT &= ~0x1; 17 }
key.c
1 #include <led.h> 2 #include <key.h> 3 4 void key_init() 5 { 6 GPX3CON &= ~(0xffff<<8); 7 }
main.c
1 #include <led.h> 2 #include <beep.h> 3 #include <key.h> 4 5 6 void delay(int count) 7 { 8 while(count--); 9 } 10 11 int main() 12 { 13 beep_init(); 14 key_init(); 15 led_init(); 16 17 while(1) { 18 if(GPX3DAT&(0x1<<2)) { //判断GPX3DAT的第二位是否为1,GPX3DAT的第二位对应GPX3_2引脚捕获的电平值,1.8v为逻辑1 0v位逻辑0 19 led_off(); 20 beep_off(); 21 } 22 else { 23 led_on(); 24 beep_on(); 25 } 26 } 27 return 0; 28 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?