嵌入式-ARM(裸板开发)-3-UART驱动开发

一、UART(串行通信)驱动编程

1.基本概念

通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种串行异步收发协议,应用十分广泛。UART工作原理是将数据的二进制位一位一位的进行传输。在UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率和一些数据位

2.串行通信按传输方向来定义的传输方式:单工/半双工/全双工

3.串行接口标准

       RS232

          电气特性 (EIA(RS232)电平)

              逻辑0  +3~+15v

              逻辑1  -3~-15v

          机械特性

              传输距离 <10m 

              只能做1对1通信

       RS485:工业现场

          传输时使用差分信号

          传输距离可以超过1000m

          可以做1对多通信

     TTL电平(用于计算机内部)

       逻辑0: 低电平 <0.7v

       逻辑1: 高电平 >2.4v

4.数据传输协议

       空闲状态为高电平

       发送时首先是一个起始位(一个周期的低电平)

       发送数据时从LSB(最低值的比特位)开始发送

       每帧中数据位的个数5~8bit (变化)

       发送可能存在的1bit奇偶校验位 (变化)    

       发送1~2bit的停止位(高电平)(变化)

       波特率: bps(bit per second)(变化)

具体操作流程:

1、电路原理图     (为找到UART对应的管脚)

   PC_TXD1 <------ UARTTXD0<------GPIOD18

   PC_RXD1 <------ UARTRXD0<------GPIOD14

运行在ARM中的程序,控制UART控制器,再由UART控制器去控制收发数据的管脚,形成UART通信相关的时序,从而简化uart驱动编程

2、cpu datasheet关于 uart 相关内容

      GPIOD18, 功能1

      GPIOD14, 功能1  

以上数据均由查找手册后得知,如下:

 GPIODALTFN0 0XC001D020

      [29:28]   01, 将GPIOD14管脚设置为功能1

   GPIODALTFN1 0XC001D024

      [5:4]     01, 将GPIOD18管脚配置为功能1      

以上数据均由查找手册后得知,如下:

S5P6818 提供 6 个独立的通用异步收发器( UART),(即会拥有6个独立的UART控制器) 每个 UART 能运行于中断或 DMA 模式,即 UART 可以发出中断或 DMA 请求以便在 CPU UART 间传输数据。可支持高达4Mbps 的传输速率。

CPU感知外接硬件状态变化的方式:

       1)中断

       2)轮询

       3)DMA  (directly memory access直接存储器访问)

根据管脚的使用情况,底板上的 COM 座对应的是 UART0

配置:8n1 115200 non-fifo polling

ULCON0 0xc00a1000

      [1:0]  11, 8bit数据宽

      [2]    0,  1bit停止位

      [5:3]  000, 无校验

      [6]    0,  正常模式

UCON0  0xc00a1004

      [1:0] 01, 接收数据时采用轮询模式接收

      [3:2] 01, 发送数据时采用轮询模式发送

      [4]=0 , 正常发送数据

      [5]   0,  正常模式

 UTRSTAT0 0XC00A1010

      [0]   0/1  接收缓冲区空/非空

      [1]   0/1  发送缓存区非空/空

   UTXH0    0xc00a1020

      [7:0] 将要发送的字节数据写入其中

   URXH0    0xc00a1024

      [7:0] 读取接收到的数据

 

 获取 UART 输入的时钟源信息:

 UART0CLKENB  0XC00A9000

         [2]  0/1 禁止/使能时钟

      UART0CLKGEN0L 0XC00A9004

         [4:2] 001, 选择PLL1作为UART的时钟源      PLL1=800MHz

         [12:5] 时钟分频系数   取值为15    分频后 800M/(15+1) = 50MHz

配置串口波特率:(有公式,直接套)

波特率分频寄存器UBRDIV,UFRACVAL:

UBRDIV0  0XC00A1028

           26

UFRACVAL0 0XC00A102C

           2   //0.13*16  

配置串口波特率公式::

3、编码      

main.c


#include "uart.h"

int main(void)
{
    /*8n1 115200 polling non-fifo*/
    uart_init();

    while(1)
    {
        uart_puts("\nhello esd1909");
    }

    return 0;
}

uart.h

#ifndef __UART_H__
#define __UART_H__

extern void uart_init(void);
extern void uart_puts(char *);

#endif

uart.c 


#define UART0CLKENB         *((volatile unsigned int *)0xC00A9000)
#define UART0CLKGEN0L       *((volatile unsigned int *)0xC00A9004)

#define GPIODALTFN0         *((volatile unsigned int *)0xC001D020)
#define GPIODALTFN1         *((volatile unsigned int *)0xC001D024)

#define ULCON0              *((volatile unsigned int *)0xC00A1000)
#define UCON0               *((volatile unsigned int *)0xC00A1004)
#define UTRSTAT0            *((volatile unsigned int *)0xC00A1010)
#define UTXH0               *((volatile unsigned int *)0xC00A1020)
#define URXH0               *((volatile unsigned int *)0xC00A1024)
#define UBRDIV0             *((volatile unsigned int *)0xC00A1028)
#define UFRACVAL0           *((volatile unsigned int *)0xC00A102C)

void uart_init(void)
{
    /*禁止CLK*/
    UART0CLKENB &= ~(1<<2);
    /*配置管脚功能*/
    GPIODALTFN0 &= ~(3<<28);
    GPIODALTFN0 |= (1<<28);
    GPIODALTFN1 &= ~(3<<4);
    GPIODALTFN1 |= (1<<4);

    /*时钟源选择PLL1 800MHz*/
    UART0CLKGEN0L &= ~(7<<2);
    UART0CLKGEN0L |= (1<<2);
    /*第一次分频  800/(15+1)=50MHz*/
    UART0CLKGEN0L &= ~(0xff<<5);
    UART0CLKGEN0L |= (15<<5);

    /*8N1*/
    ULCON0 = 0x03;
    /*polling*/
    UCON0  = 0x05;
    /*根据50MHz时钟源 115200bps 进行第二次分频 */
    UBRDIV0 = 26;
    UFRACVAL0 = 2;

    /*使能CLK*/
    UART0CLKENB |= (1<<2);
}
void uart_putc(char c)
{
    /*轮询发送缓冲区是否为空
     *UTRSTAT0[1]  1,空
     * */
    while(!(UTRSTAT0 & (1<<1))) ;

    UTXH0 = c;

    if(c == '\n')
        uart_putc('\r');
}
/*abcdef*/
void uart_puts(char *str)
{
    while(*str)
    {
        uart_putc(*str);
        str++;
    }
}

程序里关于\r\n的问题:

  windows

     \r: 13 (0x0d)  去到行首

     \n: 10 (0x0a)  去到下一行

  linux: 回车换行只需要 \n

4、交叉编译

   arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib main.c -o main.o

   arm-cortex_a9-linux-gnueabi-gcc -c -nostdlib uart.c -o uart.o

   arm-cortex_a9-linux-gnueabi-ld -nostdlib -nostartfiles -Ttext=0x48000000 -emain main.o uart.o -o uart

   arm-cortex_a9-linux-gnueabi-objcopy -O binary uart uart.bin

5、下载运行         

   cp uart.bin /tftpboot/

   在开发板上执行

     tftp 48000000 uart.bin       

     go 48000000     

       

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ARM Cortex-M3是一种广泛应用于嵌入式系统的32位处理器架构。NXP LPC1768是基于ARM Cortex-M3架构的一款微控制器,具有丰富的外设和易于使用的开发环境。 在使用NXP LPC1768进行嵌入式开发实例时,我们需要以下步骤: 1. 硬件准备:准备好NXP LPC1768开发板和必要的连接线材。将开发板连接到计算机,确保正确安装驱动程序。 2. 开发环境设置:ARM Cortex-M3开发使用Keil MDK软件包,下载并安装Keil MDK开发环境。将LPC1768相关文件添加到Keil MDK,并设置正确的编译和调试选项。 3. 编写代码:使用Keil MDK的集成开发环境,我们可以编写C或汇编语言程序来控制LPC1768的外设。例如,可以通过GPIO控制LED灯,通过UART与计算机通信等。 4. 编译和下载:通过Keil MDK编译代码,生成二进制文件。然后,使用编程器将二进制文件下载到LPC1768开发板上。 5. 调试和测试:使用Keil MDK的调试功能,可以在LPC1768上单步执行程序,观察变量的值和寄存器的状态,以确保程序正确运行。 6. 扩展功能:利用LPC1768的丰富外设,我们可以实现各种功能,如通过ADC读取模拟信号,使用PWM控制电机速度等。开发者可以根据具体需求进行相应的硬件和软件开发。 总的来说,ARM Cortex-M3嵌入式开发实例基于NXP LPC1768的开发,需要进行硬件准备、开发环境设置、编写代码、编译和下载、调试和测试等步骤。通过这些步骤,我们可以实现各种功能并开发嵌入式应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值