当前位置: 首页 > news >正文

UART 使用教程

"# JL701n UART 使用教程

概述

本教程详细介绍如何在 JL701n 芯片上使用 UART 进行串口通信。该示例展示了 UART2 的初始化、数据收发、中断处理等核心功能。

目录

  1. 代码结构分析
  2. 核心功能说明
  3. 配置参数详解
  4. 使用步骤
  5. API 接口说明
  6. 注意事项
  7. 完整使用示例

代码结构分析

头文件包含

```c
#include “app_config.h” // 应用配置头文件
#include “system/includes.h” // 系统通用头文件
#include “asm/uart_dev.h” // UART设备驱动头文件
```

全局变量

```c
static u8 uart_cbuf[32] attribute((aligned(4))); // UART接收缓冲区,4字节对齐
const uart_bus_t *uart_bus = NULL; // UART总线句柄
static u8 my_test_buf[1024]; // 测试数据缓冲区
```

核心功能说明

1. UART 中断处理函数

```c
static void uart_isr_handle(void *arg, u32 status)
```

功能: 处理 UART 中断事件

参数:

  • `arg`: UART 总线指针
  • `status`: 中断状态标志

支持的中断类型:

  • `UT_RX`: 接收满帧数据中断(达到 frame_length 字节)
  • `UT_RX_OT`: 接收超时中断(不满 frame_length 字节)
  • `UT_TX`: 发送完成中断

2. UART 初始化函数

```c
void user_uart_open(void)
```

功能: 初始化并打开 UART2 设备

配置参数:

  • 发送引脚: `TCFG_UART2_TX_PORT`
  • 接收引脚: `TCFG_UART2_RX_PORT`
  • 波特率: `TCFG_UART2_BAUDRATE`
  • 帧长度: 16 字节
  • 接收超时: 100ms

3. 数据发送函数

```c
void user_uart2_send(void *buf, u32 len)
```

功能: 通过 UART2 发送数据

参数:

  • `buf`: 发送数据缓冲区
  • `len`: 数据长度

4. UART 关闭函数

```c
void user_uart_close(void)
```

功能: 关闭 UART2 设备并释放资源

配置参数详解

UART 平台数据结构

```c
struct uart_platform_data_t {
u32 tx_pin; // 发送引脚
u32 rx_pin; // 接收引脚
u8 *rx_cbuf; // 接收缓冲区
u32 rx_cbuf_size; // 缓冲区大小
u32 frame_length; // 帧长度(触发中断的字节数)
u32 rx_timeout; // 接收超时时间(ms)
void (*isr_cbfun)(void *arg, u32 status); // 中断回调函数
u32 baud; // 波特率
u8 is_9bit; // 是否9位数据位
};
```

关键配置说明

参数说明示例值
`tx_pin`发送引脚`TCFG_UART2_TX_PORT`
`rx_pin`接收引脚`TCFG_UART2_RX_PORT`
`rx_cbuf`接收缓冲区`uart_cbuf`
`rx_cbuf_size`缓冲区大小`32`
`frame_length`帧长度`16`
`rx_timeout`接收超时`100`
`baud`波特率`TCFG_UART2_BAUDRATE`
`is_9bit`数据位`0` (8位)

使用步骤

1. 初始化 UART

```c
// 在应用初始化阶段调用
user_uart_open();
```

2. 发送数据

```c
u8 send_data[] = “Hello UART!”;
user_uart2_send(send_data, sizeof(send_data) - 1);
```

3. 接收数据

数据接收通过中断自动处理,在 `uart_isr_handle` 函数中处理接收到的数据。

4. 关闭 UART

```c
// 在应用结束时调用
user_uart_close();
```

API 接口说明

主要函数接口

函数名功能参数返回值
`user_uart_open()`打开UART设备
`user_uart_close()`关闭UART设备
`user_uart2_send()`发送数据`buf`: 数据缓冲区
`len`: 数据长度
`uart_isr_handle()`中断处理函数`arg`: UART句柄
`status`: 中断状态

中断状态标志

标志含义触发条件
`UT_RX`接收满帧接收到 frame_length 字节数据
`UT_RX_OT`接收超时接收不满 frame_length 字节但超时
`UT_TX`发送完成数据发送完成

注意事项

1. 中断处理限制

  • 不要在中断中调用 `ubus->write()`,因为中断不能等待信号量
  • 建议在中断中只读取数据,通过信号量通知任务处理

2. 缓冲区管理

  • 接收缓冲区必须4字节对齐:`attribute((aligned(4)))`
  • 缓冲区大小建议为2的幂次,便于管理

3. 引脚配置

  • 确保 TX/RX 引脚在配置文件中正确定义
  • 发送引脚需要配置为高驱动模式

4. 波特率设置

  • 确保波特率与通信设备匹配
  • 常用波特率:9600, 19200, 38400, 57600, 115200

完整使用示例

基本使用流程

```c
#include “app_config.h”
#include “system/includes.h”
#include “asm/uart_dev.h”

// 1. 初始化UART
void app_init(void)
{
user_uart_open();
}

// 2. 发送数据示例
void send_test_data(void)
{
u8 test_data[] = “UART Test Message\r\n”;
user_uart2_send(test_data, sizeof(test_data) - 1);
}

// 3. 应用主循环
void app_main_loop(void)
{
while(1) {
// 定期发送数据
send_test_data();
os_time_dly(1000); // 延时1秒
}
}

// 4. 应用退出
void app_exit(void)
{
user_uart_close();
}
```

高级使用示例(带任务处理)

```c
// 定义信号量
static os_sem_t uart_rx_sem;

// 修改中断处理函数
static void uart_isr_handle(void *arg, u32 status)
{
if (status == UT_RX) {
// 在中断中只读取数据,不处理
uart_bus->read(my_test_buf, 16, 100);
// 发送信号量通知任务处理
os_sem_post(&uart_rx_sem);
}
}

// 创建UART处理任务
static void uart_task(void *arg)
{
while(1) {
// 等待接收信号量
os_sem_pend(&uart_rx_sem, 0);

    // 处理接收到的数据printf(\"Received: \");put_buf(my_test_buf, 16);// 转发到蓝牙if (bluetooth_spp_user_send_data_check()) {bluetooth_spp_user_send_data(my_test_buf, 16);}
}

}

// 在UART打开时创建任务
void user_uart_open(void)
{
// … 原有初始化代码 …

if (uart_bus != NULL) {// 创建信号量os_sem_create(&uart_rx_sem, 0);// 创建处理任务os_task_create(uart_task, NULL, 31, 512, 0, \"uart_task\");
}

}
```

故障排除

常见问题

  1. UART 打开失败

    • 检查引脚配置是否正确
    • 确认引脚未被其他功能占用
  2. 数据接收异常

    • 检查波特率是否匹配
    • 确认帧长度设置是否合适
  3. 发送数据丢失

    • 检查发送缓冲区是否足够
    • 确认发送引脚配置正确
  4. 中断不触发

    • 检查中断回调函数是否正确注册
    • 确认中断使能状态

调试建议

  1. 使用 `printf` 输出调试信息
  2. 检查 `put_buf` 输出确认数据正确性
  3. 使用示波器检查引脚信号
  4. 逐步验证配置参数

总结

本教程详细介绍了 JL701n 芯片 UART 的使用方法,包括初始化、数据收发、中断处理等核心功能。通过合理配置参数和正确处理中断,可以实现稳定可靠的串口通信功能。

建议在实际使用中根据具体需求调整配置参数,并注意遵循中断处理的最佳实践。"

#include "app_config.h"
#include "system/includes.h"
#include "asm/uart_dev.h"static u8 uart_cbuf[32] __attribute__((aligned(4)));
const uart_bus_t *uart_bus = NULL;static u8 my_test_buf[1024];
void gpio_change(void *priv);
static void uart_isr_handle(void *arg, u32 status)
{const uart_bus_t *ubus = arg;struct sys_event e;//不要在中断里面调用ubus->write(),因为中断不能pend信号量if (status == UT_RX) {  //每满frame_length字节则产生一次中断printf("uart_rx_isr\n");uart_bus->read(my_test_buf, 16, 100);put_buf(my_test_buf, 16);if (bluetooth_spp_user_send_data_check()) {bluetooth_spp_user_send_data(my_test_buf, 16);}//一般这里os_sem_post(&rx_sem); post消息到自己的任务里面把数据读出来使用}if (status == UT_RX_OT) { //outtime : 接收到不满frame_length字节进这里printf("uart_rx_ot_isr : \n");uart_bus->read(my_test_buf, 16, 100);put_buf(my_test_buf, 16);}if (status == UT_TX) {putchar('T');}
}void user_uart2_send(void *buf, u32 len)
{uart_bus->write(buf, len);
}void user_uart_open(void)
{if (uart_bus) {printf("uart2 already open\n");return;}struct uart_platform_data_t u_arg = {0};u_arg.tx_pin = TCFG_UART2_TX_PORT;u_arg.rx_pin = TCFG_UART2_RX_PORT;u_arg.rx_cbuf = uart_cbuf;u_arg.rx_cbuf_size = sizeof(uart_cbuf);u_arg.frame_length = 16; //起uart_isr_handle中断的数据长度u_arg.rx_timeout = 100;u_arg.isr_cbfun = uart_isr_handle;u_arg.baud = TCFG_UART2_BAUDRATE;u_arg.is_9bit = 0;printf("=========================== user_uart_open() ...\n");uart_bus = uart_dev_open(&u_arg);printf("========================comming %s,%d\n", __func__, __LINE__);if (uart_bus != NULL) {printf("=================success\n");gpio_set_hd(TCFG_UART2_TX_PORT, 1);gpio_set_hd0(TCFG_UART2_TX_PORT, 1);//os_task_create(uart_u_task, (void *)uart_bus, 31, 512, 0, "uart_u_task");} else {printf("=========================Uart open false\n");}
}void user_uart_close(void)
{printf("=========================== user_uart_close() ...\n");if (uart_bus != NULL) {uart_dev_close(uart_bus);uart_bus = NULL;}
}

文章转载自:

http://qvu4FlQz.qkqpy.cn
http://eMUepElZ.qkqpy.cn
http://hvguRy42.qkqpy.cn
http://aXsdf9ym.qkqpy.cn
http://bbOMyh3q.qkqpy.cn
http://MfCB1eii.qkqpy.cn
http://cnueVUn3.qkqpy.cn
http://2BJIuXn6.qkqpy.cn
http://ODUTq8w1.qkqpy.cn
http://N1DmYFkE.qkqpy.cn
http://9ZyhqXC3.qkqpy.cn
http://tTrE4aWI.qkqpy.cn
http://LB04qZOz.qkqpy.cn
http://LL5wB3li.qkqpy.cn
http://gIaz7rsU.qkqpy.cn
http://CHrML9GR.qkqpy.cn
http://nQjriYOd.qkqpy.cn
http://WkY6cS5h.qkqpy.cn
http://GkHvrm6n.qkqpy.cn
http://vFnuZyMU.qkqpy.cn
http://lbCDsuFu.qkqpy.cn
http://f04uFP0S.qkqpy.cn
http://jA804k0A.qkqpy.cn
http://vl4Io4nW.qkqpy.cn
http://GtoiWZJ4.qkqpy.cn
http://Aa4Umgqp.qkqpy.cn
http://E8hASNnV.qkqpy.cn
http://LN44fefk.qkqpy.cn
http://NKJKohHw.qkqpy.cn
http://X28rAwEk.qkqpy.cn
http://www.dtcms.com/a/372181.html

相关文章:

  • cuda中线程id的计算方式(简单)
  • Archon02-代码解析
  • # 图片格式转换工具:重新定义您的图片处理体验
  • 【Python】S1 基础篇 P2 列表详解:基础操作
  • 液压伺服千斤顶系统设计cad+设计说明书
  • MySQL 锁机制解析
  • directive-plugin指令插件相关参数文档
  • 3D 版接雨水
  • (LeetCode 每日一题)1304. 和为零的 N 个不同整数(数组)
  • WebGL2初识
  • 浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
  • TI例程demo-ADC电压、电流采样的学习研究及硬件验证调试
  • AOP常见面试题
  • Suricata 8阿里云编译安装保姆教程
  • 【112】基于51单片机大棚鸡舍远程数据检测系统【Keil程序+报告+原理图】
  • 深入理解OpenHarmony中的BUILD.gn:从语法到模块化构建
  • 阴阳学:从入门到精通
  • vulhub通关笔记1—docker unauthorized-rce
  • ZYNQ PS XADC读取芯片内部温度值,电压值。
  • 每日一题(3)
  • 泛型编程(简单介绍,通俗易懂)
  • 扩散模型揭秘:生成式AI的核心与应用
  • 【Flink】Flink Runtime 架构设计
  • MySQL数据库同步
  • 使用 Spring Security 实现 OAuth2:一步一步的操作指南
  • Axure: 分组柱状图1
  • CEEMDAN-PSO-CNN-GRU 锂电池健康状态预测matlab
  • Spring Cloud Gateway 作为一个独立的服务进行部署吗
  • webrtc弱网-LossBasedBweV2类源码分析与算法原理
  • leetcode hot100 二叉搜索树