- 12/02 Information!!
- 07/07 【グラブル】バハムートを最終上限解放
- 07/06 【グラブル】光有利の古戦場
- 06/14 【動物園】愛媛県立とべ動物園
- 05/31 【グラブル】開放したシスとエッセルの使用感
This is new entry
4ヶ月ぶりの記事ですね。
もはや自分用のメモの役割になってる記事です。
¥がこのブログでは半角で出せないので全角で記述しています。コピペする際にはご注意を。
あとtabも詰めちゃうようなので、プログラム部分は変な感じになってます(特に{})がご了承を。恐らくシリーズの最初に断ってると思いますが4ヶ月ぶりの記事になるので再度。
-----------------------
さて、前回は1文字、しかもアスキーコードの文字を送りました。
今回は文字列を送りたいと思います。
(ベースの説明が主なので割り込みはまだ使いません)
文字列を送る手順はざっくり言うと、USART_SendData()関数を使って1文字ずつ送るのを繰り返すだけです。
終端文字である¥0をトリガに脱出するループ文を書きます。
void USART_Send_String(USART_TypeDef* USARTx, volatile char *s){
while(*s){
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *s);
*s++;
}
}
こういう関数を作っちゃいます。
でもってメイン関数から
USART_Send_String(USART2, "TEST");
と記述すればUSART2からTESTという文字列が飛び出てきます。
TESTという文字列は*sでアドレスで関数に渡されます。
関数側ではそのアドレスの中身をみて「0」になるまで(終端文字)送信を繰り返します。
もしくは
void USART_Send_String2(USART_TypeDef* USARTx, const int8_t String[]){
uint8_t i =0;
while(String[i] != '¥0'){
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, String[i]);
i++;
}
}
やってることは同じです。
終端文字である¥0を見かけたらループから抜け出すといったものです。
終端文字を文字としてみるかどうかの違いでしかありません。
お好きな方をどうぞ
毎度のことですが関数作った際はextern処理しておきましょう。
ついでなのでGetFlagStatusについて解説します。
これはUSARTに関わるいろんなフラグを確認する関数です。stm32l1xx_usart.cの1263行目にあります。
USART_FLAG_TXEとは送信レジスタが空っぽの場合にSETされて、そうでない場合はRESETが返ってきます。
よって、
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
とは、送信レジスタが空っぽでなければwhileの条件式が真となってループで待機状態になります。空っぽであれば偽になるのでループから抜けて送信を行います。要は前がつかえているかを確認しています。
他にも色々有りますがココでは割愛しますが、この後使うので一つだけ。
USART_FLAG_RXNEは受信レジスタがからっぽならRESET。データが来ている場合にはSETとなります。
さぁ、文字列の送信は出来ましたでしょうか。
ハイパーターミナルなどで確認してみてください。
もはや自分用のメモの役割になってる記事です。
¥がこのブログでは半角で出せないので全角で記述しています。コピペする際にはご注意を。
あとtabも詰めちゃうようなので、プログラム部分は変な感じになってます(特に{})がご了承を。恐らくシリーズの最初に断ってると思いますが4ヶ月ぶりの記事になるので再度。
-----------------------
さて、前回は1文字、しかもアスキーコードの文字を送りました。
今回は文字列を送りたいと思います。
(ベースの説明が主なので割り込みはまだ使いません)
文字列を送る手順はざっくり言うと、USART_SendData()関数を使って1文字ずつ送るのを繰り返すだけです。
終端文字である¥0をトリガに脱出するループ文を書きます。
void USART_Send_String(USART_TypeDef* USARTx, volatile char *s){
while(*s){
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *s);
*s++;
}
}
こういう関数を作っちゃいます。
でもってメイン関数から
USART_Send_String(USART2, "TEST");
と記述すればUSART2からTESTという文字列が飛び出てきます。
TESTという文字列は*sでアドレスで関数に渡されます。
関数側ではそのアドレスの中身をみて「0」になるまで(終端文字)送信を繰り返します。
もしくは
void USART_Send_String2(USART_TypeDef* USARTx, const int8_t String[]){
uint8_t i =0;
while(String[i] != '¥0'){
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, String[i]);
i++;
}
}
やってることは同じです。
終端文字である¥0を見かけたらループから抜け出すといったものです。
終端文字を文字としてみるかどうかの違いでしかありません。
お好きな方をどうぞ
毎度のことですが関数作った際はextern処理しておきましょう。
ついでなのでGetFlagStatusについて解説します。
これはUSARTに関わるいろんなフラグを確認する関数です。stm32l1xx_usart.cの1263行目にあります。
USART_FLAG_TXEとは送信レジスタが空っぽの場合にSETされて、そうでない場合はRESETが返ってきます。
よって、
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
とは、送信レジスタが空っぽでなければwhileの条件式が真となってループで待機状態になります。空っぽであれば偽になるのでループから抜けて送信を行います。要は前がつかえているかを確認しています。
他にも色々有りますがココでは割愛しますが、この後使うので一つだけ。
USART_FLAG_RXNEは受信レジスタがからっぽならRESET。データが来ている場合にはSETとなります。
さぁ、文字列の送信は出来ましたでしょうか。
ハイパーターミナルなどで確認してみてください。
今回はもうひとつ、USARTのデータ受信も解説します。
(これも基本を解説なので割り込みは使いません)
LEDチカチカやった時にループ部分があると思いますのでそこに
USART_Receive(USART2);
という関数を作ってしまいます。
これは自分で作る関数です。
そのまえにpinコンフィグを先に。
GPIO_configurationのなかに
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
を書き足します。
被ってるところは省略可能です。
他のSTM32のチップとは記述が少し異なるのでご注意を。
USART_configurationのほうはいじらないで行けるはずです。
さて、受信の関数ですが
こんなかんじに書きます。
void USART_Receive(USART_TypeDef* USARTx){
if(USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) != RESET){
uint8_t RxData;
RxData = (int8_t)USART_ReceiveData(USART2);
if(RxData == 0x41){
USART_Send_String(USART2, "Receive_Test_TRUE");
}else{
USART_Send_String(USART2, "Receive_Test_FALSE");
}
}
}
手順としては送信の逆バージョンをやってるだけです。
先に解説した受信フラグを確認して、データがなければそのまま処理に入らず抜けてます。
データが有れば受信の関数USART_ReceiveData()を使ってデータを受信します。その際に変数を定義してそこに代入します。
あとはちょっとおまけです。
もし受信したデータがA(アスキーコード0x41)であればさっき作った送信関数を使ってTRUEですよ。と送り返します。それ以外であればFALSEですよ。とおくり返します。
あ、関数作ったらextern処理は忘れずに。ビルドの時に怒られるのでわかると思いますが。
この関数がループに入っているので、繰り返しフラグを見に来ます。そしてデータがあるかないかを確認して再びループで永久に回ってます。
ハイパーターミナルでAという文字を送れば、向こうから反応が帰ってくるはずです。
今回はここまでです。
次回は割り込みでもしてみましょうか・・・。
main.cだけですが、今までのまとめたソースを張っておきます。
---------------------------
#define MAIN_EXTERN
#include "stm32l1xx.h"
#include "main.h"
int main(void)
{
RCC_configuration();
GPIO_configuration();
USART_configuration();
USART_SendData(USART2, 0x41);
USART_Send_String(USART2, "STM32L-Discovery¥r¥n");
USART_Send_String2(USART2, "NOVICE-USARTTEST¥r¥n");
while(1){
LED_blue_toggle();
LED_green_toggle();
USART_Receive(USART2);
}
}
void RCC_configuration(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
}
void GPIO_configuration(void){
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void USART_configuration(void){
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_BaudRate = 19200;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
void LED_blue_toggle(void){
GPIOB->ODR ^= GPIO_Pin_6;
}
void LED_green_toggle(void){
GPIOB->ODR ^= GPIO_Pin_7;
}
void USART_Send_String(USART_TypeDef* USARTx, volatile char *s){
while(*s){
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *s);
*s++;
}
}
void USART_Send_String2(USART_TypeDef* USARTx, const int8_t String[]){
uint8_t i =0;
while(String[i] != '¥0'){
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, String[i]);
i++;
}
}
void USART_Receive(USART_TypeDef* USARTx){
if(USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) != RESET){
uint8_t RxData;
RxData = (int8_t)USART_ReceiveData(USART2);
if(RxData == 0x41){
USART_Send_String(USART2, "Receive_Test_TRUE");
}else{
USART_Send_String(USART2, "Receive_Test_FALSE");
}
}
}
PR
COMMENT
プロフィール
HN:
komyu/シュクレール/修造
性別:
非公開
自己紹介:
こうぶつはけものみみとのーびす(♀)とエリーン
主にROとTERAとラノベと雑多なkomyuの日記帳です。
主にROとTERAとラノベと雑多なkomyuの日記帳です。
TERAキャラ紹介
シュクレール(バサ)
syuzo(エレ)
サケマス(アチャ)
その他サブ
ウリエルキゥィス(スレLv54)
Vermillion(サラLv56)
パズドラ
157,318,362
フレンド募集中
枠なきゃ増やす
最終プレイ3日以上になったら消す
カレンダー
10 | 2024/11 | 12 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
最新記事
(12/02)
(07/07)
(07/06)
(06/14)
(05/31)
ブログ内検索
最新コメント