CS+ For CA学习笔记(基于RL78/G13/R5F100LGA开发板)第六课 串口通信

终于到了通信协议部分了,这节课学习串口UART接发数据,下节课就学习IIC接发数据。

一、Serial设置

1. Channel

        通过查看用户手册,64引脚产品一共有2个单元,6个通道,最多可实现3个串口收发。

        这里选择通道0的UART0,后面选择发送/接收功能。

        

        打开UART0的Receive页,从上到下一个一个来讲。

        Data length setting 数据长度,这个一般选8bit(一个字节);

        Transfer direction setting 传输设置,LSB是低位先行,MSB是高位先行,一般选默认的LSB。

        Parity setting 校验位设置,看需求,这里不选校验位。

        Stop bit length setting 停止位长度,这里默认1bit。

        Receive data level setting 接收数据空闲设置,一般默认高电平(Normal)为空闲状态。

        Transfer rate setting 传输速度设置,就是选比特率是多少,根据需求进行选择。

        Interrupt setting 中断设置,设置接受完数据时触发,接收完成中断 RXI0 的优先级。

        Callback function setting ,接收完成中断、返回错误中断是否开启,这里默认开启,方便我们接收完数据后进行处理。

分组选项含义
ChannelUART0当前正在配置 SAU0 通道 0 作为 UART0 接收器
Data length7 / 8 / 9 bits一帧数据位长度;8 bits 最常用
Transfer directionLSB / MSB位序:先传最低位 LSB(默认),或最高位 MSB
ParityNone / Zero / Odd / Even校验方式;None=无校验,Even=偶校验
Stop bit1 bit fixedRL78 接收时 固定 1 位停止位,不可改
Receive data levelNormal / Reverse空闲电平极性:Normal=高电平空闲;Reverse=低电平空闲(极少用)
Transfer rateBaudrate 9600 …期望波特率;下方给出实际误差
Reception end interrupt priority (INTSR0)Level 0~3接收完成中断 RXI0 的优先级;0=屏蔽
Reception error interrupt priority (INTSRE0)Level 0~3帧错误/溢出/奇偶错 中断优先级
Callback functionReception end接收完成时 用户回调名(默认 r_uart0_callback_receiveend
 Reception error接收出错时 用户回调名

        

        Transmit 选项卡也是类似,不多讲解。

2. Pin assignment

        

        从这里可以看到,TxD0和RxD0对应P11和P12引脚。

 

二、编写代码

        1、r_cg_serial.c

        看到自动生成的函数,和之前一样,_Create 函数不用编写,_Start需要放到Main函数的初始化函数中。 用到的是

        MD_STATUS R_UART0_Send(uint8_t * const tx_buf, uint16_t tx_num);

        (里面的形参用来存储要发送的数据,调用后数据自动发送)
        MD_STATUS R_UART0_Receive(uint8_t * const rx_buf, uint16_t rx_num);

        (里面的形参用来存储要接收的数据,调用后数据自动接收)

        static void r_uart0_callback_receiveend(void);

        接收完毕后进入中断,需要编辑中断函数里面的内容

        static void r_uart0_callback_sendend(void);

        发送完毕后进入中断,需要编辑中断函数里面的内容

        需要注意,后面两个函数在r_cg_serial_user.c里面。

        2. r_cg_serial_user.c

        

        在这两个中断函数中,写入标志位置零,标志接收/发送完毕。

        3. r_main.c

        定义接收和发送数组,就可以调试运行了。

三、遇到的坑

1. 接收数据后进中断,但是RX_Buffer里面全是0

        这个经过排查,是因为uint8_t const RX_Buffer[5] = {0};将RX_Buffer[5]定义为了只读数组,所以中断可以进,但是RX_Buffer[5]里面的数值不可修改。

********AI 生成******

MD_STATUS R_UART0_Receive(uint8_t * const rx_buf, uint16_t rx_num),调用这个函数时,用RX_Buffer给第一个参数(uint8_t RX_Buffer[5] = {0};)和(uint8_t const RX_Buffer[5] = {0};)有什么区别?

区别只在于 指针本身的“常量性”对接收功能毫无影响,但对代码可读性与后续维护有语义差异


🔍 函数原型

c

复制

MD_STATUS R_UART0_Receive(uint8_t * const rx_buf, uint16_t rx_num);
  • 第一个参数类型是 uint8_t * const
    指针本身(地址)在函数体内不可改,但指向的内存可写(接收数据)。


✅ 两种写法的对比

表格

复制

调用写法实际传入类型是否合法语义说明
uint8_t RX_Buffer[5] = {0};
R_UART0_Receive(RX_Buffer, 5);
uint8_t * → 自动转 uint8_t * const普通可写缓冲区,最常用
uint8_t const RX_Buffer[5] = {0};
R_UART0_Receive(RX_Buffer, 5);
const uint8_t * → 转 uint8_t * const❌ 编译错误试图把“只读内存”地址传给要“写入数据”的函数

⚠️ 关键点

  • uint8_t const RX_Buffer[] 表示 元素只读,编译器把数组放在 flash 或只读段
    R_UART0_Receive() 必定会往里面写数据,因此 类型不匹配,直接报错

  • 函数形参的 const修饰指针本身,不是修饰指向的数据;
    它保证 函数体内不会把 rx_buf 重新指向别的地址,但 要求实参指向的内存必须可写


✅ 正确做法

c

复制

uint8_t RX_Buffer[5] = {0};          // 可写缓冲区
R_UART0_Receive(RX_Buffer, 5);       // ✅ 合法

❌ 错误做法

c

复制

uint8_t const RX_Buffer[5] = {0};    // 只读
R_UART0_Receive(RX_Buffer, 5);       // ❌ 编译错误:丢弃 const 限定

✅ 一句话总结

R_UART0_Receive() 传参时,必须用可写数组 (uint8_t []),
const uint8_t [] 会编译失败,因为驱动需要把接收到的数据 写入 这块内存。

********AI 生成******

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值