welcom ! Handel home

2014年6月17日 星期二

ST32教程(8)


                                         STM32
筆記之八:來跟PC打個招呼,基本串口通訊 

a)        
目的:在基礎實驗成功的基礎上,對串口的調試方法進行實踐。硬體代碼順利完成之後,對日後調試需要用到的printf重定義進行調試,固定在自己的庫函數中。

b)        
初始化函式定義:

void USART_Configuration(void);        //定義串口初始化函數

c)        
初始化函式呼叫: 

void UART_Configuration(void);        //串口初始化函式呼叫

初始化代碼:

void USART_Configuration(void)                        //
串口初始化函數

{

//
串口參數初始化  

  USART_InitTypeDef USART_InitStructure;              //
串口設置恢復默認參數

//
初始化參數設置

  USART_InitStructure.USART_BaudRate = 9600;                                     //
串列傳輸速率9600

   USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //
字長8

  USART_InitStructure.USART_StopBits = USART_StopBits_1;                 //1
位元停止位元組

  USART_InitStructure.USART_Parity = USART_Parity_No;                      //
無同位

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//
無流控制

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//
打開Rx接收和Tx發送功能

    USART_Init(USART1, &USART_InitStructure);                                         //
初始化

  USART_Cmd(USART1, ENABLE);                                                          //
啟動串口

}

RCC
中打開相應串口

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);

GPIO
裡面設定相應串口管腳模式

//
串口1的管腳初始化  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                        //
管腳9

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       //
複用推挽輸出

  GPIO_Init(GPIOA, &GPIO_InitStructure);                               //TX
初始化

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                    //
管腳10

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //
浮空輸入

  GPIO_Init(GPIOA, &GPIO_InitStructure);                             //RX
初始化

d)        
簡單應用:

發送一位元字元

USART_SendData(USART1,
數據);                //發送一位元資料

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}                                                                                        //
等待發送完畢

接收一位元字元

while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}                                                                                        //
等待接收完畢

變數= (USART_ReceiveData(USART1));        //接受一個位元組

發送一個字串

   
先定義字串:char rx_data[250];

      
然後在需要發送的地方添加如下代碼

  int i;                                                                     //
定義迴圈變數

    while(rx_data!='\0')                                           //
迴圈逐字輸出,到結束字'\0'

    {USART_SendData(USART1, rx_data);            //
發送字元

     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //
等待字元發送完畢

     i++;} 

e)        USART
注意事項:

發動和接受都需要配合標誌等待。

只能對一個位元組操作,對字串等大量資料操作需要寫函數

使用串口所需設置:RCC初始化裡面打開RCC_APB2PeriphClockCmd

(RCC_APB2Periph_USARTx);GPIO
裡面管腳設定:串口RX50HzIN_FLOATING);串口TX50HzAF_PP); 

f)        printf
函數重定義(不必理解,調試通過以備後用)

1        需要c標準函數:

#include "stdio.h"

2        粘貼函式定義代碼

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)  //
定義為putchar應用

3        RCC中打開相應串口

4        GPIO裡面設定相應串口管腳模式

6        增加為putchar函數。

int putchar(int c)                                              //putchar
函數

{

  if (c == '\n'){putchar('\r');}                                //
printf\n變成\r

  USART_SendData(USART1, c);                                    //
發送字元

  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //
等待發送結束

  return c;                                                     //
返回值

}

8        通過,試驗成功。printf使用變數輸出:%c字元,%d整數,%f浮點數,%s字串,/n/r為換行。注意:只能用於main.c中。

3
        NVIC串口中斷的應用

a)        
目的:利用前面調通的硬體基礎,和幾個函數的代碼,進行串口的中斷輸入練習。因為在實際應用中,不使用中斷進行的輸入是效率非常低的,這種用法很少見,大部分串口的輸入都離不開中斷。

b)        
初始化函式定義及函式呼叫:不用添加和調用初始化函數,在指定調試位址的時候已經調用過,在那個NVIC_Configuration裡面添加相應開中斷代碼就行了。

c)        
過程:

i.        
在串口初始化中USART_Cmd之前加入中斷設置:

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//TXE
發送中斷,TC傳輸完成中斷,RXNE接收中斷,PE奇偶錯誤中斷,可以是多個。

ii.        RCC
GPIO裡面打開串口相應的基本時鐘、管腳設置

iii.        NVIC
裡面加入串口中斷打開代碼:

NVIC_InitTypeDef NVIC_InitStructure;//
中斷默認參數

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;//
通道設置為串口1中斷

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   //
中斷佔先等級0

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;              //
中斷回應優先順序0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //
打開中斷

NVIC_Init(&NVIC_InitStructure);                                                //
初始化

iv.        
stm32f10x_it.c檔中找到void USART1_IRQHandler函數,在其中添入執行代碼。一般最少三個步驟:先使用if語句判斷是發生那個中斷,然後清除中斷標誌位元,最後給字串賦值,或做其他事情。

void USART1_IRQHandler(void)                              //
串口1中斷

{

char RX_dat;                                                          //
定義字元變數

   

  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //
判斷發生接收中斷

  {USART_ClearITPendingBit(USART1,  USART_IT_RXNE);          //
清除中斷標誌

  

   GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)0x01);             //
開始傳輸

   RX_dat=USART_ReceiveData(USART1) & 0x7F;                       //
接收資料,整理除去前兩位

   USART_SendData(USART1, RX_dat);                                       //
發送資料

   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}//
等待發送結束

  }

}

d)        
中斷注意事項:

可以隨時在程式中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);來關閉中斷回應。

NVIC_InitTypeDef NVIC_InitStructure
定義一定要加在NVIC初始化模組的第一句。

全域變數與函數的定義:在任意.c檔中定義的變數或函數,在其它.c檔中使用extern+定義代碼再次定義就可以直接調用了。


沒有留言: