質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
組み込み開発

組み込み開発とは、スマートフォンや家電、自動車などに組み込まれているコンピューターシステムの開発のことです。特定の用途に特化しており、限られた機能のための開発を指します。組み込み開発で作られた機器を組み込み機器と呼び、近年ではPCのオペレーションシステム(OS)にも採用されています。

Q&A

解決済

2回答

1322閲覧

RXマイコンでのシリアル通信(SCIFA)のFIFOバッファが分からない

Nyanmage.neko

総合スコア7

組み込み開発

組み込み開発とは、スマートフォンや家電、自動車などに組み込まれているコンピューターシステムの開発のことです。特定の用途に特化しており、限られた機能のための開発を指します。組み込み開発で作られた機器を組み込み機器と呼び、近年ではPCのオペレーションシステム(OS)にも採用されています。

0グッド

0クリップ

投稿2023/08/25 07:37

編集2023/08/25 07:47

実現したいこと

SCIFAを使用してシリアル通信を行いたい。

前提

使用開発環境は、e2studio
CCRXコンパイラ
スマートコンフィグレータ機能を使用し、SCIF9のコンポーネントを追加

発生している問題・エラーメッセージ

SCIFAはFIFOバッファを利用した通信仕様になるのですが、FIFOバッファを利用した送受信でのデータの取り出し方が理解できません。
シリアル通信(RS232C)で外部機器との通信を考えています。
外部機器が指定したコマンドを使用して、フレーム同期をしなくてはならないのですが、マイコン側で、送受信を行う場合に、

①受信
外部機器からの「AF 06 B4 00 01 01 00 1A EF」という16進数表記の送信データが2進数変換され、マイコン側のレシーブシフトレジスタ(RSR)に1バイトずつ格納された後に、レシーブFIFOデータレジスタ(FRDR)に格納されていくと思いますが、このFRDRから、「AF 06 B4 00 01 01 00 1A EF」としてデータを読み取るためにはどのような操作が必要でしょうか。
16段のFIFOバッファであるFRDRレジスタに保存された時点で、2進数になっていると思いますが、この中から16進数としてデータを取り出す方法が知りたいです。

例えば、MTU0.TCNTでタイマカウンタを読む場合では、16ビット単位のアクセスとなっているので、
data = MTU0.TCNT; (dataは16ビット以上の変数) で読み取り可能と思いますが、似たような方法は可能なのでしょうか。

②送信
同様に、マイコン側から外部機器へ、「AF 05 B1 00 01 00 1A EF」のようなデータ送信を行う場合に、トランスミットFIFOデータレジスタ(FTDR)に上記のデータを書き込むことになりますが、直接上記の16進数データ列を書き込んでよいのでしょうか。
以下にスマートコンフィグレータで作成したSCIF9のソースを記します。

該当のソースコード

C言語

1#include "r_cg_macrodriver.h" 2#include "Config_SCIF9.h" 3/* Start user code for include. Do not edit comment generated here */ 4/* End user code. Do not edit comment generated here */ 5#include "r_cg_userdefine.h" 6 7 8volatile uint8_t * gp_scifa9_tx_address; /* SCIFA9 transmit buffer address */ 9volatile uint16_t g_scifa9_tx_count; /* SCIFA9 transmit data number */ 10volatile uint8_t * gp_scifa9_rx_address; /* SCIFA9 receive buffer address */ 11volatile uint16_t g_scifa9_rx_count; /* SCIFA9 receive data number */ 12volatile uint16_t g_scifa9_rx_length; /* SCIFA9 receive data length */ 13 14void R_Config_SCIF9_Create(void) 15{ 16 volatile uint16_t dummy; 17 uint32_t w_count; 18 19 /* Cancel SCIFA9 module stop state */ 20 MSTP(SCIFA9) = 0U; 21 22 /* Clear transmit/receive enable bits */ 23 SCIFA9.SCR.BIT.TE = 0U; 24 SCIFA9.SCR.BIT.RE = 0U; 25 26 /* Reset transmit/receive FIFO data register operation */ 27 SCIFA9.FCR.BIT.TFRST = 1U; 28 SCIFA9.FCR.BIT.RFRST = 1U; 29 30 /* Read and clear status flags */ 31 dummy = SCIFA9.FSR.WORD; 32 SCIFA9.FSR.WORD = 0x00U; 33 34 dummy = (uint16_t) SCIFA9.LSR.BIT.ORER; 35 SCIFA9.LSR.BIT.ORER = 0U; 36 37 /* Set clock enable bits */ 38 SCIFA9.SCR.WORD = _0000_SCIF_INTERNAL_SCK_UNUSED; 39 40 /* Set transmission/reception format */ 41 SCIFA9.SMR.WORD = _0000_SCIF_CLOCK_PCLK | _0000_SCIF_STOP_1 | _0000_SCIF_PARITY_DISABLE | 42 _0000_SCIF_DATA_LENGTH_8 | _0000_SCIF_ASYNCHRONOUS_MODE; 43 SCIFA9.SEMR.BYTE = _00_SCIF_16_BASE_CLOCK | _00_SCIF_NOISE_FILTER_DISABLE | _00_SCIF_DATA_TRANSFER_LSB_FIRST | 44 _00_SCIF_BAUDRATE_SINGLE; 45 46 /* Clear modulation duty register select */ 47 SCIFA9.SEMR.BIT.MDDRS = 0U; 48 49 /* Set bit rate */ 50 SCIFA9.BRR = 0xC2U; 51 52 /* Wait for at least 1-bit interval */ 53 for (w_count = 0U; w_count <= _000004E0_SCIF_1BIT_INTERVAL; w_count++) 54 { 55 nop(); 56 } 57 58 /* Set FIFO trigger conditions */ 59 SCIFA9.FTCR.WORD = _0000_SCIF_TX_FIFO_TRIGGER_NUM_0 | _0080_SCIF_TX_TRIGGER_TFTC_VALID | 60 _0100_SCIF_RX_FIFO_TRIGGER_NUM_1 | _8000_SCIF_RX_TRIGGER_RFTC_VALID; 61 SCIFA9.FCR.WORD = _0000_SCIF_LOOPBACK_DISABLE | _0000_SCIF_MODEM_CONTROL_DISABLE; 62 63 /* Disable transmit/receive FIFO data register reset operation */ 64 SCIFA9.FCR.BIT.TFRST = 0U; 65 SCIFA9.FCR.BIT.RFRST = 0U; 66 67 /* Set interrupt priority */ 68 IPR(SCIFA9, TXIF9) = _0F_SCIF_PRIORITY_LEVEL15; 69 IPR(SCIFA9, RXIF9) = _0F_SCIF_PRIORITY_LEVEL15; 70 71 /* Set RXD9 pin */ 72 MPC.PB6PFS.BYTE = 0x0AU; 73 PORTB.PMR.BYTE |= 0x40U; 74 75 /* Set TXD9 pin */ 76 MPC.PB7PFS.BYTE = 0x0AU; 77 PORTB.PMR.BYTE |= 0x80U; 78 79 R_Config_SCIF9_Create_UserInit(); 80} 81 82/*********************************************************************************************************************** 83* Function Name: R_Config_SCIF9_Start 84* Description : This function starts the SCIFA9 channel 85* Arguments : None 86* Return Value : None 87***********************************************************************************************************************/ 88 89void R_Config_SCIF9_Start(void) 90{ 91 /* Clear interrupt flag */ 92 IR(SCIFA9,TXIF9) = 0U; 93 IR(SCIFA9,RXIF9) = 0U; 94 95 /* Enable SCIF interrupt */ 96 IEN(SCIFA9,TXIF9) = 1U; 97 ICU.GENAL0.BIT.EN4 = 1U; 98 IEN(SCIFA9,RXIF9) = 1U; 99 ICU.GENAL0.BIT.EN5 = 1U; 100 ICU.GENAL0.BIT.EN6 = 1U; 101 ICU.GENAL0.BIT.EN7 = 1U; 102} 103 104/*********************************************************************************************************************** 105* Function Name: R_Config_SCIF9_Stop 106* Description : This function stop the SCIFA9 channel 107* Arguments : None 108* Return Value : None 109***********************************************************************************************************************/ 110 111void R_Config_SCIF9_Stop(void) 112{ 113 114 /* Disable serial transmit */ 115 SCIFA9.SCR.BIT.TE = 0U; 116 117 /* Disable serial receive */ 118 SCIFA9.SCR.BIT.RE = 0U; 119 120 /* Disable TXI interrupt */ 121 SCIFA9.SCR.BIT.TIE = 0U; 122 123 /* Disable RXI, ERI, BRI and DRI interrupt */ 124 SCIFA9.SCR.BIT.RIE = 0U; 125 IR(SCIFA9,TXIF9) = 0U; 126 IEN(SCIFA9,TXIF9) = 0U; 127 ICU.GENAL0.BIT.EN4 = 0U; 128 IR(SCIFA9,RXIF9) = 0U; 129 IEN(SCIFA9,RXIF9) = 0U; 130 ICU.GENAL0.BIT.EN5 = 0U; 131 ICU.GENAL0.BIT.EN6 = 0U; 132 ICU.GENAL0.BIT.EN7 = 0U; 133} 134 135/*********************************************************************************************************************** 136* Function Name: R_Config_SCIF9_Serial_Receive 137* Description : This function receive SCIFA9 data 138* Arguments : rx_buf - 139* receive buffer pointer (Not used when receive data handled by DTC or DMAC) 140* rx_num - 141* buffer size (Not used when receive data handled by DTC or DMAC) 142* Return Value : status - 143* MD_OK or MD_ARGERROR 144***********************************************************************************************************************/ 145 146MD_STATUS R_Config_SCIF9_Serial_Receive(uint8_t * const rx_buf, uint16_t rx_num) 147{ 148 MD_STATUS status = MD_OK; 149 150 if (rx_num < 1U) 151 { 152 status = MD_ARGERROR; 153 } 154 else 155 { 156 g_scifa9_rx_count = 0U; 157 g_scifa9_rx_length = rx_num; 158 gp_scifa9_rx_address = rx_buf; 159 160 SCIFA9.FTCR.BIT.RFTC = _01_SCIF_RX_TRIG_NUM; 161 162 SCIFA9.SCR.BIT.RE = 1U; 163 SCIFA9.SCR.BIT.RIE = 1U; 164 SCIFA9.SCR.BIT.REIE = 1U; 165 } 166 167 return (status); 168} 169 170/*********************************************************************************************************************** 171* Function Name: R_Config_SCIF9_Serial_Send 172* Description : This function transmits SCIFA9 data 173* Arguments : tx_buf - 174* transfer buffer pointer (Not used when transmit data handled by DTC or DMAC) 175* tx_num - 176* buffer size (Not used when transmit data handled by DTC or DMAC) 177* Return Value : status - 178* MD_OK or MD_ARGERROR 179***********************************************************************************************************************/ 180 181MD_STATUS R_Config_SCIF9_Serial_Send(uint8_t * const tx_buf, uint16_t tx_num) 182{ 183 MD_STATUS status = MD_OK; 184 185 if (tx_num < 1U) 186 { 187 status = MD_ARGERROR; 188 } 189 else 190 { 191 gp_scifa9_tx_address = tx_buf; 192 g_scifa9_tx_count = tx_num; 193 SCIFA9.SCR.BIT.TE = 1U; 194 SCIFA9.SCR.BIT.TIE = 1U; 195 } 196 197 return (status); 198} 199 200/* Start user code for adding. Do not edit comment generated here */ 201/* End user code. Do not edit comment generated here */ 202

試したこと

SCI0を使用しての調歩同期式通信は行えました。これは、頭とお尻に指定した文字列を配置することによる、フレーム同期です。数字は配列から抜き出しています。一方FIFO付きのSCIFAでは8ビットの塊でしか数字を処理できないので、送った16進数の数字がばらばらになるのではと思っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

バイナリデータの1バイト単位でFIFOバッファに貯められます。
それをふつーに1バイト単位で読み込んでいくだけです。
16進数表記とか2進数表記、ってのは、そのバイトデータを文字列に変換するときの表現ってだけの話なので、気にする必要はありません

投稿2023/08/25 07:40

y_waiwai

総合スコア88024

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nyanmage.neko

2023/08/25 08:03

ご回答ありがとうございます。 受信データの「AF 06 B4 00 01 01 00 1A EF」をバイトデータに変換すると、 「AF(1010 1111) 06(0000 0110) B4(1011 0100) 00 01(0000 0001) 01(0000 0001) 001A(0001 1010) EF(1110 1111)」 のような形になるので、確かに1バイトずつ読み込むだけで値は読めそうなのですが、例えば2バイト使うデータ(1000など)の場合は、2バイトまとめて併せて読むなど可能なのでしょうか。
y_waiwai

2023/08/25 11:26

2バイトデータの場合は、1バイトを2つ読んで、そこから2バイトデータを構成します その場合は、最初のバイトが2バイトデータの上位バイトなのか、下位バイトなのかを通信仕様から読み取って、2バイトデータを構成する必要があります
Nyanmage.neko

2023/08/28 01:52

ご回答ありがとうございます。 上位バイトと下位バイトにて2バイトデータとすること理解しました。
guest

0

ベストアンサー

2進数とか16進数とかいう言葉をこのシーンで言い出すのは「間違い」です。その議論の先に理解はありません。
int a;という変数を宣言したとして、a=100;と記述しても、a=0x64;と記述しても、a=0144;と記述しても、a=0b1100100;と記述しても(ルネサスのCは0b表記を受け付けなかったと思いますが)、結果のaは同じ状態になりますし、aに入っているのが「何進数か」という議論は意味を為しません。aが保持しているのは「値」であって、表現ではありませんから。
a=100; //あるいはa=0x64、またa=0b1100100
のあとに
a==100;
a==0x64;
a==0144;
a==0b1100100;
のいずれを評価しても1になります。n進数というのは値の表現方法の問題であって、表現される値そのものは表現方法によらないからです。

なので、1バイト=8ビットのデータを扱いたいのなら、そのデータをchar型に格納したデータとして扱えばよい、それだけです。

あとは、スマートコンフィグレータを使っているのですから、ハードウェアは隠蔽されているので、API関数の使い方だけ分かればよいです。

基本的には、データの受信にはR_Config_SCIF9_Serial_Receive(rx_buf, rx_num)関数を呼び出すのでしょう。このとき、例えばrx_num(要求した受信データバイト数)より受信済のデータバイト数が少なかったときに何が起こるかとかはマニュアルを精読してください。(事前にg_scifa9_rx_countを調べてから必要なデータ数があることを確認して呼ぶのかな、とは思います)

また、UART通信は1バイト単位の通信です。1バイトに満たないデータを気にする必要もありませんが、逆に1バイト以上のグループで構造を持ったデータのフレームのデータが欠落したとき、ノイズで不要なデータが受信されてしまった時の処理は全てプログラムで対応する必要があります。つまり、データを9バイト受信したら"AF ... EF"の9バイトが受信できる期待をしてはいけません。"00 AF..."(余計なデータがつく)だったり”AF ... EF 00"(データが足りない)だったりしたときに、適切な方法でフレームを切り出せる状態に復帰する必要があります。そこはあなたのウデの見せ所、ということになりますね。

投稿2023/08/26 02:35

編集2023/08/26 10:36
thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nyanmage.neko

2023/08/27 22:57

ご回答ありがとうございます。 「2進数とか16進数とかいう言葉をこのシーンで言い出すのは「間違い」です。その議論の先に理解はありません。」、このことは非常に重要で、私自身がうまく咀嚼できていなかったことがはっきりとわかりました。まさにこの内容が、私が理解が進まない原因でした。 また、レジスタの事ばかり気にしていた結果、実際に取得するデータの長さなどを判断する部分をおろそかにしていました。事前にデータの長さなどを取得する関数についての理解を深めておくべきでした。 大変助かりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問