ashwatermelon

ashwatermelon

【学習ノート】stm32マイコンUSARTシリアルポート

最近学んだ STM32 のシリアル通信。
シリアルポートは以前 51 を学んだときに使ったことがありますが、ほとんど忘れてしまいました(悲)。
それでは、シリアル通信の復習を始めましょう。

(一)USART とは何か#

シリアルポートは非常に広く使用されている通信インターフェースで、コストが低く、使いやすく、通信回線がシンプルで、2 つのデバイス間の相互通信を実現できます。
マイコンのシリアルポートは、マイコン同士、マイコンとコンピュータ、マイコンとさまざまなモジュール間の通信を可能にし、マイコンの応用範囲を大幅に拡大し、マイコンシステムのハードウェア能力を強化します。
その通信方式は非同期フルデュプレックスで、非同期とは通信の両者間にクロック線が接続されておらず、あらかじめボーレート(伝送周波数)を設定する必要があることを指します;フルデュプレックスとは、通信の両者が信号を送受信でき、互いに干渉しないことを指します。
USART のシリアル通信には 2 本の線があります。1 本は TXD で、信号を送信するために使用されます;もう 1 本は RXD で、信号を受信するために使用されます。双方の TXD は相手の RXD に交差接続されます。(画像がなぜかアップロードできませんでした、まあいいでしょう)
USART が送信する完全な情報には、スタートビット、データビット、パリティビット、ストップビットが含まれます。その中で、データビットとパリティビットは合計で 8 または 9 ビットで、パリティビットは 1 ビットだけです。ストップビットの長さを変更することで送信周波数を変更できますが、一般的には 8 ビット無パリティまたは 9 ビットパリティを選択し、ストップビットの長さは 1 ビットで十分です。

(二)コード設定#

STM32 のライブラリ関数には専用の USART 関数があるため、設定プロセスは 51 よりも簡単です。
コードは以下の通りです:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure);

USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate=9600; USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&USART_InitStructure);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_Init(&NVIC_InitStructure);

USART_Cmd(USART1,ENABLE);
私たちは、クロックを有効にしてピンを初期化した後、USART_Init を使用して USART を初期化(ボーレート 9600、8 ビット無パリティ)し、その後 USART_ITConfig を使用して割り込みを有効にし、最後に NVIC を設定してシリアルポートを起動すればよいのです。

(三)信号の送信と受信#

信号を送信するのは非常に簡単で、USART_SendData 関数を使用するだけです:
void Serial_SendByte(uint8_t Data)
{
USART_SendData(USART1,Data);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

この基本の上に、文字列を送信する関数や数字を送信する関数をラップすることもできます。例えば、以下の文字列を送信する関数:
void Serial_SendString(uint8_t*Data)
{
int j = 0;
for(j=0;Data[j]!='\0';j++)
{
Serial_SendByte(Data[j]);
}
}

データを受信するには割り込みを使用する必要があります。コードは以下の通りです:
void USART1_IRQHandler()
{
while(USART_GetITStatus(USART1,USART_IT_RXNE)==RESET);
SerialRXFlag=1;
SerialRXData=USART_ReceiveData(USART1);
}

(四)シリアルポートのデータパケットの送受信#

実際には、シリアルポートが特定の形式の内容を送受信することを意味します。例えば、データパケットのヘッダーは 0xFF、パケットの末尾は 0xFE で、コードは大体以下の通りです:
void Serial_Sendpacket()
{
Serial_SendByte(0xFF);
Serial_SendArray(SerialTXPacket,4);
Serial_SendByte(0xFE);
}

void USART1_IRQHandler()
{
static int pRXPacket = 0;
static uint8_t RxState = 0;
while(USART_GetITStatus(USART1,USART_IT_RXNE)==RESET);
uint8_t RXData = 0;
RXData = USART_ReceiveData(USART1);
switch (RxState)
{
case 0:
if (RXData == 0xFF)
{
RxState = 1;
pRXPacket = 0;
}
break;
case 1:
SerialRXPacket[pRXPacket] = RXData;
pRXPacket++;
if (pRXPacket >= 4)
{
RxState = 2;
}
break;
case 2:
if (RXData == 0xFE)
{
RxState = 0;
SerialRXFlag=1;
}
break;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}

USART の内容は大体これくらいです。それほど複雑ではありません。なぜなら、関数ライブラリが私たちが本来設定する必要があった多くのことをすでに行ってくれているからです。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。