学习笔记——嵌入式系统通信基础及串口开发

嵌入式系统通信基础及i.MX6ULL串口开发笔记

一、通信基本概念

1.1 通信定义

嵌入式系统中的通信是指两个或两个以上的主机之间的数据交互过程。

1.2 通信分类

异步通信 vs 同步通信
类型 特点 示例
异步通信 无需时钟信号同步,依靠起始位、停止位、校验位等标志位 UART、RS-232
同步通信 需要时钟信号同步,发送和接收方使用同一时钟 SPI、I2C、USB
串行通信 vs 并行通信
类型 特点 优缺点 示例
串行通信 逐位顺序传输 优点:节省引脚、抗干扰 缺点:速度相对慢 UART、I2C、SPI
并行通信 多位同时传输 优点:速度快 缺点:引脚多、干扰大 8086总线、打印机接口
单工/半双工/全双工
类型 特点 示意图 示例
单工 单向传输 A → B 广播、电视
半双工 双向但不同时 A ↔ B(分时) 对讲机、RS-485
全双工 双向同时传输 A ⇄ B 电话、UART

1.3 电气标准

TTL电平
  • 逻辑0:0V

  • 逻辑1:3.3V/5V

  • 传输距离短(<1m)

RS-232
  • 逻辑0:+3V ~ +15V

  • 逻辑1:-3V ~ -15V

  • 传输距离:15米

  • 点对点通信

RS-485
  • 差分信号传输

  • 逻辑0:A-B < -0.2V

  • 逻辑1:A-B > +0.2V

  • 传输距离:1200米

  • 支持多点通信

差分传输
  • 使用两根信号线传输相位相反的信号

  • 优点:抗干扰能力强,传输距离远

  • 缺点:需要两根线传输一位数据

二、原理图分析

2.1 参考文档

2.2 USB转串口模块

复制代码
┌─────────────────────┐
│     USB接口         │
│   (USB Type-B)      │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│      CH340G         │
│   (USB转TTL芯片)    │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│   UART1_TX/RX       │
│   (TTL电平)         │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│   i.MX6ULL SOC      │
└─────────────────────┘

2.3 关键组件说明

(1)USB接口(USB_TTL)
  • 用于PC与开发板通信

  • 注意:不建议使用USB作为电源供电,会导致板子发热

(2)CH340芯片(U8)
  • 功能:USB转串口(TTL电平)

  • 将USB信号转换为UART信号

(3)DCDC电源稳压模块(U12 U13)
  • 功能:电源稳压

  • 特点:防抖、抗干扰设计

三、代码编写

3.1 参考文档

IMX6ULL参考手册.pdf

3.2 初始化步骤

(1)时钟初始化
复制代码
// 基准时钟80MHz,预分频1分频
void uart_clk_init(void)
{
    // UART1时钟配置
    CCM->CSCDR1 &= ~(0x3F << 0);  // 清空中断
    CCM->CSCDR1 |= (1 << 0);      // 1分频
}
(2)引脚初始化
复制代码
void uart_pin_init(void)
{
    // UART1_TX引脚配置
    IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0);
    IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 0x10B0);
    
    // UART1_RX引脚配置
    IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0);
    IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX, 0x10B0);
}

3.3 寄存器配置

(1)接收寄存器(UARTx_URXD)
  • 地址:只读寄存器

  • 功能:保存接收到的字符

  • 位说明

    • RX_DATA[7:0]:已接收数据

    • 7位模式:MSB强制为0

    • 8位模式:所有位都有效

(2)发送寄存器(UARTx_UTXD)
  • 地址:可写寄存器

  • 功能:写入需要发送的数据

  • 特性:写入后自动开始发送

(3)控制寄存器1(UARTx_UCR1)
复制代码
// 重要位说明
UARTx_UCR1:
[UARTEN] b0:UART模块总使能位(1=使能,0=关闭)
(4)控制寄存器2(UARTx_UCR2)
复制代码
// 位说明
[UARTEN]  b0:软件复位(写1复位,持续4个时钟周期)
[RXEN]    b1:接收器使能
[TXEN]    b2:发送器使能
[WS]      b5:字长选择(0=8位,1=7位)
[STPB]    b6:停止位数量(0=1位,1=2位)
[PREN]    b8:奇偶校验使能
[IRTS]    b14:忽略RTS流控(设置为1)
(5)控制寄存器3(UARTx_UCR3)
复制代码
[RXDMUXSEL] b2:必须设置为1(MUXED模式)
(6)FIFO控制寄存器(UARTx_UFCR)
复制代码
[RFDIV] b7-b9:参考时钟分频器
// 000 = 6分频,001 = 5分频,010 = 4分频
// 011 = 3分频,100 = 2分频,101 = 1分频
(7)状态寄存器2(UARTx_USR2)
复制代码
[TXDC] b3:发送完成标志位(1=完成)
[RDR]  b0:接收数据就绪标志位(1=有数据)
(8)波特率配置
复制代码
// 波特率计算公式
BaudRate = Ref_Freq / (16 × ((UBMR + 1) / (UBIR + 1)))

// 寄存器配置
UARTx_UBIR:增量寄存器
UARTx_UBMR:模数寄存器

3.4 UART驱动函数实现

(1)发送函数
复制代码
// 发送单个字符
void putc(unsigned char d)
{
    // 等待发送完成标志
    while ((UART1->USR2 & (1 << 3)) == 0);
    // 写入发送寄存器
    UART1->UTXD = d;
}

// 发送字符串
void puts(const char *pStr)
{
    while (*pStr)
    {
        putc(*pStr++);
    }
    putc('\n');  // 添加换行
}
(2)接收函数
复制代码
// 接收单个字符
unsigned char getc(void)
{
    // 等待接收数据就绪
    while ((UART1->USR2 & (1 << 0)) == 0);
    // 读取数据
    return (unsigned char)UART1->URXD & 0xFF;
}

3.5 移植标准输入输出(stdio)

步骤说明
  1. 添加空函数(解决编译错误)

    复制代码
    void raise(int n)
    {
        // 空函数体
    }
  2. 修改汇编文件扩展名

    • start.s改为start.S

    • 注意:大写S会进行预处理,小写s则不会

  3. 修改Makefile

    复制代码
    # 库路径配置
    libpath = -lgcc -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.4
    
    # 包含目录
    incdirs = bsp imx6ull stdio/include
    
    # 源码目录
    srcdirs = bsp project stdio/lib
    
    # 链接选项
    $(ld) -Timx6ull.lds -o$(target).elf $^ $(libpath)
    
    # 编译选项
    $(cc) -Wall -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c $(include) -o $@ $<
相关推荐
不怕犯错,就怕不做2 小时前
Linux内核默认允许多个进程打开同一字符设备
linux·驱动开发·嵌入式硬件
小袁顶风作案2 小时前
leetcode力扣——452. 用最少数量的箭引爆气球
学习·算法·leetcode·职场和发展
乡野码圣2 小时前
【RK3588 Android12】同步机制选型指南
嵌入式硬件
羑悻的小杀马特2 小时前
零成本神器组合:用Docker+Uptime Kuma+cpolar打造永不掉线的远程监控系统!
运维·人工智能·docker·容器
StevenZeng学堂2 小时前
一文读懂K8S的PV和PVC以及实践攻略
运维·docker·云原生·容器·kubernetes·云计算·go
2501_942326442 小时前
脑科学高效记忆法让学习变轻松
学习
Bruce-li__2 小时前
2025保姆级Docker教程------一篇学会使用docker
运维·docker·容器
科技小E2 小时前
EasyGBS在物业视频安防管理中的应用实践
运维·网络·音视频
cocodameyou1322 小时前
从能量阻滞到流动:解码“被动学习”背后的家庭动能重构逻辑
笔记·学习·其他·百度·微信·重构·课程设计