バックグラウンド
なぜここでシリアル通信を書くかというと、実際のプロジェクトではシリアルポートを使用するため、STM8S003F3P6 のシリアルポートは単純であり、特に言及する必要はありません。この記事で書かれているシリアル ポートは非常に単純です。ここでは簡単なものから始めて、徐々に難しいものを取り上げていきたいと思います。ここで概要を説明しますと、この記事で設計したシリアル ポートは STM8S003F3P6 チップ上のシリアル ポートを使用することになります。STM8S003F3P6 のリソースは限られているため、2 台のマシンの通信リソースでは不足することがよくありますが、次の記事では IO を使用してデータ送受信用のシリアル ポートをシミュレートすることを提案します。
回路図
関連する実際の回路図は次の図に示されています。これは比較的単純です。
STM8S003F3P6のPD5/PD6ピンをシリアルポートトランシーバーに使用します。
STM8S003F3P6の対応マニュアルよりご覧いただけます。
PD5/PD6に対応したシリアルポート1
uart1 (以下の図に示すように)
STM8S003F3P6 シリアル ポートの基本特性、STM8S003F3P6 でサポートされている多くのシリアル ポート機能を示します。
非同期通信シリアルポート、LIN、その他のモード
実際、この記事で使用されているモードは非同期シリアル通信であり、これは最も一般的に使用されている方法でもあります。
ソフトウェア設計
シリアル ポートの初期化操作は比較的簡単で、シリアル ポートを設定し、シリアル ポート割り込みを開くだけです。
ちなみに、ここでのボーレートは 9600 ですが、多くのボーレートは 115200 です。ここで、STM8 の最適なボーレートは 115200 であることに注意してください。ボーレートが高すぎると、データ損失が発生しやすくなります。STM32 デバッグではこの問題は発生しません。
/************************************************
函数名称 : UART_Initializes
功 能 : UART初始化
参 数 : 无
返 回 值 : 无
作 者 :
*************************************************/
void UART_Initializes(void)
{
UART1_Init((uint32_t)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
UART1_Cmd(ENABLE);
//enableInterrupts();
}
メイン周波数構成、ここでは内部 HSI が使用され、メイン周波数は 16M
/************************************************
函数名称 : CLK_Configuration
功 能 : 时钟配置
参 数 : 无
返 回 值 : 无
作 者 :
*************************************************/
void CLK_Configuration(void)
{
/*
ErrorStatus clk_return_status;
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); //HSI = 16M (8分频)=2MHZ
//切换内部低速时钟128khz
clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_LSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
if (clk_return_status == SUCCESS) //SUCCESS or ERROR
{
CLK_ClockSwitchCmd(ENABLE);
CLK_LSICmd(ENABLE);
CLK_ClockSwitchCmd(DISABLE);
}*/
// CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //HSI = 16M (1分频)
//ErrorStatus clk_return_status;
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //HSI = 16M (8分频)=2MHZ
/*
//切换内部低速时钟8M
clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
if (clk_return_status == SUCCESS) //SUCCESS or ERROR
{
CLK_ClockSwitchCmd(ENABLE);
CLK_HSECmd(ENABLE);
CLK_ClockSwitchCmd(DISABLE);
}*/
}
シリアルポート受信割り込み機能
シリアルポート受信割り込み関数では、受信したシリアルポートのバイトを読み取る必要があります。
次のコードはデータをキャッシュに置きます
/**
* @brief UART1 RX Interrupt routine.
* @param None
* @retval None
*/
uint8_t com_in = 0;
uint8_t com_out = 0;
uint8_t com_rv_buf[MAX_COM_RV_BUF];
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
uint8_t tmp,index;
tmp = UART1_ReceiveData8();
index = (com_in + 1) & (MAX_COM_RV_BUF - 1);
if (index != com_out)
{
com_rv_buf[com_in] = tmp;
com_in++;
com_in &= (MAX_COM_RV_BUF - 1);
}
}
シリアルポート送信機能は、最初に1バイトを送信する機能を実現し、次に複数バイトを送信する機能を実現します。
/************************************************
函数名称 : UART1_Printf
功 能 : 串口1打印输出
参 数 : String --- 字符串
返 回 值 : 无
作 者 :
*************************************************/
void UART1_Printf(uint8_t *String)
{
RE485_TX;
while((*String) != '\0')
{
UART1_SendByte(*String);
String++;
}
RE485_RX;
}
/************************************************
函数名称 : UART1_SendByte
功 能 : UART1发送一个字符
参 数 : Data --- 数据
返 回 值 : 无
作 者 :
*************************************************/
void UART1_SendByte(uint8_t Data)
{
while((UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));
UART1_SendData8(Data);
while((UART1_GetFlagStatus(UART1_FLAG_TC)==RESET));
}
概要: この記事で設計されたシリアル ポートは、STM8S003F3P6 チップのシリアル ポートを使用するものです。STM8S003F3P6 のリソースは限られているため、2 台のマシンの通信リソースでは不足することがよくありますが、次の記事では IO を使用してデータ送受信用のシリアル ポートをシミュレートすることを提案します。