0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

敏矽微電子Cortex-M0學習筆記07——串口通信詳解

jf_pJlTbmA9 ? 來源:敏矽MCU ? 作者:敏矽MCU ? 2023-09-26 17:11 ? 次閱讀

1、UART串口簡介

單片機應用開發(fā)中,串口可以說是最常用的外設之一了。

串口最重要的功能就是能夠讓單片機和外部設備進行數(shù)據(jù)交互。例如在我們學習敏矽微電子的cortex m0時,可以將開發(fā)板與電腦相連,通過串口調(diào)試助手來調(diào)試程序、觀察程序運行結(jié)果。還有很多其他的串口模塊,比如藍牙、 NBIOT、GPRS、4G 等模組,都是使用的串口來進行驅(qū)動的,因此掌握串口是嵌入式工程師必備的技能。

接下來我們就來學習如何驅(qū)動ME32F030上的串口。

在正式學習之前,我們先對UART串口的通信格式做一個了解。UART的全稱是:通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter)。串行傳輸數(shù)據(jù)是按照字節(jié)為單位進行移位傳輸?shù)?,因此通信速度較低。但其擁有線路簡單、通信距離遠的優(yōu)點,使用兩條線即可實現(xiàn)雙向通信,一條用于發(fā)送,一條用于接收。因此在工業(yè)應用中受到廣泛應用。其通信格式也十分簡單,如下圖所示:

wKgaomUD0nCAM9_OAAC09zui9IU593.png

圖1 UART數(shù)據(jù)格式

空閑位:數(shù)據(jù)線在空閑狀態(tài)的時候保持高電平,表示沒有數(shù)據(jù)傳輸。

起始位:當要傳輸數(shù)據(jù)的時候,數(shù)據(jù)線會被拉低,表示開始數(shù)據(jù)傳輸。

數(shù)據(jù)位:數(shù)據(jù)位就是實際要傳輸?shù)臄?shù)據(jù),一般都是按照字節(jié)傳輸數(shù)據(jù)的,即一次傳輸8 位數(shù)據(jù)的。一般都是低位在前,高位在后。當然也有相反的傳輸協(xié)議,但平時很少會遇到。

奇偶校驗位:這是對數(shù)據(jù)中“1”的位數(shù)進行奇偶校驗用的,可以根據(jù)需求進行選擇。

停止位:數(shù)據(jù)傳輸完成標志位,停止位的位數(shù)可以選擇 1 位、1.5 位或 2 位高電平,一般都選擇 1 位停止位。

波特率:波特率就是 UART 數(shù)據(jù)傳輸?shù)乃俾剩簿褪敲棵雮鬏數(shù)臄?shù)據(jù)位數(shù),一般選擇 9600、19200、115200 等。

隨著電腦日新月異的升級換代,現(xiàn)在很多電腦都不帶傳統(tǒng)的COM口,USB接口開始廣泛應用。所以就有了USB轉(zhuǎn)串口芯片來解決這個難題,常用的U轉(zhuǎn)串芯片有CH340、PL2303 等。通過這些芯片就可以實現(xiàn)串口 TTL 轉(zhuǎn) USB。

ME32F030開發(fā)板使用的是PL2303 芯片來完成串口和電腦之間的連接,只需要一條USB 線即可。在使用前需要注意兩件事:第一,先下載并安裝PL2303的驅(qū)動程序。第二,檢查開發(fā)板的USB跳線帽是否接到COM、USB這邊。正確的接法如下:

wKgZomUD0nKAUTZaAA31EYmpGNk420.png

圖2 跳線連接

2、UART驅(qū)動寄存器

ME32F030 提供2個 UART 外設:UART0,UART1。串行接口都支持紅外傳輸(IrDA)協(xié)議功能。時鐘都受 SYSAHBCLKCTRL 寄存器控制。同時每個 UART 有獨立的時鐘分頻器來產(chǎn)生波特率,并使之不受系統(tǒng)時鐘和PCLK影響。UART對應的管腳映射圖如下:

wKgaomUD0nSAbao-AADZ1I_hZn8560.png

圖3 UART管腳映射

看完管腳的映射關系,接下來就列出與UART相關的寄存器組,隨后會挨個進行講解。

wKgaomUD0nWAD0HrAAIUqWbLjHk857.png

圖4 UART寄存器

2-1 UART接收/發(fā)送緩沖寄存器

UART 接收/發(fā)送緩沖寄存器包含著 UART 接收到/將發(fā)送的字節(jié),接收到的數(shù)據(jù)和待發(fā)送的串口數(shù)據(jù)都在該寄存器中。

2-2 UART狀態(tài)寄存器

該寄存器用于提供 UART 接收發(fā)送緩存器的狀態(tài)。大致可以歸類為以下幾種狀態(tài):

發(fā)送狀態(tài):發(fā)送FIFO空、發(fā)送FIFO半滿、發(fā)送FIFO滿。

接收狀態(tài):接收FIFO空、接收FIFO半滿、接收FIFO滿。

奇偶校驗狀態(tài):沒有奇偶校驗錯誤,或檢測到奇偶錯誤,寫1來清除錯誤標志。

接收緩存器溢出狀態(tài) :用來表明緩存器是否溢出。

2-3 UART控制寄存器

接下來就要著重講解下UART控制寄存器了。0-5位屬于基本的接收、發(fā)送中斷使位,這里不再累述。

BIT6:奇偶校驗中斷使能,使能該中斷后,當接收到的數(shù)據(jù)發(fā)生奇偶校驗錯誤后,會產(chǎn)生中斷通知串口接收發(fā)生錯誤。

BIT7:接收溢出中斷使能,使能該中斷后,當接收到的數(shù)據(jù)超出FIFO容量就會產(chǎn)生中斷。通知及時取出數(shù)據(jù)或者清空FIFO。

BIT8:奇偶校驗方式選擇位,0為偶校驗,1為奇校驗。這里注意,這只是選擇了奇偶校驗的方式,但是并不會生效,是否啟動校驗還需要下面介紹的寄存器。

BIT9:奇偶校驗使能位,只有當該位置1才會使能奇偶校驗,具體的校驗方式由剛才介紹的奇偶校驗方式選擇位來決定。

BIT10:IRDA傳輸協(xié)議使能位,置1使能。

BIT22:RX接收使能,置1使能。

BIT23:TX發(fā)送使能,置1使能。

wKgZomUD0neAJXHNAAK6NMS23fo174.png

wKgaomUD0niARYsTAAGJ2mrw_CE256.png

圖5 UART控制寄存器

2-4 UART中斷狀態(tài)寄存器

既然剛才在介紹UART控制寄存器的時候,介紹了不少中斷使能控制??隙ň蜁邢鄳闹袛酄顟B(tài)的管理。UART中斷狀態(tài)寄存器從低位開始依次管理著:①、發(fā)送結(jié)束中斷狀態(tài),②、接收完成中斷狀態(tài),③、發(fā)送FIFO滿中斷,④、接收FIFO滿中斷,⑤、發(fā)送FIFO半滿中斷,⑥、接收FIFO半滿中斷,⑦、奇偶校驗錯誤中斷,⑧、接收溢出中斷。

2-5 UART 波特率分頻器寄存器

UART 波特率分頻器寄存器 (BAUDDIV) 用于時鐘分頻從而產(chǎn)生相應的波特率。該寄存器可讀寫。該分頻器的時鐘源是由UARTnCLKDIV 控制 UART 的波特率源時鐘(SCLK)。

wKgaomUD0nmAIUV0AACwNPR1ong274.png

圖6 UART 波特率分頻器寄存器

波特率分頻值計算公式:

BAUDDIV = SCLK / UART BAUDRATE

2-6 UART TX/RX FIFO 數(shù)據(jù)清除寄存器

操作該寄存器可以快速對TX/RX FIFO進行數(shù)據(jù)清空。

wKgZomUD0nuAbR10AADCxKq6uTI349.png

圖7 UART TX/RX FIFO 數(shù)據(jù)清除寄存器

3、UART驅(qū)動函數(shù)

在例程LIB->common->Drivers->Source文件夾內(nèi)有uart.c文件,這個就是提供的UART驅(qū)動文件,里面包含了一些基本的驅(qū)動函數(shù),使用起來十分方便。下面會對每個函數(shù)進行講解。

3-1 UART初始化

在每段源代碼的后面,筆者對其進行一下注釋,方便大家快速掌握和使用這個函數(shù)。這個函數(shù)的4個參數(shù)的意義如下:

uart:要使能的UART模塊,可選UART0、UART1。

baudrate:要設置的串口的波特率。

parityoption:奇偶校驗位,可選UART_EVEN_PARITY(奇校驗)、 UART_ODD_PARITY(偶校驗)、 UART_RX_NO_INT(無校驗)。

rxinttriggerlevel:接收中斷觸發(fā)條件。

voidUART_Open(UART0_Type*uart,uint32_tbaudrate,uint8_tparityoption,uint8_trxinttriggerlevel)
{
uint32_tvolatiledelays;

if(uart==UART0)
{

//初始化時關閉UART0IRQ
NVIC_DisableIRQ(UART0_IRQn);

//使能UART0時鐘
SYSCON->SYSAHBCLKCTRL_b.UART0_CLK=1;//enableUART0PCLK
SYSCON->UART0CLKDIV_b.DIV=0x1;/*dividedby1*/

//復位UART0
SYSCON->PRESETCTRL_b.UART0_RST_N=0;
SYSCON->PRESETCTRL_b.UART0_RST_N=1;
}
elseif(uart==UART1)
{
//初始化時關閉UART1IRQ
NVIC_DisableIRQ(UART1_IRQn);

//使能UART1時鐘
SYSCON->SYSAHBCLKCTRL_b.UART1_CLK=1;//enableUART1PCLK
SYSCON->UART1CLKDIV_b.DIV=0x1;/*dividedby1*/

//復位UART1
SYSCON->PRESETCTRL_b.UART1_RST_N=0;
SYSCON->PRESETCTRL_b.UART1_RST_N=1;
}
elsereturn;

//設置波特率
uart->BAUDDIV_b.BAUDDIV=MainClock/baudrate;

//設置奇偶校驗
if(parityoption==UART_ODD_PARITY)
uart->CTRL_b.PARISEL=1;

if(parityoption!=UART_NO_PARITY)
uart->CTRL_b.PARIEN=1;

//設置中斷觸發(fā)條件
if(rxinttriggerlevel==UART_RX_NOT_EMPTY)
uart->CTRL_b.RXNEIE=1;

if(rxinttriggerlevel==UART_RX_HALF_FULL)
uart->CTRL_b.RXHLFIE=1;

if(rxinttriggerlevel==UART_RX_FULL)
uart->CTRL_b.RXFIE=1;

//使能發(fā)送和接收功能
uart->CTRL_b.TXEN=1;
uart->CTRL_b.RXEN=1;

//插入延時
SYS_DelaymS(1);

//清空FIFO
uart->FIFOCLR=0xFF;
return;
}

3-2 UART關閉

這段函數(shù)用來關閉UART0或者UART1,只需要傳入需要關閉的串口即可。

voidUART_Close(UART0_Type*uart)
{
if(uart==UART0)
{
//關閉UART0_IRQ
NVIC_DisableIRQ(UART0_IRQn);

//關閉UART0時鐘
SYSCON->SYSAHBCLKCTRL_b.UART0_CLK=0;

}elseif(uart==UART1)
{

//關閉UART1_IRQ
NVIC_DisableIRQ(UART1_IRQn);

//關閉UART1時鐘
SYSCON->SYSAHBCLKCTRL_b.UART1_CLK=0;
}
elsereturn;

//關閉相應UART的中斷,并清除中斷標志
UART_DisableInt(uart);
UART_ClearIntFlag(uart);
return;
}

3-3 UART讀取單個字節(jié)

這段函數(shù)的作用是UART讀取單個字節(jié)的數(shù)據(jù)。

uint8_tUART_ByteRead(UART0_Type*uart,uint8_t*data)
{
if(uart->STATE_b.RXNE)
{
*data=uart->DATA;
return0;
}
else
return1;
}

3-4 UART連續(xù)讀取多個字節(jié)

UART連續(xù)讀取串口數(shù)據(jù),直到讀取到指定長度的數(shù)據(jù)。

voidUART_Read(UART0_Type*uart,uint8_t*rxbuf,uint8_t*readbytes)
{
uint8_ttemp=0;

//getalldata
while((uart->STATE_b.RXNE)  ((*readbytes)--))
{
*rxbuf++=uart->DATA;
temp++;
}

//returnnumberofread
*readbytes=temp;
return;
}

3-5 UART發(fā)送單個字節(jié)

這段函數(shù)的作用是UART發(fā)送單個字節(jié)的數(shù)據(jù)。

uint8_tUART_ByteWrite(UART0_Type*uart,uint8_tdata)
{
if(uart->STATE_b.TXF)
return1;

uart->DATA=data;
return0;
}

3-6 UART連續(xù)發(fā)送多個字節(jié)

UART連續(xù)發(fā)送串口數(shù)據(jù),直到發(fā)送完指定長度的數(shù)據(jù)。

voidUART_Send(UART0_Type*uart,uint8_t*txbuf,uint32_tsendbytes)
{
while(sendbytes--)
{
while(uart->STATE_b.TXF);
uart->DATA=*txbuf++;
}
return;
}

3-7 UART發(fā)送字符串

UART發(fā)送一段字符串數(shù)據(jù),只需要將要發(fā)送的字符串數(shù)據(jù)首地址傳入即可。

voidUART_PutString(UART0_Type*uart,uint8_t*str)
{
while(!(*str=='?'))
{
while(uart->STATE_b.TXF);
uart->DATA=*str++;
}
return;
}

3-8 UART使能中斷

有兩個參數(shù)項,第一個是選擇需要使能的UART,第二個選擇觸發(fā)中斷的條件。

voidUART_EnableInt(UART0_Type*uart,uint32_tintcon)
{
uart->CTRL|=intcon;
return;
}

3-9 UART關閉中斷

調(diào)用該函數(shù)后,所有的串口的中斷觸發(fā)條件都將關閉。

voidUART_DisableInt(UART0_Type*uart)
{
uart->CTRL =0xFFFFFF00;
return;
}

4、串口中斷例程

介紹完UART常用的驅(qū)動函數(shù),接下來用個小例程來演示下UART的驅(qū)動。測試程序的功能是:通過串口助手發(fā)送一個字節(jié)的數(shù)據(jù)到單片機,單片機收到該數(shù)據(jù)后,將該數(shù)據(jù)通過單片機的串口發(fā)送到串口助手。

程序設計思路

首先是對UART0端口的初始化,將IO口復用為串口UART0的TX、RX功能。

隨后將UART0初始化為波特率115200,無奇偶校驗,接收非空觸發(fā)中斷。

下一步就是使能UART0的中斷,中斷觸發(fā)條件為接收FIFO非空。

最后使能UART0_IRQn中斷服務子程序。

測試程序的代碼如下:

intmain(void)
{
//UART0端口初始化
PA_2_INIT(PA_2_TX0);
PA_3_INIT(PA_3_RX0);

//UART0寄存器初始化
UART_Open(UART0,115200,UART_NO_PARITY,UART_RX_NOT_EMPTY);
UART_EnableInt(UART0,UART_RX_NOT_EMPTY);
NVIC_EnableIRQ(UART0_IRQn);
while(1)
{
}
}

//UART0中斷服務子程序
voidUART0_IRQHandler(void)
{
uint8_tcdata;

//判斷中斷狀態(tài)位
if(UART0->INTSTATUS_b.RXNEINT)
{
cdata=UART0->DATA;//將接收到的數(shù)據(jù)返回
UART0->DATA=cdata;
}

//清除中斷狀態(tài)
UART0->INTSTATUS=0x0F;
}

程序調(diào)試

編寫完程序,首先要在編譯環(huán)境下進行編譯、連接。沒有錯誤后(最好連警告也沒有)。就可以實際連接到電路板進行程序調(diào)試運行了。

在實驗前需要先確定U轉(zhuǎn)串所使用的的串口號,通過windows的設備管理器中的端口(COM和LPT)查看我們的串口,比如本例中是COM7。

wKgZomUD0nyAUPz-AAE5mPH8Wuw228.png

圖8 串口端口號選擇

接下來打開串口上位機工具,本例使用的是“大傻串口工具”。按照程序中設置的串口參數(shù)配置好串口。端口選擇COM7,波特率115200,數(shù)據(jù)位8位,無奇偶校驗,1位停止位。最后點擊打開串口即可。打開后如圖所示:

wKgaomUD0n2AW0ejAABhVr6Si6g644.png

圖9 串口配置

上位機環(huán)境配置好之后,接下里就可以下載并仿真程序了。首先我們在UART0_IRQ中斷子程序中位置打上斷點。隨后全速運行程序。

wKgaomUD0n-AfQSXAACju3l2Sgo292.png

圖10 仿真界面

然后我們在上位機發(fā)送一個數(shù)據(jù)進行測試,例如發(fā)送一個字節(jié)0x11。這時候單片機便會進入串口中斷服務程序,并且停止在斷點處。這時候我們聽過watch窗口看到接收的數(shù)據(jù),就是0x11。

wKgaomUD0oGAZq6JAAEU0DgN1CI378.png

圖11 數(shù)據(jù)發(fā)送

繼續(xù)單步運行并退出中斷服務程序,這時候我們再去看上位機,發(fā)現(xiàn)收到了單片機返回的數(shù)據(jù)。

wKgZomUD0oKAWjixAACvM5_LU20516.png

圖12 數(shù)據(jù)接收

來源:敏矽MCU

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6026

    文章

    44452

    瀏覽量

    630803
  • uart
    +關注

    關注

    22

    文章

    1214

    瀏覽量

    100995
  • 串口通信
    +關注

    關注

    34

    文章

    1604

    瀏覽量

    55324
  • Cortex-M0
    +關注

    關注

    4

    文章

    124

    瀏覽量

    38591
收藏 人收藏

    評論

    相關推薦

    cortex-m0學習資料

    本帖最后由 jheng 于 2015-4-9 21:54 編輯 cortex-m0學習
    發(fā)表于 04-09 21:48

    深入淺出Cortex-M0學習資料

    深入淺出Cortex-M0學習資料
    發(fā)表于 06-18 10:50 ?0次下載
    深入淺出<b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b>資料

    Cortex-M0的指令集

    Cortex-M0的指令集,有需要的下來看看。
    發(fā)表于 01-13 17:17 ?29次下載

    cortex-m0加密

    cortex-m0加密
    發(fā)表于 10-13 15:08 ?5次下載
    <b class='flag-5'>cortex-m0</b>加密

    MCU學習筆記_ARM Cortex M0_簡介

    MCU學習筆記ARM Cortex M01. RM的CPU core 的基本概念2. ARM Cortex
    發(fā)表于 10-28 11:21 ?14次下載
    MCU<b class='flag-5'>學習</b><b class='flag-5'>筆記</b>_ARM <b class='flag-5'>Cortex</b> <b class='flag-5'>M0</b>_簡介

    基于ARM Cortex-M0核的MCU設計及應用

    知網(wǎng)鏈接:基于ARM Cortex-M0核的MCU設計及應用
    發(fā)表于 11-05 15:35 ?18次下載
    基于ARM <b class='flag-5'>Cortex-M0</b>核的MCU設計及應用

    全球最強性能Cortex-M0 MCU誕生!

    Arm傳統(tǒng)的、為MCU打造的Cortex-M系列CPU主要有:Cortex-M0, Cortex-M3, Cortex-M4。其中Cortex-M0
    的頭像 發(fā)表于 12-20 11:15 ?1207次閱讀

    串口通信入門筆記

    串口最重要的功能就是能夠讓單片機和外部設備進行數(shù)據(jù)交互。例如在我們學習微電子cortex
    的頭像 發(fā)表于 04-23 17:37 ?1400次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>通信</b>入門<b class='flag-5'>筆記</b>

    微電子Cortex-M0學習筆記08——基本定時器詳解

    微電子Cortex-M0學習筆記08——基本定時器詳解
    的頭像 發(fā)表于 09-26 17:13 ?786次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>08——基本定時器<b class='flag-5'>詳解</b>

    微電子Cortex-M0學習筆記06——段式LCD液晶實例

    微電子Cortex-M0學習筆記06——段式LCD液晶實例
    的頭像 發(fā)表于 09-26 17:10 ?664次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>06——段式LCD液晶實例

    微電子Cortex-M0學習筆記05——端口外部中斷實例

    微電子Cortex-M0學習筆記05——端口外部中斷實例
    的頭像 發(fā)表于 09-26 17:10 ?683次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>05——端口外部中斷實例

    微電子Cortex-M0學習筆記04——GPIO詳解及應用實例

    微電子Cortex-M0學習筆記04——GPIO詳解
    的頭像 發(fā)表于 09-26 17:07 ?928次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>04——GPIO<b class='flag-5'>詳解</b>及應用實例

    微電子Cortex-M0學習筆記03——時鐘系統(tǒng)設計例程

    微電子Cortex-M0學習筆記03——時鐘系統(tǒng)設計例程
    的頭像 發(fā)表于 09-26 17:06 ?819次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>03——時鐘系統(tǒng)設計例程

    微電子Cortex-M0學習筆記02——Cortex-M0開發(fā)環(huán)境的建立及調(diào)試

    微電子Cortex-M0學習筆記02——Cortex-M
    的頭像 發(fā)表于 09-26 17:05 ?1455次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>02——<b class='flag-5'>Cortex-M0</b>開發(fā)環(huán)境的建立及調(diào)試

    微電子Cortex-M0學習筆記01——芯片簡介

    微電子Cortex-M0學習筆記01——芯片簡介
    的頭像 發(fā)表于 09-26 17:03 ?789次閱讀
    <b class='flag-5'>敏</b><b class='flag-5'>矽</b><b class='flag-5'>微電子</b><b class='flag-5'>Cortex-M0</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>01——芯片簡介