|
準備材料:
- Stm32f103開發(fā)板
- Jlink調(diào)試器一個
- 配套原理圖
相信無論哪本書都會將串口通信知識點放在書籍的最開始的前幾章,可見, 串口通信在單片機中的重要性,程序運行的時候,我們不但可以通過點亮led的方式,來調(diào)試程序。 同時也可以通過串口通信的方式來向串口調(diào)試助手中打印相關(guān)變量信息,顯示在計算機上, 但從這點上,串口通信的作用就可想而知了。
在串口通信中,我們要明白幾個參數(shù), 字長(一次傳輸?shù)臄?shù)據(jù)長度), 波特率(每秒傳輸?shù)臄?shù)據(jù)位數(shù)), 奇偶校驗位, 還有停止位,這些參數(shù)都在ST的官方提供的串口庫中的USART_InitTypeDef的結(jié)構(gòu)體中含有。
接下來我們還要介紹下串口的接口的標示圖,

從圖上可以看到,他一共有九個針口, 其中RX TX GND就是在串口通信中其主要作用。在多機串口通信中,要注意連線RX-TX,
TX-RX, GND-GND,
關(guān)鍵代碼如下:
- Int Main
- {
- uint8_t a=0;
- RCC_Configuration(); //初始化外設(shè)時鐘
- GPIO_Configuration(); // 初始化GPIO
- USART_Config(USART1); // 初始化USART1
- NVIC_Configuration(); //配置中斷管理器
- while (1)
- {
- if(rec_f==1){
- rec_f=0;
- USART_OUT(USART1,"你發(fā)送的信息: \r\n");
- USART_OUT(USART1,&TxBuffer1[0]);
- if(a==0) {GPIO_SetBits(GPIOB, GPIO_Pin_5); a=1;}
- else {GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=0; }
- }
- Return 0;
- }
- /****************************************************************************
- ****************************************************************************/
- void RCC_Configuration(void)
- {
- SystemInit();
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
- | RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO , ENABLE);
- }
- ****************************************************************************/
- void GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructrue; //GPIO 初始化TX TX 對應的pin腳
- GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructrue);
- GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructrue);
- }
- /****************************************************************************
- ****************************************************************************/
- void NVIC_Configuration(void) //配置中斷管理器 優(yōu)先級組, 搶占優(yōu)先級, 相應優(yōu)先級
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- void USART_Config(USART_TypeDef* USARTx){ // 初始化串口1 波特率, 數(shù)組長度, 停止位,校驗位, 硬件控制流
- USART_InitTypeDef USART_InitStructrue;
- USART_InitStructrue.USART_BaudRate = 115200;
- USART_InitStructrue.USART_WordLength = USART_WordLength_8b;
- USART_InitStructrue.USART_StopBits = USART_StopBits_1;
- USART_InitStructrue.USART_Parity = USART_Parity_No;
- USART_InitStructrue.USART_HardwareFlowControl USART_HardwareFlowControl_None;
- USART_InitStructrue.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART1, &USART_InitStructrue);
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能接收中斷
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //使能發(fā)送中斷
- USART_Cmd(USART1, ENABLE);
- }
- /**********************************************************************/
- void USART1_IRQHandler(void)
- {
- unsigned int i;
- if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //確定接收中斷
- {
- RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);
- if(RxBuffer1[RxCounter1-2]==0x0d&&RxBuffer1[RxCounter1-1]==0x0a)
- {
- for(i=0; i< RxCounter1; i++) TxBuffer1[i]= RxBuffer1[i];
- rec_f=1;
- TxBuffer1[RxCounter1]=0;
- RxCounter1=0;
- }
- }
- if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) //排除發(fā)送中斷
- {
- USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
- }
- }
復制代碼
程序分析, 依舊是從main函數(shù)開始執(zhí)行, RCC_Configuration初始化各個外設(shè)時鐘,具體是GPIOB與USART1這兩個外設(shè)。接著是具體配置GPIO口。 應為串口通信中,必須要用的兩根數(shù)據(jù)線TX RX 電路圖如圖:
232.jpg (23.44 KB, 下載次數(shù): 117)
下載附件
2015-7-9 01:13 上傳
從圖中可以看到,RX對應的PA9, TX對應的是PA10, 分別給這兩個Pin腳配置相關(guān)參數(shù)。程序繼續(xù)執(zhí)行USART_config函數(shù),該函數(shù)就是具體配置串口通信的相關(guān)參數(shù)了。 波特率,數(shù)據(jù)長度等等...
繼續(xù)執(zhí)行NVIC_config函數(shù),這里看到了一個陌生的結(jié)構(gòu)體變量 NVIC_InitTypeDef,
簡單說的NVIC就是控制stm32所有的中斷的管理器。進入函數(shù)里面,設(shè)置中斷通道USART1_IRQn, 這里我們可以參考這張中斷向量表:
%E9%80%9A%E9%81%93.jpg (65.1 KB, 下載次數(shù): 143)
下載附件
2015-7-9 01:13 上傳
接下來本別分支搶占優(yōu)先級,以及響應優(yōu)先級。接下來,還要注意中斷函數(shù)USART1_IRQHandler, 進入該函數(shù)有兩種可能, 發(fā)送和接收到結(jié)束位,都有可能引發(fā)中斷,因此我們在進入中斷時候,要判斷下到到底是接收中斷,還是發(fā)送中斷。由于本實驗的目的只想讓接收數(shù)據(jù)產(chǎn)生中斷,故USART_ITConfig(USART1, USART_IT_TXE, DISABLE);就是關(guān)閉發(fā)送中斷。
最后來看下,產(chǎn)生中斷的原理,先看下串口架構(gòu)圖:
QQ%E5%9B%BE%E7%89%8720141124235358.jpg (44.78 KB, 下載次數(shù): 137)
下載附件
2015-7-9 01:13 上傳
數(shù)據(jù)在傳輸過程中,以發(fā)送為例, 內(nèi)核首先把數(shù)據(jù)通過cpu或者dna(數(shù)據(jù)傳輸?shù)囊环N方式) 寫入到發(fā)送數(shù)據(jù)的寄存器TDR中,接著,在適當時候把數(shù)據(jù)加載到發(fā)送移位寄存器中, 在發(fā)送到結(jié)束符時, 會讓圖中的TXE被置起,這時,就會引發(fā)一個中斷。
實驗現(xiàn)象:
串口助手打印出“ 你發(fā)送的信息為:xxxx ”
|
|