0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

代码生成器配置和软件UART的实现

瑞萨MCU小百科 来源:瑞萨MCU小百科 2023-05-09 09:25 次阅读

由于MCU内部资源限制,在应用中会出现UART接口不够用的情况,如果UART使用的波特率不太高,而且系统中的负荷不是很大的情况就可以使用端口模拟UART的收发,下文是一个在R5F100LE(RL78)上的具体的实现方法,这里略去工程的建立过程,相应的驱动程序细节可以参考代码生成器生成的代码,这里只重点讲述代码生成器配置和软件UART的实现。

一、硬件资源准备

01一个具有外部边沿中断功能的IO口来做UART的RXD端口,下面是一个配置的例子,在这里我们使用P137(INTP0),在代码生成器里选择INTP0为下降沿中断,中断优先级可以任意设置。

dab1c39a-ed7e-11ed-90ce-dac502259ad0.png

02一个普通的输出口来作为UART的TXD端口。这里选择P43端口,设置端口输出高。

dadcf0d8-ed7e-11ed-90ce-dac502259ad0.png

03两个可以产生中断、可以随时关闭启动、定时间隔可以任意设定的定时器,一个发送定时器用于发送数据,一个接收定时器用于接收数据。

将接收定时器的定时间隔初始化为1位数据的时长的一半,比如波特率2400,1位为416.6us,那么定时器设置为416.6us/2=208.3us,在这里我们使用了Timer的Channel 1

db087d98-ed7e-11ed-90ce-dac502259ad0.pngdb38ade2-ed7e-11ed-90ce-dac502259ad0.png

将发送定时器的定时间隔设置为1位数据时长,比如波特率2400,1位为416.6us,那么定时器设置为416.6us,在这里我们使用Timer的Channel 0。

db4ce2da-ed7e-11ed-90ce-dac502259ad0.png

二、UART接收功能的实现

01接收的软件实现

接收时我们需要写两个中断函数,在中断里完成数据的接收,接收完毕后设置一个标志,在主循环中根据标志来判断数据是否接收完毕。初始化时需要打开边沿中断,关闭定时器中断。

1)边沿中断函数处理

当下降沿中断到来时,在边沿中断函数里启动接收定时器,关闭边沿中断。具体程序如下:

左右滑动查看完整内容

void softuart_rece_port_fall_edge_callback(void)
{
 softuart_rece_state = 0;//接收定时器进入次数计数清零
 uart_port_intp_stop();// 关闭边沿中断
 start_uart_rece_timer();//打开接收定时器中断
}

这个函数放到r_cg_intc_user.c内

db6fd894-ed7e-11ed-90ce-dac502259ad0.png

2)接收定时器中断函数

每奇数次进入中断时(第1,3,5…)进行RXD端口的采样并保存数据,同时根据我们的要求进行移位操作(比如LSB或MSB,数据长度是几位),在偶数次进入中断时就直接退出,当数据接收完成后设置标志,同时关闭接收定时器中断,打开边沿中断中断,具体程序如下,这里我是用的8位数据长度和1个停止位:

左右滑动查看完整内容

void softuart_rece_timer_callback(void)
{
static __saddr uint8_t uartrece_shift_reg;
 softuart_rece_state++;//进入次数++
 if(softuart_rece_state==1)//接收start位
 {
  //check start bit
  if(1==get_uart_rece_port())
  {
   //start bit error
   uartrece_shift_reg = 0;
   stop_uart_rece_timer();
   uart_port_intp_start();
  }
 }
 else if (softuart_rece_state<=17)//接收8位数据位
  {
    //receive data sampling point 3,5,7,9,11,13,15,17
    if(0==(softuart_rece_state&1)) return;
   uartrece_shift_reg >>= 1;
  if(1==get_uart_rece_port())
  {
   uartrece_shift_reg |= 0x80;
  }
 }
 else if(softuart_rece_state>=19)//接收停止位
 {
  //stop bit sample sampling point 19
  stop_uart_rece_timer();//关闭接收定时器
  uart_port_intp_start();//打开下降沿中断
  if(uartrece_end_fg ==0)
  {
   uartrece_data = uartrece_shift_reg;
   uartrece_end_fg =1;//设置接收完毕标志
  }
 }
}

这个程序要放到r_cg_timer_user.c内

db8518f8-ed7e-11ed-90ce-dac502259ad0.png

3)在主循环里调用如下函数来判断是否收到数据

左右滑动查看完整内容

uint8_t get_softuart_rece(uint8_t * buff)
{
 if(uartrece_end_fg==1)
 {
  uartrece_end_fg =0;
  *buff = uartrece_data;//将数据放入接收缓冲区
  return 1;//说明收到数据
 }
 return 0;
}

三、UART发送功能的实现

01发送软件的实现

发送时需要写一个发送定时器中断函数,在中断里完成数据发送,发送完成后设置一个标志,在主循环中判断,初始化时需要关闭发送定时器,中断的代码如下:

左右滑动查看完整内容

void softuart_send_callback(void)
{
 softuart_send_state++;
 if(softuart_send_state==10)//发送停止位
 {
  //sampling point 10 stop bit
  softuart_send_port_h();
 }
 else if(softuart_send_state>10)//等待停止位发送完毕
 {
  //>11 stop bit send finished
  softuart_send_state=0;
  stop_uart_send_timer();
 }
 else//发送数据
 {
  //samplimng point 2,3,4,5,6,7,8,9
  if(0!=(uartsend_shift_reg&1))
  {
   softuart_send_port_h();
  }
  else
  {
   softuart_send_port_l();
  }
  uartsend_shift_reg >>= 1;
 }
}

这个程序要放到r_cg_timer_user.c内

dbb12fb0-ed7e-11ed-90ce-dac502259ad0.png

当需要发送时,先将发送端口设置为低电平,然后开启发送定时器,如果正在发送返回发送错误。具体的操作代码如下:

左右滑动查看完整内容

uint8_t softuart_send(uint8_t data)
{
 if(softuart_send_state!=0)return 0;//数据没有发送完毕
 softuart_send_state = 1;
 DI();
 softuart_send_port_l();   //发送起始位
 uartsend_shift_reg=data;//将要发送的数据放到移位寄存器
 start_uart_send_timer();//启动UART发送定时器
 EI();
 return 1;
}

四、整个程序的初始化

由于相应硬件的初始化程序在R_Systeminit已经调用过了,所以我们只用调用启动程序就行了,为了方便程序的修改,用宏定义重新定义了接口部分。

左右滑动查看完整内容

#define start_uart_rece_timer() R_TAU0_Channel1_Start()
#define stop_uar_rece_timer()  R_TAU0_Channel1_Stop()
#define uart_port_intp_start()    R_INTC0_Start()
#define uart_port_intp_stop()    R_INTC0_Stop()
#define get_uart_rece_port()    P13_bit.no7
#define start_uart_send_timer() R_TAU0_Channel0_Start()
#define stop_uart_send_timer() R_TAU0_Channel0_Stop()
#define softuart_send_port_h()    {P4_bit.no3 = 1;}
#define softuart_send_port_l()    {P4_bit.no3 = 0;}

如果想要修改使用的硬件资源只用修改宏定义即可。

在使用软件UART之前需要先调用一下如下初始化函数。

左右滑动查看完整内容

void softuart_int(void)
{
 stop_uart_send_timer();//停止发送定时器
 stop_uart_rece_timer();//停止接收定时器
 uart_port_intp_stop(); // 边沿中断接收停止
 softuart_send_port_h(); // TXD端口设置为高
 uart_port_intp_start(); // 允许RXD端口的下降沿中断
 softuart_send_state = 0;
 softuart_rece_state = 0;
 uartrece_end_fg = 0;
}

注意

1)使用上述方法就可以实现一个软件的UART操作,但是使用过程中不能有长时间的关闭中断操作,如果有的话会影响程序的执行。

2)如果通讯波特率发生变化需要修改定时器的定时值。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17123

    浏览量

    350984
  • 中断
    +关注

    关注

    5

    文章

    898

    浏览量

    41470
  • 定时器
    +关注

    关注

    23

    文章

    3246

    浏览量

    114719
  • uart
    +关注

    关注

    22

    文章

    1235

    浏览量

    101354
  • 代码生成器
    +关注

    关注

    0

    文章

    25

    浏览量

    9118

原文标题:代码生成器配置和软件UART的实现

文章出处:【微信号:瑞萨MCU小百科,微信公众号:瑞萨MCU小百科】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    汉字生成器软件

    给个汉字生成器软件!!
    发表于 01-18 11:18

    怎么使用代码生成器进行外部唤醒源配置

    大家好,我正在使用板, 5.2.1我想配置WKUP [2]引脚号:PA [1]作为外部唤醒源,我没有找到使用代码生成器唤醒的任何回调函数代码生成
    发表于 11-28 10:31

    python生成器

    python生成器1. 什么是生成器生成器(英文名 Generator ),是一个可以像迭代器那样使用for循环来获取元素的函数。生成器的出现(Python 2.2 +),
    发表于 02-24 15:56

    利用LabVIEW代码生成器简化应用项目

    利用LabVIEW代码生成器简化应用项目
    发表于 02-26 14:01 24次下载
    利用LabVIEW<b class='flag-5'>代码</b><b class='flag-5'>生成器</b>简化应用项目

    代码生成器的应用

    jeesite框架代码生成器,可以很方便的生成代码,挺不错的。
    发表于 01-14 15:19 0次下载

    数码管代码生成器

    数码管代码生成器,迅速生成数码管的相应代码
    发表于 04-25 10:54 40次下载

    STM32库函数代码自动生成器V1.2

    stm32库函数代码自动生成器是STM32学习的小工具。 stm32库函数代码自动生成器可以根据你的配置
    发表于 06-17 17:55 0次下载

    STM32库函数代码自动生成器正式版

    STM32库函数代码自动生成器正式版,感兴趣的可以看看。
    发表于 07-13 16:55 0次下载

    STM32库函数代码自动生成器正式版

    STM32库函数代码自动生成器正式版 STM32库函数代码自动生成器正式版
    发表于 07-25 18:52 0次下载

    python生成器是什么

    python生成器 1. 什么是生成器生成器(英文名 Generator ),是一个可以像迭代器那样使用for循环来获取元素的函数。 生成器的出现(Python 2.2 +),
    的头像 发表于 02-24 15:53 3655次阅读

    如何扩展自定义功能块,以及代码生成器的用法

    被动代码生成器 目标代码生成之后,需要进行修改和完善,然后独立发展和维护,与代码生成器再与关系。
    的头像 发表于 11-02 13:26 1105次阅读

    将使用代码生成器生成的项目移植到与智能配置器一起使用的项目

    将使用代码生成器生成的项目移植到与智能配置器一起使用的项目
    发表于 01-11 19:00 0次下载
    将使用<b class='flag-5'>代码</b><b class='flag-5'>生成器</b><b class='flag-5'>生成</b>的项目移植到与智能<b class='flag-5'>配置</b>器一起使用的项目

    个性化地定制自己的uvm代码生成器模板和脚本

    使用uvm代码生成器创建基本的uvm验证环境框架,然后丢弃代码生成器模板并扩展和维护生成出来的代码
    的头像 发表于 05-14 16:51 2075次阅读
    个性化地定制自己的uvm<b class='flag-5'>代码</b><b class='flag-5'>生成器</b>模板和脚本

    将使用代码生成器生成的项目移植到与智能配置器一起使用的项目

    将使用代码生成器生成的项目移植到与智能配置器一起使用的项目
    发表于 06-30 20:54 0次下载
    将使用<b class='flag-5'>代码</b><b class='flag-5'>生成器</b><b class='flag-5'>生成</b>的项目移植到与智能<b class='flag-5'>配置</b>器一起使用的项目

    RL78的代码生成器发布说明

    电子发烧友网站提供《RL78的代码生成器发布说明.pdf》资料免费下载
    发表于 01-30 09:48 0次下载
    RL78的<b class='flag-5'>代码</b><b class='flag-5'>生成器</b>发布说明