Home » 华清嵌入式 » 嵌入式linux-ARM体系结构及接口技术,设备间通信方式,串口通信机制,串口寄存器配置,(ARM程序)编译模板(编译脚本—Makefile,汇编文件---start.S,连接文件—map.lds)

嵌入式linux-ARM体系结构及接口技术,设备间通信方式,串口通信机制,串口寄存器配置,(ARM程序)编译模板(编译脚本—Makefile,汇编文件---start.S,连接文件—map.lds)

编 辑:Y ┊ 时 间:2022年03月02日 ┊ 访问: 27 次

1,设备间 通讯实现

73067-giyjfaboajk.png

  1. 串口通信接收端通过循环检测高低电平来读取数据。若频率太高,波形就会变窄,接收端误识别几率就会增大
  2. 所以同步通信引入了时钟线。同步通信速度较异步高

2,串口 UART

2.1,串口 UART 协议

98895-s05l6nazhbr.png

2.1,UART 内部机制

49763-c6oautna0h8.png

3,例

3.1,代码—main.c

#define GPA1CON     (*(volatile unsigned int *)0x11400020)     //volatile 确保本条指令不会因编译器的优化而省略
#define ULCON2         (*(volatile unsigned int *)0x13820000)     //串口2线控:数据位,停止位,奇偶校验位
#define UCON2         (*(volatile unsigned int *)0x13820004)     //串口2读取控制:串口读的方式(如:轮询/中断等),写的方式
#define UBRDIV2     (*(volatile unsigned int *)0x13820028)     //串口2波特率设置
#define UFRACVAL2     (*(volatile unsigned int *)0x1382002c)     //串口2波特率设置
#define UTXH2         (*(volatile unsigned int *)0x13820020)     //串口2发送缓存器
#define URXH2         (*(volatile unsigned int *)0x13820024)     //串口2接受缓存器
#define UTRSTAT2     (*(volatile unsigned int *)0x13820010)     //串口2状态寄存器

#define GPA0CON     (*(volatile unsigned int *)0x11400000)     //volatile 确保本条指令不会因编译器的优化而省略
#define ULCON0         (*(volatile unsigned int *)0x13800000)     //串口0线控:数据位,停止位,奇偶校验位
#define UCON0         (*(volatile unsigned int *)0x13800004)     //串口0读取控制:串口读的方式(如:轮询/中断等),写的方式
#define UBRDIV0     (*(volatile unsigned int *)0x13800028)     //串口0波特率设置
#define UFRACVAL0     (*(volatile unsigned int *)0x1380002c)     //串口0波特率设置
#define UTXH0         (*(volatile unsigned int *)0x13800020)     //串口0发送缓存器
#define URXH0         (*(volatile unsigned int *)0x13800024)     //串口0接受缓存器
#define UTRSTAT0     (*(volatile unsigned int *)0x13800010)     //串口0状态寄存器

#define ULCON3         (*(volatile unsigned int *)0x13830000)     //串口3线控:数据位,停止位,奇偶校验位
#define UCON3         (*(volatile unsigned int *)0x13830004)     //串口3读取控制:串口读的方式(如:轮询/中断等),写的方式
#define UBRDIV3     (*(volatile unsigned int *)0x13830028)     //串口3波特率设置
#define UFRACVAL3     (*(volatile unsigned int *)0x1383002c)     //串口3波特率设置
#define UTXH3         (*(volatile unsigned int *)0x13830020)     //串口3发送缓存器
#define URXH3         (*(volatile unsigned int *)0x13830024)     //串口3接受缓存器
#define UTRSTAT3     (*(volatile unsigned int *)0x13830010)     //串口3状态寄存器

void uart_init(void)
{    
    //4.设置波特率为115200
    //For example, if the Baud rate is 115200 bps and SCLK_UART is 100 MHz,UBRDIVn and UFRACVALn are:
    //DIV_VAL = (SCLK_UART/(bps * 16)) - 1
    //DIV_VAL = (100000000/(115200 * 16)) – 1
    //= 54.253 – 1
    //= 53.253
    //UBRDIVn = 53 (integer part of DIV_VAL)
    //UFRACVALn/16 = 0.253
    //Therefore, UFRACVALn = 4

    //1.配置GPA1CON寄存器中的UART3        GPA1_4  UART_3_RXD
    //                                     GPA1_5  UART_3_TXD
    GPA1CON &= 0xff00ffff;
    GPA1CON |= 0x00220000;

    //2.配置ULCON3寄存器      串口0 8位数据位,1位停止位,无奇偶校验
    ULCON3 &= 0Xffffffc0;
    ULCON3 |= 0x00000003;

    //3.配置UCON3寄存器     通过轮询(polling)的模式读取串口数据     通过轮询(polling)的模式往串口写入数据数据
    UCON3 &= 0xfffffff0;
    UCON3 |= 0x00000005;

    //4.设置波特率为115200
    UBRDIV3 = 53;
    UFRACVAL3 = 4;


    //1.配置GPA1CON寄存器中的UART2        GPA1_0  UART_2_RXD
    //                                     GPA1_1  UART_2_TXD
    GPA1CON &= 0xffffff00;
    GPA1CON |= 0x00000022;

    //2.配置ULCON2寄存器      串口2 8位数据位,1位停止位,无奇偶校验
    ULCON2 &= 0Xffffffc0;
    ULCON2 |= 0x00000003;

    //3.配置UCON2寄存器     通过轮询(polling)的模式读取串口数据     通过轮询(polling)的模式往串口写入数据数据
    UCON2 &= 0xfffffff0;
    UCON2 |= 0x00000005;

    UBRDIV2 = 53;
    UFRACVAL2 = 4;

    
    //1.配置GPA0CON寄存器中的UART0        GPA0_0  UART_0_RXD
    //                                     GPA0_1  UART_0_TXD
    GPA0CON &= 0xffffff00;
    GPA0CON |= 0x00000022;

    //2.配置ULCON0寄存器      串口0 8位数据位,1位停止位,无奇偶校验
    ULCON0 &= 0Xffffffc0;
    ULCON0 |= 0x00000003;

    //3.配置UCON0寄存器     通过轮询(polling)的模式读取串口数据     通过轮询(polling)的模式往串口写入数据数据
    UCON0 &= 0xfffffff0;
    UCON0 |= 0x00000005;

    //4.设置波特率为115200
    UBRDIV0 = 53;
    UFRACVAL0 = 4;

}
void uart0_putc(char c)
{
    while(1)
    {
        if(UTRSTAT0 && 0X02) break;
    }

    UTXH0 = c;
}
char uart0_getc(char *c)
{
    while(1)
    {
        if(UTRSTAT0 && 0X01) break;
    }
    *c = URXH0;
    uart0_putc(*c);

    return *c;
}

void uart2_putc(char c)
{
    while(1)
    {
        if(UTRSTAT2 && 0X02) break;
    }

    UTXH2 = c;
}
void uart3_putc(char c)
{
    while(1)
    {
        if(UTRSTAT3 && 0X02) break;
    }

    UTXH3 = c;
}

int main(void) 
{
    uart_init();
    char c;

    while(1)
    {

        uart0_getc(&c);
        uart2_putc('b');
        uart3_putc('c');
        delay1s();
    }
    
    return 0;
}

3.2,编译脚本—Makefile

all:
    arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o start.o start.S
    arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o main.o main.c
    arm-none-linux-gnueabi-ld start.o main.o -Tmap.lds -o uart.elf
    arm-none-linux-gnueabi-objcopy -O binary  uart.elf uart.bin
    arm-none-linux-gnueabi-objdump -D uart.elf > uart.dis
clean:
    rm -rf *.bak start.o main.o uart.elf uart.bin uart.dis

3.3,汇编文件—start.S

    .global  delay1s 
    .text     
    .global _start
_start:
        b        reset                        @0x00
        ldr        pc,_undefined_instruction  @0x04
        ldr        pc,_software_interrupt     
        ldr        pc,_prefetch_abort
        ldr        pc,_data_abort
        ldr        pc,_not_used
        ldr        pc,_irq
        ldr        pc,_fiq

_undefined_instruction: .word  _undefined_instruction
_software_interrupt:    .word  _software_interrupt
_prefetch_abort:        .word  _prefetch_abort
_data_abort:            .word  _data_abort
_not_used:                .word  _not_used
_irq:                    .word  _irq 
_fiq:                    .word  _fiq


reset: 
    ldr    r0,=0x40008000      @设置异常向量表的起始地址为 0x40008000
    mcr    p15,0,r0,c12,c0,0        @ Vector Base Address Register

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*/

        b        main    /* 调用C文件main()函数 */

delay1s:
     ldr      r4,=0x1ffffff   
delay1s_loop:
     sub    r4,r4,#1
     cmp   r4,#0         
     bne    delay1s_loop
     mov   pc,lr    


    .align    4

    /****  swi_interrupt handler  ****/

stacktop:    .word         stack+4*512

.data

stack:    
  .space  4*512
.end

3.4,连接文件—map.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*   指定输出的文件格式     */
OUTPUT_ARCH(arm)         /*     生成文件支持arm系列的CPU     */
ENTRY(_start)             /*  连接后的第一条指令所在的地址是_start  */
SECTIONS                 /*  目标文件的摆放            */
{
    . = 0x40008000;      /*  指定链接的起始地址       */
    . = ALIGN(4);        /*  指令的对齐                 */
    .text      :          /*  代码段的开始             */
    {
        start.o(.text)     /*     start.o文件放在开始的位置   */
        *(.text)        /*     其他目标文件自动分配位置    */
    }
    . = ALIGN(4);          /*     代码的对齐*/
    .data : 
    { *(.data) }
    . = ALIGN(4);
    .bss :
     { *(.bss) }
}



Copyright © 2026 Y 版权所有.网站运行:13年238天21小时27分