【ARM】接口编程LED点亮与控制——第四篇

6d63dc5dd3994f75ae53a20768cc10f6.gif

个人主页: 长夜漫漫想学习 

本文收录专栏: ARM学习之路 

其他专栏: C语言学习之路 

学习格言:路漫漫其修远兮,吾将上下而求索

欢迎点赞、关注、收藏( •̀ ω •́ )   一起努力,一起学习!

目录

1、ARM程序启动执行

2、接口编程

2.1、点亮LED灯(实验)

2.2、硬件接口编程的流程

2.3、start.s程序里实现点亮LED灯

3、按键控制LED灯

3.1、GPX1寄存器

3.2、GPX1CON(配置寄存器)

3.3、GPX1DAT(数据寄存器)

3.4、按键控制LED程序


1、ARM程序启动执行

        对于ARM的CPU,当执行程序时有可能产生异常,此时CPU会切换到对应的工作模式,CPU会跳到异常向量表去执行(PC会赋值为对应的异常地址)。

        对于ARM程序,第一段执行代码为异常向量表,为汇编代码,进行对应的异常向量定义、初始化异常处理

2、接口编程

        通过CPU如何控制外部硬件这样的编程过程,理解为接口编程。

        GPIO:挂载在APB总线上,GPIO为通用输入输出端口。管理芯片上所有的引脚的输入与输出

        GPIO控制器作用:

        (1)输出高电平或低电平

        (2)输入高电平或低电平

2.1、点亮LED灯(实验)

2.2、硬件接口编程的流程

(1)找到对应控制设备----LED(本实验LED)

(2)进行电路分析,从外设板连接到核心板,外部硬件soc控制器连接控制。

(3)设置芯片的控制器控制引脚线的高低电平

编程流程

【ARM】接口编程LED点亮与控制——第四篇_第1张图片

查看LED电路

【ARM】接口编程LED点亮与控制——第四篇_第2张图片

查看SOC连接对应引脚

【ARM】接口编程LED点亮与控制——第四篇_第3张图片

LED3----连接芯片引脚为A3,只要芯片的控制器能够控制引脚线为高电平,LED就亮

LED3----XEINT8/KP_COLO/ALV_DBG4/GPX1_0

GPX1_0----GPIO----X1(控制器管脚组)----0(组中引脚编号为0)

GPX1控制器

【ARM】接口编程LED点亮与控制——第四篇_第4张图片

GPX1CON(控制寄存器)配置

【ARM】接口编程LED点亮与控制——第四篇_第5张图片

GPX1DAT(数据寄存器)

【ARM】接口编程LED点亮与控制——第四篇_第6张图片

        GPX1CON控制器,通过操作对应的寄存器(赋值),GPX1CON控制器就完成对应的功能在寄存器中,某几位用来表示一个编号(管脚)。

        GPX1DAT(数据寄存器):如果是输入模式,则对应位的值就表示外部引脚的电平状态(如: [5]位,表示是第5号管脚的电平),如果是输出模式,则对应位的值就表示输出到外部引脚的电平状态(如:[4]位,则表示输出到第4号管脚的电平)

  • GPX1CON:控制寄存器(控制功能) ---- 0x11000C20

  • GPX1DAT:数据寄存器 ---- 0x11000C24

  • GPXXCON:用于选择引脚功能

  • GPXXDAT:用于读/写引脚数据

  • [3:0] :0x1----output(本实验选择0x1)、0x0----input

  • [0] :GPX1控制器对应0号引脚

  • GPX1DAT:操作0号引脚电平--—[0]---0号引脚

2.3、start.s程序里实现点亮LED灯

汇编程序

_data_abort:                    .word  _data_abort
_not_used:                      .word  _not_used
_irq:                                   .word  irq_handler
_fiq:                           .word  _fiq
​
​
reset:
​
        ldr     r0,=0x40008000
        mcr     p15,0,r0,c12,c0,0               @ Vector Base Address Register
​
                mrs     r0,cpsr
                bic             r0,r0,#0x1f
                orr             r0,r0,#0xd3
                msr             cpsr,r0         @ Enable svc mode of cpu
​
        mov     r0, #0xfffffff
        mcr     p15, 0, r0, c1, c0, 2   @ Defines access permissions for each coprocessor
                                                                        @ Privileged and User mode access
​
        /*
         * Invalidate L1 I/D
         */
        mov     r0, #0                  @ set up for MCR
        mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
        mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
​
​
        @Set the FPEXC EN bit to enable the FPU:
        MOV r3, #0x40000000
        fmxr FPEXC, r3
​
        /*
         * disable MMU stuff and caches
         */
        mrc     p15, 0, r0, c1, c0, 0
        bic     r0, r0, #0x00002000     @ clear bits 13 (--V-)
        bic     r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)
        orr     r0, r0, #0x00001000     @ set bit 12 (---I) Icache
        orr     r0, r0, #0x00000002     @ set bit 1  (--A-) Align
        orr     r0, r0, #0x00000800     @ set bit 11 (Z---) BTB
        mcr     p15, 0, r0, c1, c0, 0
​
/* LED Test Code */
/*
        ldr r0, =0x114001E0
        ldr r1, [r0]
        bic r1, r1, #0xf0000
        orr r1, r1, #0x10000
        str r1, [r0]
​
        ldr r0, =0x114001E8
        ldr r1, [r0]
        bic r1, r1, #0x300
        str r1, [r0]
​
        ldr r0, =0x114001E4
        ldr r1, [r0]
        orr r1, r1, #0x10
        str r1, [r0]
*/
init_stack:
                ldr             r0,stacktop         /*get stack top pointer*/
​
        /********svc mode stack********/
                mov             sp,r0
                sub             r0,#128*4          /*512 byte  for irq mode of stack*/
        /****irq mode stack**/
                msr             cpsr,#0xd2
                mov             sp,r0
                sub             r0,#128*4          /*512 byte  for irq mode of stack*/
        /***fiq mode stack***/
                msr     cpsr,#0xd1
                mov             sp,r0
                sub             r0,#0
        /***abort mode stack***/
                msr             cpsr,#0xd7
                mov             sp,r0
                sub             r0,#0
        /***undefine mode stack***/
                msr             cpsr,#0xdb
                mov             sp,r0
                sub             r0,#0
   /*** sys mode and usr mode stack ***/
                msr             cpsr,#0x10
                mov             sp,r0             /*1024 byte  for user mode of stack*/
​
@/---------------点亮LED灯----------------/
led_on:
        @led3
        @gpx1_0 GPX1 0  
​
        ldr r0,=0x11000c20
        ldr r1,[r0] @ r1 =[3:0]的值
        bic r1,#0xf
        orr r1,#0x1
​
        str r1,[r0]
​
        @ gpxdat
        ldr r1,[r0,#4]
        orr r1,#0x1
​
        str r1,[r0,#4]
loop:
        b loop
​

3、按键控制LED灯

3.1、GPX1寄存器

注:GPX1CON-----0x0c20

        GPX1DAT-----0x0c24

3.2、GPX1CON(配置寄存器)

【ARM】接口编程LED点亮与控制——第四篇_第7张图片

注:配置input(0x0)功能

3.3、GPX1DAT(数据寄存器)

【ARM】接口编程LED点亮与控制——第四篇_第8张图片

3.4、按键控制LED程序

一个按键控制两个LED灯

void delay()//延时函数
{
        int i=0,j=0;
        for(;i<100000;i++)
        {
                for(;j<1000000;j++)
                {
                }
        }
}
int main()
{
        unsigned int * k2 = 0x11000c20;//key2
        unsigned int *p=0x11000c20;
        unsigned int *q=0x11000c40;
        *k2 = *k2 & ~(0xf<<4);//把4-7位清零,配置为输入
        *p = *p & ~(0xf) | 0x1; //output
        *q = *q & ~(0xf<<28) | (0x1<<28); //output
​
        k2 = k2+1;//把寄存器的值全部取出,查看第一位(引脚1)
        while(1)
        {
                if((*k2 & 1<<1) != 0)//k2未按下时执行
                {
                        *(p+1) = *(p+1) & ~1 | 1; //led3_on(亮)
                        delay();
                        *(p+1) = *(p+1) & ~1 ; //led3_off(灭)
                        delay();
                }
                else
                {
                        *(q+1) = *(q+1) & ~1<<7 | 1<<7; //led2_on(亮)
                        delay();
                        *(q+1) = *(q+1) & ~1<<7 ; //led2_off(灭)
                        delay();
                }
        }
        return 0;
}
使用两个按键分别控制LED灯
void delay()//延时函数
{
        int i=0,j=0;
        for(;i<100000;i++)
        {
                for(;j<1000000;j++)
                {
​
                }
        }
}
​
int main()
{
        unsigned int * k2 = 0x11000c20;//key2
        unsigned int * k3 = 0x11000c20;//key3
        unsigned int *p=0x11000c20;
        unsigned int *q=0x11000c40;
        *k2 = *k2 & ~(0xf<<4);//把4-7位清零,配置为输入
        *k3 = *k3 & ~(0xf<<8);
        *p = *p & ~(0xf) | 0x1; //output
        *q = *q & ~(0xf<<28) | (0x1<<28); //output
​
        k2 = k2+1;//把寄存器的值全部取出,查看第一位(引脚1)
        k3 = k3+1;
        while(1)
        {
                if((*k2 & 1<<1) == 0)//k2按下时执行
                {
                        *(p+1) = *(p+1) & ~1 | 1; //led3_on(亮)
                        delay();
                        *(p+1) = *(p+1) & ~1 ; //led3_off(灭)
                        delay();
                }
                if((*k3 & 1<<2) == 0)//k3按下时执行
                {
                        *(q+1) = *(q+1) & ~1<<7 | 1<<7; //led2_on(亮)
                        delay();
                        *(q+1) = *(q+1) & ~1<<7 ; //led2_off(灭)
                        delay();
                }
        }
        return 0;
}
​

✨本篇到此结束啦!欢迎点赞收藏❤关注

ade2d02221184de18874af569fd12e2c.png

 

你可能感兴趣的:(ARM学习之路,单片机,嵌入式硬件,学习,linux,ubuntu)