0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

代碼生成器配置和軟件UART的實(shí)現(xiàn)

瑞薩MCU小百科 ? 來(lái)源:瑞薩MCU小百科 ? 2023-05-09 09:25 ? 次閱讀

由于MCU內(nèi)部資源限制,在應(yīng)用中會(huì)出現(xiàn)UART接口不夠用的情況,如果UART使用的波特率不太高,而且系統(tǒng)中的負(fù)荷不是很大的情況就可以使用端口來(lái)模擬UART的收發(fā),下文是一個(gè)在R5F100LE(RL78)上的具體的實(shí)現(xiàn)方法,這里略去工程的建立過(guò)程,相應(yīng)的驅(qū)動(dòng)程序細(xì)節(jié)可以參考代碼生成器生成的代碼,這里只重點(diǎn)講述代碼生成器配置和軟件UART的實(shí)現(xiàn)。

一、硬件資源準(zhǔn)備

01一個(gè)具有外部邊沿中斷功能的IO口來(lái)做UART的RXD端口,下面是一個(gè)配置的例子,在這里我們使用P137(INTP0),在代碼生成器里選擇INTP0為下降沿中斷,中斷優(yōu)先級(jí)可以任意設(shè)置。

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

02一個(gè)普通的輸出口來(lái)作為UART的TXD端口。這里選擇P43端口,設(shè)置端口輸出高。

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

03兩個(gè)可以產(chǎn)生中斷、可以隨時(shí)關(guān)閉啟動(dòng)、定時(shí)間隔可以任意設(shè)定的定時(shí)器,一個(gè)發(fā)送定時(shí)器用于發(fā)送數(shù)據(jù),一個(gè)接收定時(shí)器用于接收數(shù)據(jù)。

將接收定時(shí)器的定時(shí)間隔初始化為1位數(shù)據(jù)的時(shí)長(zhǎng)的一半,比如波特率2400,1位為416.6us,那么定時(shí)器設(shè)置為416.6us/2=208.3us,在這里我們使用了Timer的Channel 1

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

將發(fā)送定時(shí)器的定時(shí)間隔設(shè)置為1位數(shù)據(jù)時(shí)長(zhǎng),比如波特率2400,1位為416.6us,那么定時(shí)器設(shè)置為416.6us,在這里我們使用Timer的Channel 0。

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

二、UART接收功能的實(shí)現(xiàn)

01接收的軟件實(shí)現(xiàn)

接收時(shí)我們需要寫(xiě)兩個(gè)中斷函數(shù),在中斷里完成數(shù)據(jù)的接收,接收完畢后設(shè)置一個(gè)標(biāo)志,在主循環(huán)中根據(jù)標(biāo)志來(lái)判斷數(shù)據(jù)是否接收完畢。初始化時(shí)需要打開(kāi)邊沿中斷,關(guān)閉定時(shí)器中斷。

1)邊沿中斷函數(shù)處理

當(dāng)下降沿中斷到來(lái)時(shí),在邊沿中斷函數(shù)里啟動(dòng)接收定時(shí)器,關(guān)閉邊沿中斷。具體程序如下:

左右滑動(dòng)查看完整內(nèi)容

void softuart_rece_port_fall_edge_callback(void)
{
 softuart_rece_state = 0;//接收定時(shí)器進(jìn)入次數(shù)計(jì)數(shù)清零
 uart_port_intp_stop();// 關(guān)閉邊沿中斷
 start_uart_rece_timer();//打開(kāi)接收定時(shí)器中斷
}

這個(gè)函數(shù)放到r_cg_intc_user.c內(nèi)

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

2)接收定時(shí)器中斷函數(shù)

每奇數(shù)次進(jìn)入中斷時(shí)(第1,3,5…)進(jìn)行RXD端口的采樣并保存數(shù)據(jù),同時(shí)根據(jù)我們的要求進(jìn)行移位操作(比如LSB或MSB,數(shù)據(jù)長(zhǎng)度是幾位),在偶數(shù)次進(jìn)入中斷時(shí)就直接退出,當(dāng)數(shù)據(jù)接收完成后設(shè)置標(biāo)志,同時(shí)關(guān)閉接收定時(shí)器中斷,打開(kāi)邊沿中斷中斷,具體程序如下,這里我是用的8位數(shù)據(jù)長(zhǎng)度和1個(gè)停止位:

左右滑動(dòng)查看完整內(nèi)容

void softuart_rece_timer_callback(void)
{
static __saddr uint8_t uartrece_shift_reg;
 softuart_rece_state++;//進(jìn)入次數(shù)++
 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位數(shù)據(jù)位
 ?{
 ? ?//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();//關(guān)閉接收定時(shí)器
  uart_port_intp_start();//打開(kāi)下降沿中斷
  if(uartrece_end_fg ==0)
  {
   uartrece_data = uartrece_shift_reg;
   uartrece_end_fg =1;//設(shè)置接收完畢標(biāo)志
  }
 }
}

這個(gè)程序要放到r_cg_timer_user.c內(nèi)

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

3)在主循環(huán)里調(diào)用如下函數(shù)來(lái)判斷是否收到數(shù)據(jù)

左右滑動(dòng)查看完整內(nèi)容

uint8_t get_softuart_rece(uint8_t * buff)
{
 if(uartrece_end_fg==1)
 {
  uartrece_end_fg =0;
  *buff = uartrece_data;//將數(shù)據(jù)放入接收緩沖區(qū)
  return 1;//說(shuō)明收到數(shù)據(jù)
 }
 return 0;
}

三、UART發(fā)送功能的實(shí)現(xiàn)

01發(fā)送軟件的實(shí)現(xiàn)

發(fā)送時(shí)需要寫(xiě)一個(gè)發(fā)送定時(shí)器中斷函數(shù),在中斷里完成數(shù)據(jù)發(fā)送,發(fā)送完成后設(shè)置一個(gè)標(biāo)志,在主循環(huán)中判斷,初始化時(shí)需要關(guān)閉發(fā)送定時(shí)器,中斷的代碼如下:

左右滑動(dòng)查看完整內(nèi)容

void softuart_send_callback(void)
{
 softuart_send_state++;
 if(softuart_send_state==10)//發(fā)送停止位
 {
  //sampling point 10 stop bit
  softuart_send_port_h();
 }
 else if(softuart_send_state>10)//等待停止位發(fā)送完畢
 {
  //>11 stop bit send finished
  softuart_send_state=0;
  stop_uart_send_timer();
 }
 else//發(fā)送數(shù)據(jù)
 {
  //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;
 }
}

這個(gè)程序要放到r_cg_timer_user.c內(nèi)

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

當(dāng)需要發(fā)送時(shí),先將發(fā)送端口設(shè)置為低電平,然后開(kāi)啟發(fā)送定時(shí)器,如果正在發(fā)送返回發(fā)送錯(cuò)誤。具體的操作代碼如下:

左右滑動(dòng)查看完整內(nèi)容

uint8_t softuart_send(uint8_t data)
{
 if(softuart_send_state!=0)return 0;//數(shù)據(jù)沒(méi)有發(fā)送完畢
 softuart_send_state = 1;
 DI();
 softuart_send_port_l();   //發(fā)送起始位
 uartsend_shift_reg=data;//將要發(fā)送的數(shù)據(jù)放到移位寄存器
 start_uart_send_timer();//啟動(dòng)UART發(fā)送定時(shí)器
 EI();
 return 1;
}

四、整個(gè)程序的初始化

由于相應(yīng)硬件的初始化程序在R_Systeminit已經(jīng)調(diào)用過(guò)了,所以我們只用調(diào)用啟動(dòng)程序就行了,為了方便程序的修改,用宏定義重新定義了接口部分。

左右滑動(dòng)查看完整內(nèi)容

#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之前需要先調(diào)用一下如下初始化函數(shù)。

左右滑動(dòng)查看完整內(nèi)容

void softuart_int(void)
{
 stop_uart_send_timer();//停止發(fā)送定時(shí)器
 stop_uart_rece_timer();//停止接收定時(shí)器
 uart_port_intp_stop(); // 邊沿中斷接收停止
 softuart_send_port_h(); // TXD端口設(shè)置為高
 uart_port_intp_start(); // 允許RXD端口的下降沿中斷
 softuart_send_state = 0;
 softuart_rece_state = 0;
 uartrece_end_fg = 0;
}

注意

1)使用上述方法就可以實(shí)現(xiàn)一個(gè)軟件的UART操作,但是使用過(guò)程中不能有長(zhǎng)時(shí)間的關(guān)閉中斷操作,如果有的話會(huì)影響程序的執(zhí)行。

2)如果通訊波特率發(fā)生變化需要修改定時(shí)器的定時(shí)值。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    16785

    瀏覽量

    349317
  • 中斷
    +關(guān)注

    關(guān)注

    5

    文章

    893

    瀏覽量

    41319
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3226

    瀏覽量

    114139
  • uart
    +關(guān)注

    關(guān)注

    22

    文章

    1214

    瀏覽量

    100995
  • 代碼生成器
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    9066

原文標(biāo)題:代碼生成器配置和軟件UART的實(shí)現(xiàn)

文章出處:【微信號(hào):瑞薩MCU小百科,微信公眾號(hào):瑞薩MCU小百科】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    漢字生成器軟件

    給個(gè)漢字生成器軟件!!
    發(fā)表于 01-18 11:18

    怎么使用代碼生成器進(jìn)行外部喚醒源配置

    大家好,我正在使用板, 5.2.1我想配置WKUP [2]引腳號(hào):PA [1]作為外部喚醒源,我沒(méi)有找到使用代碼生成器喚醒的任何回調(diào)函數(shù)代碼生成
    發(fā)表于 11-28 10:31

    python生成器

    python生成器1. 什么是生成器生成器(英文名 Generator ),是一個(gè)可以像迭代器那樣使用for循環(huán)來(lái)獲取元素的函數(shù)。生成器的出現(xiàn)(Python 2.2 +),
    發(fā)表于 02-24 15:56

    利用LabVIEW代碼生成器簡(jiǎn)化應(yīng)用項(xiàng)目

    利用LabVIEW代碼生成器簡(jiǎn)化應(yīng)用項(xiàng)目
    發(fā)表于 02-26 14:01 ?24次下載
    利用LabVIEW<b class='flag-5'>代碼</b><b class='flag-5'>生成器</b>簡(jiǎn)化應(yīng)用項(xiàng)目

    代碼生成器的應(yīng)用

    jeesite框架代碼生成器,可以很方便的生成代碼,挺不錯(cuò)的。
    發(fā)表于 01-14 15:19 ?0次下載

    數(shù)碼管代碼生成器

    數(shù)碼管代碼生成器,迅速生成數(shù)碼管的相應(yīng)代碼
    發(fā)表于 04-25 10:54 ?40次下載

    STM32庫(kù)函數(shù)代碼自動(dòng)生成器V1.2

    stm32庫(kù)函數(shù)代碼自動(dòng)生成器是STM32學(xué)習(xí)的小工具。 stm32庫(kù)函數(shù)代碼自動(dòng)生成器可以根據(jù)你的配置
    發(fā)表于 06-17 17:55 ?0次下載

    STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版

    STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版,感興趣的可以看看。
    發(fā)表于 07-13 16:55 ?0次下載

    STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版

    STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版 STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版
    發(fā)表于 07-25 18:52 ?0次下載

    python生成器是什么

    python生成器 1. 什么是生成器? 生成器(英文名 Generator ),是一個(gè)可以像迭代器那樣使用for循環(huán)來(lái)獲取元素的函數(shù)。 生成器的出現(xiàn)(Python 2.2 +),
    的頭像 發(fā)表于 02-24 15:53 ?3534次閱讀

    如何擴(kuò)展自定義功能塊,以及代碼生成器的用法

    被動(dòng)代碼生成器 目標(biāo)代碼生成之后,需要進(jìn)行修改和完善,然后獨(dú)立發(fā)展和維護(hù),與代碼生成器再與關(guān)系。
    的頭像 發(fā)表于 11-02 13:26 ?1040次閱讀

    將使用代碼生成器生成的項(xiàng)目移植到與智能配置器一起使用的項(xiàng)目

    將使用代碼生成器生成的項(xiàng)目移植到與智能配置器一起使用的項(xiàng)目
    發(fā)表于 01-11 19:00 ?0次下載
    將使用<b class='flag-5'>代碼</b><b class='flag-5'>生成器</b><b class='flag-5'>生成</b>的項(xiàng)目移植到與智能<b class='flag-5'>配置</b>器一起使用的項(xiàng)目

    個(gè)性化地定制自己的uvm代碼生成器模板和腳本

    使用uvm代碼生成器創(chuàng)建基本的uvm驗(yàn)證環(huán)境框架,然后丟棄代碼生成器模板并擴(kuò)展和維護(hù)生成出來(lái)的代碼
    的頭像 發(fā)表于 05-14 16:51 ?1889次閱讀
    個(gè)性化地定制自己的uvm<b class='flag-5'>代碼</b><b class='flag-5'>生成器</b>模板和腳本

    將使用代碼生成器生成的項(xiàng)目移植到與智能配置器一起使用的項(xiàng)目

    將使用代碼生成器生成的項(xiàng)目移植到與智能配置器一起使用的項(xiàng)目
    發(fā)表于 06-30 20:54 ?0次下載
    將使用<b class='flag-5'>代碼</b><b class='flag-5'>生成器</b><b class='flag-5'>生成</b>的項(xiàng)目移植到與智能<b class='flag-5'>配置</b>器一起使用的項(xiàng)目

    RL78的代碼生成器發(fā)布說(shuō)明

    電子發(fā)燒友網(wǎng)站提供《RL78的代碼生成器發(fā)布說(shuō)明.pdf》資料免費(fèi)下載
    發(fā)表于 01-30 09:48 ?0次下載
    RL78的<b class='flag-5'>代碼</b><b class='flag-5'>生成器</b>發(fā)布說(shuō)明