神灯亮起来

过去有个“傻瓜相机”,现在的软件开发也是越来越傻瓜化,在一个没有各种库,没有各种GUI的乌起码黑的世界里,LED神灯犹如"希望",值得我们去膜拜。

一个6410的例子,现在看来有点过时。

 

汇编语言 + C语言混编

一、汇编代码部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.globl _start
.globl delay
_start:
 
   /* 硬件相关设置 */
    ldr r0, =0x70000000
    orr r0, r0, #0x13
    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)
     
     /* 关闭看门狗 */
    ldr r0, =0x7E004000
    mov r1, #0
    str r1, [r0]
 
    /* 设置栈 */
    ldr sp, =8*1024  //6410's cpu上的8K
    mov r0, #2
    mov r1, #8
    bl led_ctl     //asm->c
halt:
    b halt 
 
delay:
delay_loop:    
    cmp r0, #0
    sub r0, r0, #1
    bne delay_loop
    mov pc, lr

  

二、高级语言部分

汇编调用c 函数,同时给c传递参数,也就是参数寄存器赋值,(r0,r1)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void delay(int count);
 
 
int led_ctr(int a, int b)
{
    int i = 0;
    int k = a + b;  //传进来2和8,那么k = 10
    volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008800;
    volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008808;
     
    /* gpm 0,1,2,3设为输出引脚 */
    *gpmcon = 0x11110000;
     
 
     
    while (k--)     /*循环10次,灯闪烁10次*/
    {
        *gpmdat = i;
        i += 16;
        if (i == 240)
          i = 16;
        delay(5000000);  //c->asm
    }
 
    return 0;
}

这里c函数又调用汇编,而r0自然等于5000000。

没有定时器,用循环实现延时。

  

然后将程序编译成.bin烧入内存一个地址,比如0c000000,然后go 0c000000。

哈哈,神灯就这么闪了十下,asm->c 的参数传对了。但延时比较短,因为是汇编的缘故,灯闪烁的较快,若用c实现delay,灯会慢许多。

一直以来,将心思放在内核代码,偶然发现,仔细研究下arm五花八门的控制器,也是一种乐趣,毕竟软件的基础是硬件,硬件的大脑就是这么个arm,若能充分了解arm寄存器的控制,对内核的理解才会突破瓶颈,柳暗花明。

 

End.

posted @   郝壹贰叁  阅读(519)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示