久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> STM32 >> 瀏覽文章

STM32學習之串口的使用

作者:忙碌的小姚   來源:忙碌的小姚   點擊數:  更新時間:2014年06月10日   【字體:

 

串口的使用

1、為什么要用串口?

     自上一篇寫的時間是1月20號,今6月7號了,半年沒更新了。

這半年發生了什么?過完年就去找公司實習,在那里自我感覺進步很大。其實在公司大多都是自學,師傅基本不會給你說什么。但這并不能說明你的師傅對你不好,帶我的那個師傅只比我高一屆,但他的水平比我高的好多屆。他也是自學,也沒人告訴他該怎么做,因為老板也不太懂。所以自學能力很重要,當然有人帶你的話,這樣會更好。

      不說這些了,串口在調試的時候作用非常大。也學我們在學51的時候,只是將程序下載到開發板,看看是否能運行起來,通過數碼管將結果顯示出來,從而就知道程序設計的正確性。以前我也是這樣做的,沒什么不好。

在公司實習的時候,他們調試都是使用串口打印輸出信息,觀察程序從上電、初始化、運行數據什么的全部都顯示到PC機上。然后再一句一句分析它的打印信息,從而找到出錯的源頭。這使我對串口的認識有更深了一步,所以我決定在學習STM32的時候,開發流程跟在公司學的方法一樣——使用串口,觀察打印信息。

2、STM32跟PC機(也就是電腦)如何連接

       我的STM32F103C8T6只是裸板,沒有串口芯片,當然用的也是學生機——筆記本電腦,同樣也沒串口。

解決辦法1、買一塊 MAX3232轉接板+一條USB轉串口線 +郵費=30塊左右

              2、只需要買一塊PL2303的USB轉接板。這樣就將第一種的轉接板和連接結合到一起了。

不過我用的是第一種,MAX3232+USB的串口線  ,為什么不用方便的2種?

max3232對于沒有串口的開發板可以充當電平轉換芯片,如何開發板有了電平轉換芯片,我便使用USB轉串口線經行連接,這樣便靈活了。第二種只是用在既沒轉換芯片也沒USB轉串口的情況,不過對于最小系統板來說,它既可以下載程序,又可以當做串口來調試。至于臺式機就不需要USB轉串口線了,普通串口線即可。

                連接示意如下所示:

3、代碼分析

       再寫這里之前,應該已經學過模塊化編程了,STM32的每個XXX.c 和xxx.h 這都是模塊化編程。良好的程序,與其好的代碼風格有關。你的代碼風格跟你接觸教你寫代碼的有很大關系。以前剛剛學習單片機編程,我還不信,現在我承認,跟教我單片機的老師風格有些像。

 

       這里我做的是一個串口發送數據到PC機的例子:

       要讓STM32能夠順利發出數據,要進行如下配置

PA9,PA10管腳要配置,   USART也需要配置波特率,數據有幾位,停止位,數據流等。

USART和uart有什么區別   USART在做串口時,兩者并不區別,但是USART有SPI的功能。還有串口通信為什么要配置波特率,停止位,硬件數據留這些,以前我也沒想過,現在只覺得協議這個東西,是一個好的標準。

        建立一個usart_debug.c的文本,內容如下

#include"usart_debug.h"

void GPIO_Configuration(void)

{

GPIO_InitTypeDef  GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能UASRT的時鐘

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA的時鐘,開始的時候,我沒用這句話,調了兩天,跟源碼一句一句比才知道

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; //波特率較高,IO翻轉需較高頻率

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出;我看網上有人說設置成GPIO_Mode_Out_PP普通推挽輸出也行,但實踐出真知,我試了發送是亂碼。;

GPIO_Init(GPIOA,&GPIO_InitStructure);

 

GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //配置成浮空輸入,既然是輸入所以就不用配置IO口的頻率了

GPIO_Init(GPIOA,&GPIO_InitStructure);

}

 

void USART1_config(void)

{

USART_InitTypeDef     USART_InitStructure;

USART_InitStructure.USART_BaudRate= 115200;     //配置波特率

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //配置數據位

USART_InitStructure.USART_StopBits = USART_StopBits_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;

USART_Init(USART1, &USART_InitStructure);

 

USART_Cmd(USART1, ENABLE);

}

//這段很重要,如果要使用printf函數打印信息,需要加fputc函數,就需要對printf函數重定向到串口,以前工作中他們老是提重定向,什么串口重定向,USB重定向什么的,我也是云里霧里,如今給我的感覺就是將上層函數實現對底層硬件的操作

int  fputc(int ch,  FILE*f){

while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET); //網上的一些函數里面是沒有這一句代碼,如果不加的話,打印時第一個字符就會沒有,原因據說是硬件復位后,USART_FLAG_TC被置一了,而要發送數據必須讓其為底才可以,一表示數據發送發出的標志,也可以用這樣一句USART_ClearFlag(USART2,USART_FLAG_TC);清楚標準位?墒俏覜]這樣做一樣發成功了,這個疑惑以后再想明白。

USART_SendData(USART1, (uint16_t)ch);

 

while(USART_GetFlagStatus(USART1, USART_FLAG_TC) !=SET);

return ch;

 

}

void usart_debug_config(void)  //提供給main函數調用的串口配置函數

{

GPIO_Configuration(); //IO口配置

USART1_config();   //串口配置

}

 

 

還就是usart_debug.h

#ifndef __usart_debug_H

#define    __usart_debug_H

 

#include "stm32f10x.h"

#include

 

void usart_debug_config(void);

int fputc(int ch, FILE *f);

 

 

#endif // __USART1_H

 

 

 

 

 

       main函數:

這里使用兩種方式一種是 使用普通的方式發送,另一種使用printf函數

其實還有一種USART_printf函數來實現,這里不做介紹。有空看看區別一下printf和usart_printf,據說是支持格式多少的問題

 

#include"stm32f10x.h"

#include"usart_debug.h" //包含main函數里的調用函數

int main(void)

{

 

unsigned char TxBuf1[100] ={"發送字符串。!\r\n"};

int  i;

SystemInit();

usart_debug_config();

for( i = 0; TxBuf1[i] != '\0'; i++)

{

while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);//這里跟分析fputc時是一樣的

USART_SendData(USART1 , TxBuf1[i]);//發送字符數組里的單個字符

while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);

}

 

printf("hello world!  世界你好! \r\n"); //調用printf函數

while(1)

{

;

}

 

}

 

 

仿真及調試

程序編好之后,在target option里要選擇 USE microLIB (keil自帶的微庫),這是使用非標準C庫,在編譯鏈接是,將我們編寫的fputc函數作為編譯的首選,否則就會編譯stdio.h里的fputc函數。

寫到這里我發現我這個代碼感覺不是很好,使用微庫而不用標準C庫,應該會有影響,我瞬間就明白了他們為什么要自己編寫支持輸出格式很少的的USART_printf函數了,后面目測我也會使用這個函數。

一個好的程序代碼就是結構健全,BUG很少。把簡單做到極致



在KEIL里繼續軟件仿真

仿真和下載時要注意的是,仿真要選USE Simulation  而下載要選右邊的JTAG。。。。

然后點擊debug 進入調試界面

 

view--->serial windos -->UART 1

全速運行 其結果如下:

串口發送數據就到此為止。

串口接收數據

這兒寫的跟上面的已經沒有關系了,不要搞混。

關于從PC機發送數據到STM32,這一部分則需要中斷來實現,因為我們不需要時時刻刻都來檢測外部是否發出數據給STM32,因此只要有數據來,就觸發中斷。這里就需要配置NVIC了

void NVIC_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //優先組為2

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  //打開USART中斷通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //搶占優先級

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;          //子優先級

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //中斷通道使能

NVIC_Init(&NVIC_InitStructure);

 

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);    //串口接收中斷使能

 

USART_Cmd(USART1, ENABLE);

}

 

 

其他配置比如串口復用到IO配置,串口時鐘配置,和發送數據是一樣的。

 

 

串口中斷處理函數:

 

 

void USART1_IRQHandler(void)

 int RX_status;  //自己定義一個標志位

RX_status = USART_GetFlagStatus(USART1, USART_FLAG_RXNE);//讀取接收數據標志位,如果裝好了一幀數據則硬件將其置一。

if(RX_status == SET) {

USART_SendData(USART1 , USART_ReceiveData(USART1));//將收到的數據再由STM32發送給PC機。

while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);//等待發送完成。

 

}

}

       串口的發送接收大致如此,還是要搞懂什么數據位,硬件流,停止位,校驗位什么,一個東西既然出現了就要好好分析出現的意義。想到了今天給電腦拆機清灰,電腦最好兩年清一次。反正每次上螺絲都會多出那么一兩個來,是不是可以不用要?

       肯定不是,生產商肯定也知道節約成本什么,他們的結構工程師也知道PCB上開一個螺絲孔也是要收錢的。所以每一顆螺絲都有它的意義,所以什么校驗位,停止位也有他的意義,即便我們不使用。其實剩的螺絲我也扔了,完全不知道上在哪兒!

        差不多就到這里了,有問題或者需要STM32的學習資料,關注我的新浪微博@忙碌的小姚,私信我即可,

  學習知識一定要主動,這是多么痛的領悟啊。!

                                                                                                                                        記于2014年6月8日

 

串口發送數據     百度云盤:http://pan.baidu.com/s/1i3kj31N

串口發送接收數據  百度云盤:http://pan.baidu.com/s/1o6r0OIY

關閉窗口

相關文章

主站蜘蛛池模板: 亚洲国产精品一区二区三区 | 一区二区在线不卡 | 91精品国产综合久久精品图片 | 精品免费国产 | 欧美伊人影院 | 亚洲天堂色 | 搞av.com| 国产一二三区精品视频 | 精品日韩| 国产精品一区一区 | 深爱激情综合 | 青青久久| 超碰97在线免费 | 91久久精品一区二区二区 | 中文久久 | 中文精品一区二区 | 免费在线国产视频 | 中文字幕一区二区三区不卡在线 | 一本岛道一二三不卡区 | av片免费 | 中文字幕亚洲一区 | 亚洲成年人免费网站 | 日韩欧美国产成人一区二区 | 久久综合九色综合欧美狠狠 | 久热精品在线播放 | 国产日韩一区二区三区 | 人和拘一级毛片c | 日韩在线观看一区 | 国产999精品久久久久久 | 久久新视频 | 在线看日韩 | 国产午夜精品一区二区 | 精品国产乱码久久久久久闺蜜 | 一区二区在线观看免费视频 | 99热首页 | 99热首页| 中文视频在线 | 亚洲免费在线播放 | 午夜电影一区二区 | 久久久久久成人 | 亚洲高清电影 |