免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
GD32實(shí)戰(zhàn)6__串口讀寫

目的

? 串口通信是非常非常常見的一種通信方式,必須掌握的。可以從如下幾個(gè)方面掌握串口通信:

  1. 串口通信原理,此處我們只研究異步串口
  2. GD32常見的幾種串口通信配置

異步串口通信原理

1. 配置

? 在了解原理之前,我們先看看串口要如何使用,如下圖,只要選擇正確的串口號(hào),把收發(fā)雙方的波特率、校驗(yàn)位、數(shù)據(jù)位、停止位配置成一致,這么就可以實(shí)現(xiàn)雙方通信。

那么配置的這些參數(shù)分別代表什么意思呢?

串口號(hào):唯一標(biāo)識(shí)一個(gè)串口,當(dāng)設(shè)備存在多個(gè)串口時(shí),可以用其標(biāo)識(shí)每個(gè)串口。

波特率:每秒鐘傳輸?shù)臄?shù)據(jù)位數(shù)。表示數(shù)據(jù)傳輸?shù)乃俾?,單位bps(位每秒)。比如115200bps就表示1s可以傳輸115200bits的數(shù)據(jù)。

校驗(yàn)位:

? even 每個(gè)字節(jié)傳送整個(gè)過(guò)程中bit為1的個(gè)數(shù)是偶數(shù)個(gè)(校驗(yàn)位調(diào)整個(gè)數(shù))
? odd 每個(gè)字節(jié)穿送整個(gè)過(guò)程中bit為1的個(gè)數(shù)是奇數(shù)個(gè)(校驗(yàn)位調(diào)整個(gè)數(shù))
? none 沒有校驗(yàn)位
? space 校驗(yàn)位總為0
? mark 校驗(yàn)位總為1

數(shù)據(jù)位:5678共4個(gè)選擇,這是歷史原因,如下

? 5:用于電報(bào)機(jī)傳26個(gè)英文字母,5位足以

? 6:用于電報(bào)機(jī),識(shí)別大小寫字母,增加一個(gè)大小寫位

? 7:用于電腦,ASCII碼7位

? 8:用于電腦,DBCS碼用于兼容ASCII和支持中文雙字節(jié)

停止位:

? 停止位是按長(zhǎng)度來(lái)算的。串行異步通信從計(jì)時(shí)開始,以單位時(shí)間為間隔(一個(gè)單位時(shí)間就是波特率的倒數(shù)),依次接受所規(guī)定的數(shù)據(jù)位和奇偶校驗(yàn)位,并拼裝成一個(gè)字符的并行字節(jié);此后應(yīng)接收到規(guī)定長(zhǎng)度的停止位“1”。所以說(shuō),停止位都是“1”,1.5是它的長(zhǎng)度,即停止位的高電平保持1.5個(gè)單位時(shí)間長(zhǎng)度。一般來(lái)講,停止位有1,1.5,2個(gè)單位時(shí)間三種長(zhǎng)度。

2. 幀格式

? 下面我們看下串行協(xié)議的幀格式,如圖

一個(gè)幀由4部分組成,起始位 數(shù)據(jù)位 校驗(yàn)位 停止位,正好跟上面的配置一一對(duì)應(yīng),其中,起始位必須是低電平,停止位必須是高電平。

至此,也大致明白串口是怎么回事了。

3. 常見的串口電平標(biāo)準(zhǔn)

? 下面幾種都是串口,只是電平標(biāo)準(zhǔn)不同,導(dǎo)致其應(yīng)用場(chǎng)景存在差異,通信協(xié)議和配置都是相同的,通信原理是相同的,軟件實(shí)現(xiàn)相同,硬件電路存在差異。

TTL:

  1. 接線方式如圖

  2. 高電平表示邏輯1, 低電平表示邏輯零

     ![1536645105294](assets/1536739271596.png)

RS232和RS485對(duì)比

  1. 抗干擾性:RS485 接口是采用平衡驅(qū)動(dòng)器和差分接收器的組合,抗噪聲干擾性好。RS232 接口使用一根信號(hào)線和一根信號(hào)返回線而構(gòu)成共地的傳輸形式,這種共地傳輸容易產(chǎn)生共模干擾。
  2. 傳輸距離:RS485 接口的最大傳輸距離標(biāo)準(zhǔn)值為 1200 米(9600bps 時(shí)),實(shí)際上可達(dá) 3000 米。RS232 傳輸距離有限,最大傳輸距離標(biāo)準(zhǔn)值為 50 米,實(shí)際上也只能用在 15 米左右。
  3. 通信能力:RS-485 接口在總線上是允許連接多達(dá)128個(gè)收發(fā)器,用戶可以利用單一的 RS-485 接口方便地建立起設(shè)備網(wǎng)絡(luò)。RS-232只允許一對(duì)一通信。
  4. 傳輸速率:RS-232傳輸速率較低,在異步傳輸時(shí),波特率為 20Kbps。RS-485 的數(shù)據(jù)最高傳輸速率為 10Mbps 。
  5. 信號(hào)線:RS485 接口組成的半雙工網(wǎng)絡(luò),一般只需二根信號(hào)線。RS-232 口一般只使用 RXD、TXD、GND 三條線 。
  6. 電氣電平值:RS-485的邏輯"1"以兩線間的電壓差為 (2-6) V 表示;邏輯"0"以兩線間的電壓差為-(2-6)V 表 示 。在 RS-232-C 中任何一條信號(hào)線的電壓均為負(fù)邏輯關(guān)系。即:邏輯"1",-5- -15V;邏輯"0 " 5- 15V 。

4. 芯片如何實(shí)現(xiàn)串口功能

?

? 我們知道串口的作用是為CPU和其它設(shè)備之間提供通信,本質(zhì)上是把數(shù)據(jù)從其他設(shè)備搬移到自身MCU的內(nèi)存中去,如上圖,MCU為實(shí)現(xiàn)串口功能會(huì)做如上的模塊劃分。

  1. GPIO

    串口總線狀態(tài),默認(rèn)是高電平,所以Tx應(yīng)該是上拉輸出,Rx應(yīng)該是浮空輸入。

  2. 移位器

    我們知道串口是一位位傳輸?shù)模砸莆黄骷纯梢詫?shí)現(xiàn)串口的收發(fā)。

  3. 數(shù)據(jù)寄存器

    用于存儲(chǔ)將要發(fā)送和接收的數(shù)據(jù),其實(shí)只要收發(fā)共用一個(gè)字節(jié)就足以。

  4. 時(shí)鐘

    上述的運(yùn)行過(guò)程都需要在固定時(shí)鐘下才能正確運(yùn)行,例如波特率。

  5. 數(shù)據(jù)由寄存器搬移到內(nèi)存

    1. CPU方式,由CPU控制數(shù)據(jù)如何在數(shù)據(jù)寄存器和內(nèi)存之間進(jìn)行轉(zhuǎn)移,例如當(dāng)數(shù)據(jù)寄存器空時(shí),將內(nèi)存轉(zhuǎn)移到數(shù)據(jù)寄存器中,即發(fā)送過(guò)程
    2. DMA方式,過(guò)程同CPU,那為什么還有有DMA呢?因?yàn)閿?shù)據(jù)搬移省去CPU的參與,也就意味著CPU可以去忙其它事情,效率自然就高了。
  6. 狀態(tài)寄存器

    1. 我們粗略的思考下,在整個(gè)串口的傳輸過(guò)程中,肯定會(huì)有各式各樣的狀態(tài),例如,收到數(shù)據(jù),數(shù)據(jù)異常,幀錯(cuò)誤,數(shù)據(jù)發(fā)送完畢,數(shù)據(jù)寄存器空了等等,這些都需要狀態(tài)寄存器存儲(chǔ)。
    2. 再深入思考下,當(dāng)我們需要及時(shí)的處理上述狀態(tài)時(shí),靠CPU輪詢顯然太慢了,所以肯定需要中斷,再增加一組中斷狀態(tài)寄存器。
  7. 配置寄存器

    ? 上述情況那么多,代表不同的配置,肯定需要幾組配置寄存器。例如,中斷的使能控制等

功能設(shè)計(jì)

? 如果明白了原理,那么自然就知道該如何配置一個(gè)串口了,無(wú)非就是從芯片手冊(cè)中找到相應(yīng)的寄存器進(jìn)行配置而已。

? 在”串口發(fā)送“例子中,已經(jīng)接觸了串口的發(fā)送功能,現(xiàn)在我們把這個(gè)例子再度深入,實(shí)現(xiàn)串口的接收功能。實(shí)現(xiàn)一個(gè)回顯功能,即PC通過(guò)串口向GD32寫入數(shù)據(jù),然后GD32把數(shù)據(jù)原封不動(dòng)返回給PC。

輪詢方式
VOID DRV_UART1_PollTest(VOID){    U8 ch = 0;        while (1)    {        if (USART_GetBitState(USART1, USART_FLAG_RBNE) != RESET)        {            ch = (U8)USART_DataReceive(USART1);            UART1_SendChar(ch);        }    }}VOID DRV_UART1_PollInit(VOID){    UART1_GpioInit();    UART1_Config();    USART_Enable(USART1, ENABLE);}

效果如圖

中斷方式

注:中斷優(yōu)先級(jí)部分,我會(huì)抽單獨(dú)章節(jié)分析。

必須注意下面這兩個(gè)函數(shù)的區(qū)別,

USART_GetBitState(USART1, USART_FLAG_RBNE); /* 非中斷使用 */USART_GetIntBitState(USART1, USART_INT_RBNE);/* 中斷內(nèi)使用 */

中斷方式處理代碼如下:

VOID USART1_IRQHandler(VOID){    if (USART_GetIntBitState(USART1, USART_INT_RBNE) != RESET)    {        if (gUart1RxCount >= DRV_UART1_BUFLEN)        {            memset(gUart1RxBuf, 0, sizeof(gUart1RxBuf));            gUart1RxCount = 0;        }        gUart1RxBuf[gUart1RxCount] = (U8)USART_DataReceive(USART1);        gUart1RxCount  ;    }    if (USART_GetIntBitState(USART1, USART_INT_IDLEF) != RESET)    {        gUart1RxBufFlag  ;    }}VOID DRV_UART1_InterruptTest(VOID){    U8 rxCount = 0;    while (1)    {        if (gUart1RxBufFlag > 0)        {            for (rxCount = 0; rxCount < gUart1RxCount; rxCount  )            {                UART1_SendChar(gUart1RxBuf[rxCount]);            }            memset(gUart1RxBuf, 0, sizeof(gUart1RxBuf));            gUart1RxCount = 0;            gUart1RxBufFlag = 0;        }    }}VOID DRV_UART1_InterruptInit(VOID){    UART1_GpioInit();    UART1_Config();    UART1_NvicConfiguration();    USART_Enable(USART1, ENABLE);    USART_INT_Set(USART1, USART_INT_RBNE, ENABLE);    USART_INT_Set(USART1, USART_INT_IDLEF, ENABLE);}
DMA方式

? 注:DMA細(xì)節(jié)我會(huì)抽單獨(dú)章節(jié)分析,此處只寫一個(gè)DMA輪詢方式的例子。

static VOID UART1_DmaRxConfig(IN U8 *buf, IN U32 len){    DMA_InitPara DMA_InitStructure;        DMA_Enable(DMA1_CHANNEL5, DISABLE);        /* USART1 RX DMA1 Channel (triggered by USART1 Rx event) Config */    DMA_DeInit(DMA1_CHANNEL5);    DMA_InitStructure.DMA_PeripheralBaseAddr = (U32) &(USART1->DR);    DMA_InitStructure.DMA_MemoryBaseAddr = (U32)buf;    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC;    DMA_InitStructure.DMA_BufferSize = len;    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE;    DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;    DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;    DMA_Init(DMA1_CHANNEL5, &DMA_InitStructure);    DMA_Enable(DMA1_CHANNEL5, ENABLE);}VOID DRV_UART1_DmaInit(VOID){    UART1_GpioInit();    UART1_Config();    RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1, ENABLE);    UART1_DmaRxConfig(gUart1RxBuf, DRV_UART1_BUFLEN);    USART_Enable(USART1, ENABLE);    USART_DMA_Enable(USART1, (USART_DMAREQ_TX | USART_DMAREQ_RX), ENABLE);}static VOID UART1_DmaSend(IN U8 *buf, IN U32 len){    DMA_InitPara DMA_InitStructure;    DMA_Enable(DMA1_CHANNEL4, DISABLE);    /* USART1_Tx_DMA_Channel (triggered by USART1 Tx event) Config */    DMA_DeInit(DMA1_CHANNEL4);    DMA_InitStructure.DMA_PeripheralBaseAddr = (U32) &(USART1->DR);    DMA_InitStructure.DMA_MemoryBaseAddr = (U32)buf;    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;    DMA_InitStructure.DMA_BufferSize = len;    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE;    DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;    DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;    DMA_Init(DMA1_CHANNEL4, &DMA_InitStructure);        DMA_Enable(DMA1_CHANNEL4, ENABLE);    while (DMA_GetBitState(DMA1_FLAG_TC4) == RESET)    {    }}VOID DRV_UART1_DmaTest(VOID){    while (1)    {        if (USART_GetBitState(USART1, USART_FLAG_IDLEF) != RESET)        {            UART1_DmaSend(gUart1RxBuf, DRV_UART1_BUFLEN);            memset(gUart1RxBuf, 0, DRV_UART1_BUFLEN);            UART1_DmaRxConfig(gUart1RxBuf, DRV_UART1_BUFLEN);            USART_DataReceive(USART1); /* 清除USART_FLAG_IDLEF */        }    }}

總結(jié)

? 串口是一種非常常見的通信總線,必須掌握。如果上面的原理和例子理解了,我相信用GPIO口虛擬一個(gè)窗口并不是什么難事。

代碼路徑

https://github.com/YaFood/GD32F103/tree/master/TestUART

來(lái)源:http://www.icode9.com/content-4-246651.html
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
STM32串口DMA超時(shí)接收方法,可大大節(jié)約CPU時(shí)間 (amoBBS 阿莫電子論壇)
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服