-
PC ではシリアル ポートは徐々に消えつつありますが、組み込み分野では、表示画面や入力デバイスのないシステムでは、シリアル ポートが低コストでプログラムに便利であるため、依然として人気があると言えます。 . ハイパーターミナルと合わせて、情報の表示と入力の問題を解決するために不可欠です。
数日間の苦労の末、Cortex-M3 プラットフォーム上での .Net Micro Framework の NativeSample 移植作業は、現在、スタートアップ コード、SRAM、クロック (RCC)、割り込み (NVIC)、SysTick、 GPIO、シリアルポート、NandFlash (FMSC) およびその他の関連機能、これらのコードは TinyClr を正常に動作させるための最低限のセットと言えます。これらを基盤として、TinyClr を移植することができます。私たちが使用している M3 開発ボードには 2M を超える RAM が搭載されており、この時点で作業は 90% 完了している可能性がありますが、リソースが限られているため、デバッグの次のステップは Flash バージョンでなければならず、未知の作業がたくさんあることになります。しかし、正直に言うと、これらのタスクをゼロから完了するのは難しいですが、ARM 開発 (特に Cortex-M3) についてはやりがいがあります。新しいレベルに改善されました。
さて、シリアルポートドライバーの開発について話しましょう。
GPIO 開発と同様に、シリアル ポート関連のレジスタ コードを CortexM3.h に記述する必要があります。
構造体 CortexM3_Usart
{
静的 const UINT32 c_MAX_BAUDRATE = 45000000;
静的const UINT32 c_MIN_BAUDRATE = 1200;
静的 const UINT32 c_Base1 = 0x40013800;
静的const UINT32 c_Base2 = 0x40004400;
静的const UINT32 c_Base3 = 0x40004800;
/****/ 揮発性 UINT16 SR;
static const UINT16 SR_TXE=((UINT16)0x0080);
static const UINT16 SR_TC=((UINT16)0x0040);
static const UINT16 SR_RXNE=((UINT16)0x0020);
UINT16 予約0;
/****/ 揮発性 UINT16 DR;
UINT16 予約済み 1;
/****/ 揮発性 UINT16 BRR;
UINT16 予約済み 2;
/****/ 揮発性 UINT16 CR1;
static const UINT16 CR1_UE_Set = ((UINT16)0x2000);
static const UINT16 CR1_UE_Reset = ((UINT16)0xDFFF);
static const UINT16 CR1_Parity_No = ((UINT16)0x0000);
static const UINT16 CR1_Parity_Even = ((UINT16)0x0400);
static const UINT16 CR1_Parity_Odd = ((UINT16)0x0600);
static const UINT16 CR1_DataBit_8 = ((UINT16)0x0000);
static const UINT16 CR1_DataBit_9 = ((UINT16)0x1000);
static const UINT16 CR1_Mode_Rx = ((UINT16)0x0004);
static const UINT16 CR1_Mode_Tx = ((UINT16)0x0008);
static const UINT16 CR1_CLEAR_Mask = ((UINT16)0xE9F3);
static const UINT16 CR1_PEIE = ((UINT16)0x0100);
static const UINT16 CR1_TXEIE = ((UINT16)0x0080);
static const UINT16 CR1_TCIE = ((UINT16)0x0040);
static const UINT16 CR1_RXNEIE = ((UINT16)0x0020);
UINT16 予約済み 3;
/****/ 揮発性 UINT16 CR2;
static const UINT16 CR2_StopBits_1 = ((UINT16)0x0000);
static const UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);
static const UINT16 CR2_StopBits_2 = ((UINT16)0x2000);
static const UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);
static const UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF); /* USART CR2 STOP ビット マスク */
UINT16 予約済み4;
/****/ 揮発性 UINT16 CR3;
static const UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000);
static const UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100);
static const UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200);
static const UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300);
static const UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF);
UINT16 予約済み5;
/****/ 揮発性 UINT16 GTPR;
UINT16 予約6;
};
上記のコードを使用すると、シリアル ポート レジスタを簡単に操作できます。
シリアル ポートの初期化には、次の初期化作業が必要です (STM3210E 開発ボードには 3 つのシリアル ポートがあります。例としてシリアル ポート 1 を取り上げます)。
1. シリアルポートクロックをオンにします
UsartId = CortexM3_NVIC::c_IRQ_Index_USART1;
RCC.APB2ENR |= CortexM3_RCC::APB2_GPIOA | CortexM3_RCC::APB2_USART1;
2. 起動割り込み
if(!CPU_INTC_ActivateInterruptEx( UsartId, (UINT32)(void *)USART1_IRQHandler)) FALSE を返します。
3. ボーレート、パリティ、データビット、ストップビットなどのシリアルポートパラメータを設定します。
わずかに
4. GPIO の再定義
CPU_GPIO_DisablePin(GPIO_Driver::PA9,RESISTOR_DISABLED,FALSE,GPIO_ALT_MODE_1);
CPU_GPIO_DisablePin(GPIO_Driver::PA10,RESISTOR_DISABLED,TRUE,GPIO_ALT_MODE_2);
5. シリアルポートの有効化
Usart.CR1 |= CortexM3_Usart::CR1_UE_Set;
割り込み関数でデータの送受信を完了します。
void CortexM3_USART_Driver::ISR( void* param )
{
UINT32 comPort = (UINT32)param;
CortexM3_Usart &Usart=CortexM3::Usart(comPort);
文字c;
UINT32 ステータス。
ステータス = Usart.SR;
if(ステータス & CortexM3_Usart::SR_RXNE)
{
c = Usart.DR;
USART_AddCharToRxBuffer( comPort, c );
Events_Set( SYSTEM_EVENT_FLAG_COM_IN );
}
if(ステータス & CortexM3_Usart::SR_TC)
{
if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))
{
戻る;
}
if(USART_RemoveCharFromTxBuffer( comPort, c ))
{
WriteCharToTxBuffer( comPort, c );
}
それ以外
{
// レベルトリガーなので、それ以上の Tx 割り込みを無効にします
TxBufferEmptyInterruptEnable(comPort, FALSE);
}
Events_Set( SYSTEM_EVENT_FLAG_COM_OUT );
}
}
コア コードは、上で紹介した関連コンテンツです。以下に、NativeSample でシリアル ポート テスト コードを記述します。
void ApplicationEntryPoint()
{
その間(TRUE)
{
if(Events_WaitForEvents(SYSTEM_EVENT_FLAG_COM_IN,100))
{
イベント_クリア(SYSTEM_EVENT_FLAG_COM_IN);
文字 bytData[512];
int サイズ=USART_BytesInBuffer(0,TRUE);
USART_Read(0,bytData,Size);
for(int i=0;i<サイズ;i++)
debug_printf("%c",bytData[i]);
}
debug_printf("こんにちは、Micro Framework!!!rn");
}
}