潘蘇皖,楊凱
(常州信息職業(yè)技術(shù)學(xué)院,江蘇常州,213164)
現(xiàn)如今,智能家電、智能手機(jī)等一系列智能設(shè)備的出現(xiàn)方便了人們的活動(dòng)。尤其是將串口和藍(lán)牙連接,可實(shí)現(xiàn)無(wú)線數(shù)據(jù)之間的信息交流。這樣可以實(shí)現(xiàn)一臺(tái)設(shè)備控制另一臺(tái)設(shè)備。本文通過使用STM32CubeMX[1]軟件,利用串口中斷實(shí)現(xiàn)對(duì)LED的控制。
本文使用低功耗藍(lán)牙開發(fā)板Cannon[2](如圖1),以STM32F401RET6[3]為微控制器。為了清楚地知道LED是否由串口接收到的數(shù)據(jù)控制,因此需要看到數(shù)據(jù)的發(fā)送與接收。由于開發(fā)板沒有USB轉(zhuǎn)TTL模塊,因此需要添加一個(gè)獨(dú)立外接的USB轉(zhuǎn)TTL模塊。而本文使用的是CH340模塊(如圖2)。表1為串口和LED的芯片引腳連接圖。
圖1 Cannon開發(fā)板正面圖
圖2 CH340模塊
表1 芯片串口和LED的芯片引腳連接圖
本文使用STM32CubeMX工具軟件對(duì)串口進(jìn)行基礎(chǔ)配置。在打開的IRA環(huán)境中實(shí)現(xiàn)串口接收的數(shù)據(jù)對(duì)LED控制并發(fā)送信息確認(rèn)是否真確。
打開STM32CubeMx軟件,選擇STM32F401RET6芯片。然后在Pinout&Configuartion->SystemCore,選擇 SYS中Debug的SerialWire進(jìn)行下載配置;在Con nectivity,選擇USART1,在MODE以及Parameter Settings選擇Asynchronous,波特率為115200,字長(zhǎng)為8位,無(wú)奇偶校驗(yàn)位,Date Direction為Receive and Tran smit模式并選擇NVIC Settings中斷使能實(shí)現(xiàn)串口串口模式以及中斷配置;在NVIC中對(duì)中斷優(yōu)先級(jí)進(jìn)行配置;在Pin out view下,選擇PB3引腳為GPIO_Output模式,在SystemCore下選擇GPIO進(jìn)行初始化,將GPIO Output level下設(shè)置為高電平,其他為默認(rèn),GPIO配置如圖3所示。
圖3
最終引腳的效果圖如圖4所示。
選擇EWSRM工具,生成工程文件。打開工程文件。
由于數(shù)據(jù)寄存器每次只能接收和發(fā)送9位,而一個(gè)字符為8位,因此串口每次接收和發(fā)送一個(gè)字符。但是在現(xiàn)實(shí)生活中正常情況是發(fā)送一串字符來(lái)進(jìn)行設(shè)備的控制。因此在這里本文不使用STM32中HAL庫(kù)中的封裝函數(shù)。
這里需要設(shè)置一個(gè)flag標(biāo)志,1為數(shù)據(jù)接收完畢,0為數(shù)據(jù)未接收或者是接收完畢。并且flag為哪種標(biāo)志值時(shí)還要判斷。本文使用' '為判斷flag標(biāo)志。在接收過程中,將每次接收到的一個(gè)字符放入數(shù)組SBUF_RX中,直到' '出現(xiàn),將flag置1,并關(guān)閉接收中斷使能。在flag=1下,進(jìn)行對(duì)接收到的字符串進(jìn)行判斷,然后對(duì)LED進(jìn)行控制,最后再次打開串口中斷使能。步驟如下:
圖4 芯片串口配置完成圖
(1)進(jìn)入中斷,判斷是否為接收中斷;
(2)接收字符,將字符放入SUBF_RX數(shù)組中;
(3)判斷是否為' '標(biāo)志,是則置1,否則不執(zhí)行;
(4)計(jì)數(shù)接收到字符的個(gè)數(shù);
(5)如果flag=1,判斷接收到的數(shù)據(jù)是否為L(zhǎng)ED控制;
(6)發(fā)送數(shù)據(jù),回應(yīng)是否控制LED。
(1)在main.c中設(shè)置全局變量:
uint16_t USART_RX_STA = 0 ;
uint8_t SBUF_RX[0x3FFF];
uint8_t flag = 0;
(2)在主函數(shù)里添加中斷使能:
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);
(3)將stm32f1xx_it.c文 件 中void USART1_IRQHandler(void)放入main.c文件下,在中斷函數(shù)中實(shí)現(xiàn)代碼如下:
uint8_t ch ;
if(__HAL_UART_GET_FLAG( &huart1,UART_FLAG_RXNE ) != RESET)
{
ch=( uint16_t)READ_REG(huart1.Instance->DR);
SBUF_RX[RX_COUNT&0X3FFF]=ch;//接收到的字符保存在 USART_RX_BUF 數(shù)組中
if(SBUF_RX[RX_COUNT]== 0X0A && SBUF_RX[RX_COUNT-1]== 0X0D)//判斷是否為' '
{
fl ag = 1; //置1
__HAL_UART_DISABLE_IT(&huart1,UART_IT_RXNE);//關(guān)閉接收中斷
}
RX_COUNT++; //計(jì)數(shù)接收到的字符的個(gè)數(shù)
}
(4)在main.c 里while(1)中實(shí)現(xiàn)代碼如下:
if(flag) //如果flag為1
{
flag = 0;//flag為0
if(StrCompare(SBUF_RX,“openL1”,RX_COUNT))//判斷接收字符是否為打開LED
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //打開LED
HAL_UART_Transmit(&huart1,"L1 open",8,1000);//發(fā)送字符,查詢方式
}
if(StrCompare(SBUF_RX,“closeL1”,RX_COUNT))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET);//關(guān)閉LED
HAL_UART_Transmit(&huart1,"L1 close",9,1000);//發(fā)送字符,查詢方式
}
HAL_UART_Transmit(&huart1,"USART1 ok",10,1000);//發(fā)送字符,查詢方式
for(uint16_t i = 0; i { SBUF_RX[i]= 0; } RX_COUNT = 0; //計(jì)數(shù)為0 __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//打開接收中斷 } StrCompare為字符串比較,用來(lái)判斷接收到的字符是否和自己指定的字符相等,不相同返回0,相同返回1。代碼如下: uint8_t StrCompare(uint8_t *t,uint8_t *s,uint8_t m) { uint8_t i; for(i = 0 ; i < m-2 ; i++) { if(t[i]!=s[i]) return 0; } return 1; } 將程序下載開發(fā)板中,CH340模塊與開發(fā)板相連插入電腦。打開串口助手。當(dāng)發(fā)送“openL1
”時(shí),開發(fā)板L1燈將會(huì)點(diǎn)亮,開發(fā)板這時(shí)會(huì)發(fā)送數(shù)據(jù)到串口助手提示已點(diǎn)亮L1燈;當(dāng)發(fā)送“closeL1
”時(shí),開發(fā)板L1將會(huì)關(guān)閉,開發(fā)板會(huì)發(fā)送數(shù)據(jù)到串口助手提示已熄滅L1燈。如圖5所示,為串口助手運(yùn)行的結(jié)果。 通過實(shí)現(xiàn)串口對(duì)設(shè)備的控制,對(duì)STM32F4的串口有了進(jìn)一步了解。實(shí)現(xiàn)字符串的串口接收和發(fā)送,需要對(duì)指針、數(shù)組、字符串等知識(shí)的靈活運(yùn)用。而采用STM32CubeMX工具軟件,則加速了實(shí)現(xiàn)項(xiàng)目的工作效率。 圖5 串口調(diào)試結(jié)果■2.4 運(yùn)行程序
3 結(jié)論