ARM架构与编程(基于I.MX6ULL): 串口UART编程(七)(下)

简介: ARM架构与编程(基于I.MX6ULL): 串口UART编程(七)

2.3.2.5 IMX6ULL特殊的地方


Daisy Chain select IMX6ULL还有一个“Daisy Chain select”功能,

比如下图中: A、B、C三个引脚都可以连接到Module X,它们都可以驱动Module X。

使用哪一个引脚呢?还需要设置“Daisy Chain

select”,用来选择A、B、C之一。

1670932215320.jpg

Daisy Chain Select有什么用处呢? 比如UART,它只有TXD、RXD两个引脚:RXD有外部电路输入。

能否让UART的TXD直接给RXD提供数据?可以!这就是回环,方便调试。 怎么做?

可以在外部电路把TXD接到RXD,也可以在芯片内部让RXD可以选择数据来源,如下图所示:

1670932228751.jpg

UART1_RX的输入选择

1670932236235.jpg


2.3.3 设置串口参数


2.3.3.1 设置波特率


波特率算公式:

1670932248013.jpg

上述公式中,Ref Freq为80MHZ,BUMR和UBIR在寄存器中设置。


要先设置UBIR,再设置BUMR

UBIR、BUMR中的值,是实际值减1

1670932257426.jpg


2.3.3.2 设置数据格式


比如数据位设置为8,无校验位,停止位设置为1。

1670932275318.jpg

2.3.3.3 IMX6ULL芯片要求必须设置


对于UART1_UCR3的bit2,必须设置为1,芯片要求的,没什么道理可讲:

1670932288123.jpg

2.3.4 根据状态寄存器读写数据


2.3.4.1 状态寄存器

1670932302417.jpg

1670932310323.jpg

2.3.4.2 接收数据寄存器


读这个寄存器,就可读取串口数据,如下图:

1670932323287.jpg


2.3.4.3 发送数据寄存器

1670932335847.jpg


2.3.4 寄存器地址


其他寄存器地址 用到的寄存器,从C代码定义如下:

volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA ;
volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA  ;
volatile unsigned int *IOMUXC_UART1_RX_DATA_SELECT_INPUT ;
volatile unsigned int *CCM_CSCDR1;
volatile unsigned int *CCM_CCGR5;
IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA  = (volatile unsigned int *)(0x20E0084);
IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA  = (volatile unsigned int *)(0x20E0088);
IOMUXC_UART1_RX_DATA_SELECT_INPUT  = (volatile unsigned int *)(0x20E0624);
CCM_CSCDR1 = (volatile unsigned int *)(0x020C4024);
CCM_CCGR5 = (volatile unsigned int *)(0x020C407C);


UART1寄存器


UART1基地址:0x02020000,里面的寄存器用结构体来表示比较方便:

/*根据IMX6ULL芯片手册<<55.15 UART Memory Map/Register Definition>>的3608页,定义UART的结构体,*/
typedef struct {
  volatile unsigned int  URXD;               /**< UART Receiver Register, offset: 0x0             串口接收寄存器,偏移地址0x0     */
       unsigned char RESERVED_0[60];  
  volatile unsigned int  UTXD;               /**< UART Transmitter Register, offset: 0x40          串口发送寄存器,偏移地址0x40*/
       unsigned char RESERVED_1[60];  
  volatile unsigned int  UCR1;               /**< UART Control Register 1, offset: 0x80         串口控制寄存器1,偏移地址0x80*/
  volatile unsigned int  UCR2;               /**< UART Control Register 2, offset: 0x84         串口控制寄存器2,偏移地址0x84*/
  volatile unsigned int  UCR3;               /**< UART Control Register 3, offset: 0x88            串口控制寄存器3,偏移地址0x88*/
  volatile unsigned int  UCR4;               /**< UART Control Register 4, offset: 0x8C            串口控制寄存器4,偏移地址0x8C*/
  volatile unsigned int  UFCR;               /**< UART FIFO Control Register, offset: 0x90         串口FIFO控制寄存器,偏移地址0x90*/
  volatile unsigned int  USR1;               /**< UART Status Register 1, offset: 0x94             串口状态寄存器1,偏移地址0x94*/
volatile unsigned int  USR2;               /**< UART Status Register 2, offset: 0x98             串口状态寄存器2,偏移地址0x98*/
  volatile unsigned int  UESC;               /**< UART Escape Character Register, offset: 0x9C     串口转义字符寄存器,偏移地址0x9C*/
  volatile unsigned int  UTIM;               /**< UART Escape Timer Register, offset: 0xA0         串口转义定时器寄存器 偏移地址0xA0*/
  volatile unsigned int  UBIR;               /**< UART BRM Incremental Register, offset: 0xA4      串口二进制倍率增加寄存器 偏移地址0xA4*/
  volatile unsigned int  UBMR;               /**< UART BRM Modulator Register, offset: 0xA8     串口二进制倍率调节寄存器 偏移地址0xA8*/
  volatile unsigned int  UBRC;               /**< UART Baud Rate Count Register, offset: 0xAC      串口波特率计数寄存器 偏移地址0xAC*/
  volatile unsigned int  ONEMS;              /**< UART One Millisecond Register, offset: 0xB0      串口一毫秒寄存器 偏移地址0xB0*/
  volatile unsigned int  UTS;                /**< UART Test Register, offset: 0xB4                 串口测试寄存器 偏移地址0xB4*/  
  volatile unsigned int  UMCR;               /**< UART RS-485 Mode Control Register, offset: 0xB8  串口485模式控制寄存器 偏移地址0xB8*/
} UART_Type;
UART_Type *uart1 = (UART_Type *)0x02020000;


3.IMX6ULL UART编程


/*根据IMX6ULL芯片手册<<55.15 UART Memory Map/Register Definition>>的3608页,定义UART的结构体,*/
  typedef struct {
    volatile unsigned int  URXD;               /**< UART Receiver Register, offset: 0x0             串口接收寄存器,偏移地址0x0     */
         unsigned char RESERVED_0[60];  
    volatile unsigned int  UTXD;               /**< UART Transmitter Register, offset: 0x40          串口发送寄存器,偏移地址0x40*/
         unsigned char RESERVED_1[60];  
    volatile unsigned int  UCR1;               /**< UART Control Register 1, offset: 0x80         串口控制寄存器1,偏移地址0x80*/
    volatile unsigned int  UCR2;               /**< UART Control Register 2, offset: 0x84         串口控制寄存器2,偏移地址0x84*/
    volatile unsigned int  UCR3;               /**< UART Control Register 3, offset: 0x88            串口控制寄存器3,偏移地址0x88*/
    volatile unsigned int  UCR4;               /**< UART Control Register 4, offset: 0x8C            串口控制寄存器4,偏移地址0x8C*/
    volatile unsigned int  UFCR;               /**< UART FIFO Control Register, offset: 0x90         串口FIFO控制寄存器,偏移地址0x90*/
    volatile unsigned int  USR1;               /**< UART Status Register 1, offset: 0x94             串口状态寄存器1,偏移地址0x94*/
  volatile unsigned int  USR2;               /**< UART Status Register 2, offset: 0x98             串口状态寄存器2,偏移地址0x98*/
    volatile unsigned int  UESC;               /**< UART Escape Character Register, offset: 0x9C     串口转义字符寄存器,偏移地址0x9C*/
    volatile unsigned int  UTIM;               /**< UART Escape Timer Register, offset: 0xA0         串口转义定时器寄存器 偏移地址0xA0*/
    volatile unsigned int  UBIR;               /**< UART BRM Incremental Register, offset: 0xA4      串口二进制倍率增加寄存器 偏移地址0xA4*/
    volatile unsigned int  UBMR;               /**< UART BRM Modulator Register, offset: 0xA8     串口二进制倍率调节寄存器 偏移地址0xA8*/
    volatile unsigned int  UBRC;               /**< UART Baud Rate Count Register, offset: 0xAC      串口波特率计数寄存器 偏移地址0xAC*/
    volatile unsigned int  ONEMS;              /**< UART One Millisecond Register, offset: 0xB0      串口一毫秒寄存器 偏移地址0xB0*/
    volatile unsigned int  UTS;                /**< UART Test Register, offset: 0xB4                 串口测试寄存器 偏移地址0xB4*/  
    volatile unsigned int  UMCR;               /**< UART RS-485 Mode Control Register, offset: 0xB8  串口485模式控制寄存器 偏移地址0xB8*/
  } UART_Type;
void delay(volatile int d)
{
  while(d--);
}
int main(void)
{
  uart_init();
  while(1)
  {
  c=getchar();
  putchar(c);
  putchar(c+1);
  }
  return 0;
}
void uart_init(void)
{
  volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA ;
  volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA  ;
  volatile unsigned int *IOMUXC_UART1_RX_DATA_SELECT_INPUT ;
  volatile unsigned int *CCM_CSCDR1;//设置总时钟
  volatile unsigned int *CCM_CCGR5;
  IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA  = (volatile unsigned int *)(0x20E0084);
  IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA  = (volatile unsigned int *)(0x20E0088);
  IOMUXC_UART1_RX_DATA_SELECT_INPUT  = (volatile unsigned int *)(0x20E0624);
  CCM_CSCDR1 = (volatile unsigned int *)(0x020C4024);
  CCM_CCGR5 = (volatile unsigned int *)(0x020C407C);
  UART_Type *uart1 = (UART_Type *)0x02020000;
/*设置uart总时钟
*uart_clk_root=80mhz
*/
*CCM_CSCDR1 &= ~((1<<6)|(0X3f));//阅读芯片手册,是重点。
/*给UART模块提供时钟
*UART1_CLK_ENABLE
*/
*CCM_CCGR |=(3<<24);
/*配置引脚功能*/
*IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA &= ~0xf;
*IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA &= ~0xf;
/*imu6ull特殊的设置*/
IOMUXC_UART1_RX_DATA_SELECT_INPUT |= 3;//将数据设置pc模式,而不是设置回环模式。
/*设置波特率
*115200=80M/(16*(UBMR+1)/(UBIR+1))
*UBIR=15
*115200 = 80M/(UBMR+1)
*UBMR = 80,000,000/115200=694
*真正的波特率=80000000/694=115274
*/
uart1->UBIR=15;
uart1->UBMR = 694;
/*设置数据格式*/
uart1->UCR2 = (0<<8) | (0<<6) | (1<<5) |(1<<2) |(1<<1);
/*IMX6ULL芯片要求设置*/
uart1->UCR3 |= (1<<2); 
/*使能UART*/  
uart1->UCE1 |=(1<<0);
}
int getchar(void)
{
UART_Type *uart1 =(UART_Type *)0x02020000;
while((uart1->USR2 & (1<<0))==0);
return uart1->URXD;
}
int putchar(char c)
{
UART_Type *uart1 = (UART_Type *)0x02020000
while ((uart1->USR2 & (1<<3))==0);
uart1->UTXD =c;
return c;  
}
相关文章
|
6天前
|
敏捷开发 数据可视化 物联网
云效产品使用常见问题之用ARM架构的机器意义不知道如何解决
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
编解码 算法 计算机视觉
轻松掌握FFmpeg编程:从架构到实践
轻松掌握FFmpeg编程:从架构到实践
164 1
|
1月前
|
存储 机器学习/深度学习 并行计算
阿里云服务器X86计算、Arm计算、GPU/FPGA/ASIC、高性能计算架构区别
在我们选购阿里云服务器的时候,云服务器架构有X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、高性能计算可选,有的用户并不清楚他们之间有何区别,本文主要简单介绍下不同类型的云服务器有何不同,主要特点及适用场景有哪些。
阿里云服务器X86计算、Arm计算、GPU/FPGA/ASIC、高性能计算架构区别
|
1月前
|
存储 缓存 安全
【ARM架构】ARMv8-A 系统中的安全架构概述
【ARM架构】ARMv8-A 系统中的安全架构概述
32 0
|
1月前
|
存储 机器学习/深度学习 人工智能
嵌入式中一文搞懂ARM处理器架构
嵌入式中一文搞懂ARM处理器架构
38 1
|
7天前
|
敏捷开发 监控 数据管理
构建高效微服务架构的五大关键策略
【4月更文挑战第20天】在当今软件开发领域,微服务架构已经成为一种流行的设计模式,它允许开发团队以灵活、可扩展的方式构建应用程序。本文将探讨构建高效微服务架构的五大关键策略,包括服务划分、通信机制、数据管理、安全性考虑以及监控与日志。这些策略对于确保系统的可靠性、可维护性和性能至关重要。
|
19天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
23 0
|
7天前
|
消息中间件 监控 持续交付
构建高效微服务架构:后端开发的进阶之路
【4月更文挑战第20天】 随着现代软件开发的复杂性日益增加,传统的单体应用已难以满足快速迭代和灵活部署的需求。微服务架构作为一种新兴的分布式系统设计方式,以其独立部署、易于扩展和维护的特点,成为解决这一问题的关键。本文将深入探讨微服务的核心概念、设计原则以及在后端开发实践中如何构建一个高效的微服务架构。我们将从服务划分、通信机制、数据一致性、服务发现与注册等方面入手,提供一系列实用的策略和建议,帮助开发者优化后端系统的性能和可维护性。
|
18天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。
|
2天前
|
监控 测试技术 持续交付
探索现代微服务架构的最佳实践
【4月更文挑战第25天】 随着软件开发领域不断演进,微服务架构已成为设计灵活、可扩展且高度可维护系统的首选方案。本文将深入探讨构建和部署微服务时的关键最佳实践,涵盖从服务划分原则到持续集成/持续部署(CI/CD)的流程,再到监控与日志记录的策略。我们的目标是为开发者提供一套实用的指南,帮助他们在构建未来的应用程序时做出明智的架构选择,并确保这些系统能够快速响应市场和技术的变化。