1. 程式人生 > >STM32F407ZET6 用串列埠通過鍵盤控制LED燈的亮滅

STM32F407ZET6 用串列埠通過鍵盤控制LED燈的亮滅

1、串列埠定義

    串列埠通訊是一種裝置間非常常用序列通訊(資料互動)方式,因為它比較簡單便捷,大部分電子裝置支援串列埠通訊方式,電子工工程師除錯裝置時常用的介面

序列通訊:佔用I/O較少,速度上較慢點
並行通訊:佔用I/O較多,速度上快速

2、常見通訊方式

1) 單工
單工通訊資料只能往一個方向發向(收音機)

2) 半雙工
同一時間內只能傳輸或者傳送資料(呼叫機)

3) 全雙工(串列埠)
   同一時間內資料可以傳送及接收(電話機)

3、使用串列埠通訊配置庫函式流程

1) 串列埠時鐘使能,GPIO 時鐘使能。

2) 設定引腳複用器對映:呼叫 GPIO_PinAFConfig 函式。

3) GPIO 初始化設定:要設定模式為複用功能。

4) 串列埠引數初始化:設定波特率,字長,奇偶校驗等引數。

5) 開啟中斷並且初始化 NVIC,使能中斷(如果需要開啟串列埠中斷才需要這個步驟)。

6) 使能串列埠。

7) 編寫中斷處理函式:函式名格式為 USARTx_IRQHandler(x 對應串列埠號)。

4、具體部分程式碼和詳細註解

相關說明:1) 這裡用到的串列埠是:PA9(USART1 TX)和PA10(USART RX)
            控制的led燈是:PE13、PE14、PF9、PF10,其中,低電平時,燈亮。
            用到的按鍵是 PA0,並且按下的時候為低電平

        2) 在相關函式中用到了  PFout(9) = 1;  PFout(10) = 1; PAin(0) == 0; 
            這些型別的語句,這是進行過相關的巨集定義的,所以,如果沒有定義,就不能隨便用這些語句,以免出錯。
            可以用 GPIO_SetBits(GPIOF, GPIO_Pin_9);
                  GPIO_SetBits(GPIOF, GPIO_Pin_10);
                  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);  代替上面三句
void usart_init()   //usart 初始化配置相關內容
{
    //首先定義幾個需要用到的結構體
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef  USART_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
    //時鐘的初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    //GPIO口初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //UART1 TX RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //複用功能 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); //設定引腳複用對映 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //進行UART的相關配置 USART_InitStruct.USART_BaudRate = 9600; //波特率 USART_InitStruct.USART_WordLength = USART_WordLength_8b; //資料位 USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位 USART_InitStruct.USART_Parity = USART_Parity_No; //奇偶校驗位 USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //模式 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬體控制流 USART_Init(USART1,&USART_InitStruct); //使能中斷 USART_ITConfig(USART1,USART_IT_RXNE, ENABLE); //配置UART相關中斷 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //搶佔式和響應式的優先順序分組設定 NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2; //搶佔式優先順序 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; //響應式優先順序 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); //使能USART1 USART_Cmd(USART1,ENABLE); } //USART1 中斷函式 void USART1_IRQHandler() { u16 Res; if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET) //判斷是否接收到資料 { USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中斷標誌位,防止重複進入中斷 Res =USART_ReceiveData(USART1); //將接受的資料傳給Res switch(Res) { case 1 : PFout(9) = 1; PFout(10) = 1; PEout(13) = 1; PEout(14) = 1; break; case 2 : PFout(9) = 0; PFout(10) = 0; PEout(13) = 0; PEout(14) = 0; break; default : break; } } USART_SendData(USART1, Res); //每次將接收到的資料再發送回去 } int main() { int i; char a[15]="hello world\r\n"; LED_Init(); usart_init(); while(1) { //這裡是主函式檢測一個按鍵有無按下,若有按下,則傳送一串字元過去 if(PAin(0) == 0) { delay(2); //消抖 if(PAin(0) == 0) { for(i=0;i<20;i++) { //每次傳送一個位元組 USART_SendData(USART1, a[i]); //每次等待一個數據傳送完成,再發下一個 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); } } } } }

5、結果和現象顯示

1) 每當按下一次 PA0 按鍵,串列埠助手就會接收到傳送過來的資料 "hello world" 如下圖所示

1

2) 在串列埠助手的傳送區傳送 2 時,四個LED亮了 如下圖所示

2

並且與此同時,2 也在串列埠助手中顯示出來了

3

3) 在串列埠助手的傳送區傳送 1 時,四個LED滅了,如下圖所示

4

並且與此同時,1 也在串列埠助手中顯示出來了

5

至此,串列埠測試完畢。 希望對你有所幫助!