最新帖子 精华区 社区服务 会员列表 统计排行
主题 : Tiny4412裸机程序之点亮LED
admin 离线
级别: 管理员
UID: 1
精华: 1
发帖: 997
金币: 526 个
银元: 488 个
铜钱: 7868 个
技术分: 601 个
在线时间: 737(时)
注册时间: 2010-04-21
最后登录: 2018-04-22
楼主  发表于: 2015-10-25   

Tiny4412裸机程序之点亮LED

管理提醒: 本帖被 admin 从 阶段1讨论区 移动到本区(2016-11-20)
我用的Tiny4412,1506版,看一下Tiny4412原理图:
[attachment=9864]
[attachment=9865]
在Tiny4412核心板上有4个可编程控制LED,我们来点亮led1, led1右边接3.3V电源,左边接GPM4_0接口,把GPM4_0设成低电平led灯亮,设成高电平led灯灭。
GPM4_0叫GPIO(通用输入输出接口)属于4412片内外设,每个片内外设都有相应的特殊功能寄存器可以控制,通过4412的启动流程可以看出,cpu上电时特殊功能寄存器被映射在(0x1000_0000~0x1400_0000)范围内,
直接读写这些寄存器地址就可以控制GPIO接口。
GIPO叫做通用输入输出接口,就是一个GPIO接口可以配置成多种用途,可以配置成输入接口,输出接口,特殊功能接口(如camera接口)。
找到4412 datasheet第6章,GPM4_0由(GPM4CON[0],GPM4DAT[0])控制,寄存器地址分别是0x1100_02E0,0x1100_02E4 。
首先把GPM4CON[0]的[3:0]位写0x1把GPM4_0配置成输出接口,再把GPM4DAT第0位写1就能输出高电平,写0就输出低电平。下面看代码怎么写。为了方便观察我们做个闪烁的效果,就是灯一闪一灭循环。make编译后生成led.bin用sd_fuse工具烧到开发板启动。
汇编可以看书 《汇编语言程序设计——基于ARM体系结构(文全刚)和ARM体系结构与编程
..text
.globl _start
_start:
 
/*
* set GPM4_0 as output
*/
ldr r0, =0x110002E0 // GPM4CON的地址是0x110002E0
ldr r1, [r0] // 先读出原值
bic r1, r1, #0xf // 清除bit[3:0]
orr r1, r1, #1 // 设置bit[3:0]为0b0001
str r1, [r0] // 写入GPM4CON


leds_loop:
/*
*set GPM4_0 as Low
*/
ldr r0, =0x110002E4 // GPM4DAT的地址是0x110002E4
ldr r1, [r0] // 读出原值
bic r1, r1, #1 // 清除bit[0]为0,led亮
str r1, [r0] // 写入GPM4_0
ldr r2,=0xffffff
bl delay

orr r1, r1, #0xf
str r1, [r0] // 写1 led灭
ldr r2,=0xffffff
bl delay

b leds_loop
halt_loop:
b halt_loop
 
delay:
sub r2,r2,#1 //sub 减法
cmp r2,#0x0 //将r0 与0比较
bne delay //b是跳 ne 是不相等 ,不相等就跳到delay
mov pc,lr //lr 里存的是调用函数时的下一条指令,让Pc指针指向lr就可以完成函数的返回

C语言实现:
//start.S
.text
.globl _start
_start:

ldr sp, =0x02027800 // 调用C函数之前必须设置栈,栈用于保存运行环境,给局部变量分配空间
                        // 参考ROM手册P14, 我们把栈指向BL2上方1K处(1K已经够用),
                        // 即:0x02020000 (iRAM基地址) + 5K(iROM代码用) + 8K(BL1用) + 16K(BL2用) + 1K(用作栈))

bl main
// 调用main函数
halt_loop:

b halt_loop

//led.c文件
//led.c文件
#define GPM4CON (*(volatile unsigned int *)0x110002E0)
#define GPM4DAT (*(volatile unsigned int *)0x110002E4)

void delay(volatile int time)
{
      for(; time > 0; time-- )
;
}


int main(void)
{

unsigned long tmp = 0;


/*
* set GPM4_0 as output
*/
 tmp = GPM4CON;
 tmp &= ~0xffff;
 tmp |= 0x1111;
 GPM4CON = tmp;

while(1){
 /* GPM4_0 output low */
 GPM4DAT &= ~0xf;     //4个灯亮
delay(9999999);
GPM4DAT |= 0xf;   // 4个灯灭
delay(9999999);
}


return 0;
 }
附件: led.zip (6 K) 下载次数:2
描述
快速回复

如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
认证码:

验证问题:
printf("%d", 13)
按"Ctrl+Enter"直接提交