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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

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

串口通訊(Serial Communication) 簡(jiǎn)介4

jf_78858299 ? 來源:匯極星科技 ? 作者:匯極星科技 ? 2023-04-23 11:30 ? 次閱讀

軟件設(shè)計(jì)

代碼如下:

//初始化 IO 串口 1 
//bound:波特率
void uart_init(u32 bound)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;


    //①串口時(shí)鐘使能,GPIO 時(shí)鐘使能,復(fù)用時(shí)鐘使能
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|
    RCC_APB2Periph_GPIOA, ENABLE); //使能 USART1,GPIOA 時(shí)鐘


    //②串口復(fù)位
    USART_DeInit(USART1); //復(fù)位串口 1
    //③GPIO 端口模式設(shè)置
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //ISART1_TX PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.9


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1_RX PA.10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.10


    //④串口參數(shù)初始化
    USART_InitStructure.USART_BaudRate = bound; //波特率設(shè)置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字長(zhǎng)為 8 位
    USART_InitStructure.USART_StopBits = USART_StopBits_1; //一個(gè)停止位
    USART_InitStructure.USART_Parity = USART_Parity_No; //無奇偶校驗(yàn)位
    USART_InitStructure.USART_HardwareFlowControl = 
    USART_HardwareFlowControl_None; //無硬件數(shù)據(jù)流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發(fā)模式
    USART_Init(USART1, &USART_InitStructure); //初始化串口


    #if EN_USART1_RX //如果使能了接收
    //⑤初始化 NVIC
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //搶占優(yōu)先級(jí) 3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí) 3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
    NVIC_Init(&NVIC_InitStructure); //中斷優(yōu)先級(jí)初始化


    //⑤開啟中斷
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //開啟中斷
    #endif


    //⑥使能串口
    USART_Cmd(USART1, ENABLE); //使能串口
}

此代碼的編寫順序即USART的配置順序:

我們用標(biāo)號(hào)①~⑥標(biāo) 示了順序:

① 串口時(shí)鐘使能,GPIO 時(shí)鐘使能

② 串口復(fù)位

    ③ GPIO 端口模式設(shè)置

    ④ 串口參數(shù)初始化

    ⑤ 初始化 NVIC 并且開啟中斷

    ⑥ 使能串口

配置全雙工的串口 1,那么 TX(PA9) 管腳需要配置為推挽復(fù)用輸出,RX(PA10)管腳配置為浮空輸入或者帶上拉輸入。

模式配置參考下面表格:

圖片

使用了串口的中斷接收,必須在 usart.h 里面設(shè)置 EN_USART1_RX 為 1(默認(rèn)設(shè)置就是 1 的) 。該函數(shù)才會(huì)配置中斷使能,以及開啟串口 1 的 NVIC 中斷。這里我們把串口 1 中斷放在組 2,優(yōu)先級(jí)設(shè)置為組 2 里面的最低。

接下來,根據(jù)之前講解的步驟 7,還要編寫中斷服務(wù)函數(shù)。串口 1 的中斷服務(wù)函數(shù) USART1_IRQHandler。

USART1_IRQHandler 函數(shù)

void USART1_IRQHandler(void)函數(shù)是串口 1 的中斷響應(yīng)函數(shù),當(dāng)串口 1 發(fā)生了相應(yīng)的中斷后,就會(huì)跳到該函數(shù)執(zhí)行。中斷相應(yīng)函數(shù)的名字是不能隨便定義的,一般我們都遵循 MDK定義的函數(shù)名。這些函數(shù)名字在啟動(dòng)文件 startup_stm32f10x_hd.s 文件中可以找到。

函數(shù)體里面通過函數(shù):

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

判斷是否接受中斷,如果是串口接受中斷,則讀取串口接受到的數(shù)據(jù):

Res =USART_ReceiveData(USART1);//(USART1->DR); //讀取接收到的數(shù)據(jù)

讀到數(shù)據(jù)后接下來就對(duì)數(shù)據(jù)進(jìn)行分析。

這里我們?cè)O(shè)計(jì)了一個(gè)小小的接收協(xié)議:通過這個(gè)函數(shù),配合一個(gè)數(shù)組 USART_RX_BUF[],一個(gè)接收狀態(tài)寄存器 USART_RX_STA(此寄存器其實(shí)就是一個(gè)全局變量,由作者自行添加。由于它起到類似寄存器的功能,這里暫且稱之為寄存器)實(shí)現(xiàn)對(duì)串口數(shù)據(jù)的接收管理。

USART_RX_BUF 的大小由 USART_REC_LEN 定義,也就是一次接收的數(shù)據(jù)最大不能超過USART_REC_LEN 個(gè)字節(jié)。USART_RX_STA 是一個(gè)接收狀態(tài)寄存器其各的定義如表 5.3.1.1 所示:

圖片

設(shè)計(jì)思路如下:

當(dāng)接收到從電腦發(fā)過來的數(shù)據(jù),把接收到的數(shù)據(jù)保存在 USART_RX_BUF 中,同時(shí)在接收狀態(tài)寄存器(USART_RX_STA)中計(jì)數(shù)接收到的有效數(shù)據(jù)個(gè)數(shù),當(dāng)收到回車(回車的表示由 2個(gè)字節(jié)組成:0X0D 和 0X0A)的第一個(gè)字節(jié) 0X0D 時(shí),計(jì)數(shù)器將不再增加,等待 0X0A 的到來,而如果 0X0A 沒有來到,則認(rèn)為這次接收失敗,重新開始下一次接收。

如果順利接收到 0X0A,則標(biāo)記 USART_RX_STA 的第 15 位,這樣完成一次接收,并等待該位被其他程序清除,從而開始下一次的接收,而如果遲遲沒有收到 0X0D,那么在接收數(shù)據(jù)超過 USART_REC_LEN 的時(shí)候,則會(huì)丟棄前面的數(shù)據(jù),重新接收。

中斷相應(yīng)函數(shù)代碼如下:

void USART1_IRQHandler(void)                  //串口1中斷服務(wù)程序
  {
  u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
    {
    Res =USART_ReceiveData(USART1);  //讀取接收到的數(shù)據(jù)


    if((USART_RX_STA&0x8000)==0)//接收未完成
      {
      if(USART_RX_STA&0x4000)//接收到了0x0d
        {
        if(Res!=0x0a)USART_RX_STA=0;//接收錯(cuò)誤,重新開始
        else USART_RX_STA|=0x8000;  //接收完成了 
        }
      else //還沒收到0X0D
        {  
        if(Res==0x0d)USART_RX_STA|=0x4000;
        else
          {
          USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
          USART_RX_STA++;
          if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開始接收    
          }     
        }
      }        
     }
}

main.c中的代碼

int main(void)
{    
   u16 t;  
  u16 len;  
  u16 times=0;
  delay_init();         //延時(shí)函數(shù)初始化    
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
  uart_init(115200);   //串口初始化為115200
   LED_Init();           //LED端口初始化
  KEY_Init();          //初始化與按鍵連接的硬件接口
   while(1)
  {
    if(USART_RX_STA&0x8000)
    {             
      len=USART_RX_STA&0x3fff;//得到此次接收到的數(shù)據(jù)長(zhǎng)度
      printf("\\r\\n您發(fā)送的消息為:\\r\\n\\r\\n");
      for(t=0;t<len;t++)
      {
        USART_SendData(USART1, USART_RX_BUF[t]);//向串口1發(fā)送數(shù)據(jù)
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發(fā)送結(jié)束
      }
      printf("\\r\\n\\r\\n");//插入換行
      USART_RX_STA=0;
    }else
    {
      times++;
      if(times%5000==0)
      {
        printf("\\r\\n精英STM32開發(fā)板 串口實(shí)驗(yàn)\\r\\n");
        printf("正點(diǎn)原子@ALIENTEK\\r\\n\\r\\n");
      }
      if(times%200==0)printf("請(qǐng)輸入數(shù)據(jù),以回車鍵結(jié)束\\n");  
      if(times%30==0)LED0=!LED0;//閃爍LED,提示系統(tǒng)正在運(yùn)行.
      delay_ms(10);   
    }
  }   
 }
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)函數(shù), 該函數(shù)是設(shè)置中斷分組號(hào)為 2,也就是 2 位搶占優(yōu)先級(jí)和 2 位子優(yōu)先級(jí)。
USART_SendData(USART1, USART_RX_BUF[t]); //向串口 1 發(fā)送數(shù)據(jù)
 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);

第一句,其實(shí)就是發(fā)送一個(gè)字節(jié)到串口。

第二句,就是我們?cè)谖覀儼l(fā)送一個(gè)數(shù)據(jù)到串口之后,要檢測(cè)這個(gè)數(shù)據(jù)是否已經(jīng)被發(fā)送完成了。USART_FLAG_TC 是宏定義的數(shù)據(jù)發(fā)送完成標(biāo)識(shí)符。

下載驗(yàn)證

首先打開串口調(diào)試助手。任何一個(gè)串口調(diào)試助手都是可以的。正點(diǎn)原子中使用的是舊版本的XCOM2.0。

圖片

我們?cè)诔绦蛏?面設(shè)置了必須輸入回車,串口才認(rèn)可接收到的數(shù)據(jù),所以必須在發(fā)送數(shù)據(jù)后再發(fā)送一個(gè)回車符, 這里 XCOM 提供的發(fā)送方法是通過勾選發(fā)送新行實(shí)現(xiàn)。

圖片

只要勾選了這個(gè)選項(xiàng),每次發(fā)送數(shù)據(jù)后,XCOM 都會(huì)自動(dòng)多發(fā)一個(gè)回車(0X0D+0X0A)。設(shè)置好了發(fā)送新行,我們?cè)僭诎l(fā)送區(qū)輸入你想要發(fā)送的文字,然后單擊發(fā)送,就能實(shí)現(xiàn)發(fā)送數(shù)據(jù)。

圖片

發(fā)送的數(shù)據(jù)被打印出來了,說明實(shí)驗(yàn)成功。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 串口通訊
    +關(guān)注

    關(guān)注

    1

    文章

    257

    瀏覽量

    24786
  • 通訊協(xié)議
    +關(guān)注

    關(guān)注

    10

    文章

    265

    瀏覽量

    20295
  • 串行通訊
    +關(guān)注

    關(guān)注

    2

    文章

    77

    瀏覽量

    16341
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Serial Communication based on Modbus Protocol

    This is my program about Serial Communication based on Modbus Protocol.And there is no errors
    發(fā)表于 11-01 09:27

    串口通訊是什么

    串口通訊目錄物理層協(xié)議層USART簡(jiǎn)介代碼講解串口通訊(Serial
    發(fā)表于 08-05 06:47

    串口通訊協(xié)議簡(jiǎn)介

    1 串口通訊協(xié)議簡(jiǎn)介串口通訊(Serial Communic
    發(fā)表于 08-12 06:30

    串口通訊簡(jiǎn)介

    串口通訊簡(jiǎn)介串口通訊(Serial Communicati
    發(fā)表于 11-30 06:56

    串口通訊基本知識(shí)簡(jiǎn)介

    基本知識(shí)串口通訊 (Serial Communication)串口中斷其實(shí)也是依靠判斷寄存器的狀態(tài)進(jìn)行中斷服務(wù)的通信的速率Bitrate—比
    發(fā)表于 12-08 08:30

    串口通信Serial簡(jiǎn)介

    簡(jiǎn)介按一次按鈕在串口監(jiān)視器輸出當(dāng)前狀態(tài)以及一共按下按鈕多少次我現(xiàn)在就缺一個(gè) 默認(rèn)單刀雙擲按鈕。。按下是A狀態(tài),不安默認(rèn)就是B狀態(tài)代碼void setup() {//開啟串口通信,波特率9600
    發(fā)表于 01-11 06:08

    串口通訊協(xié)議與RS-232標(biāo)準(zhǔn)簡(jiǎn)介

    文章目錄一、串口通訊協(xié)議1.簡(jiǎn)介2.物理層(1)RS-232 標(biāo)準(zhǔn)一、串口通訊協(xié)議1.簡(jiǎn)介
    發(fā)表于 02-15 06:03

    串口通訊串口通信協(xié)議簡(jiǎn)介

    目錄一、串口二、STM32系統(tǒng)給上位機(jī)(win10)連續(xù)發(fā)送“hello windows!”1、接線:2、代碼實(shí)現(xiàn)3、燒錄4串口調(diào)試一、串口串口
    發(fā)表于 02-15 07:21

    Serial Communication (COM) Dev

    the software to configure a ZigBee ZIC2410 for a Serial Communication application. In this application, when the device receives the da
    發(fā)表于 11-04 14:15 ?4次下載

    什么是串口通訊/同軸電纜

    什么是串口通訊/同軸電纜 串口通訊    Serial communic
    發(fā)表于 03-26 09:21 ?2738次閱讀

    Proteus在MCS&ARM中的應(yīng)用之Serial_Communication

    【好程序系列】Proteus在MCS&ARM中的應(yīng)用之Serial Communication
    發(fā)表于 01-20 15:03 ?4次下載

    STM32的串口通訊協(xié)議

    本文主要講解串口協(xié)議和RS-232標(biāo)準(zhǔn),以及RS232電平與TTL電平的區(qū)別;介紹"USB/TTL轉(zhuǎn)232"模塊(以CH340芯片模塊為例)的工作原理。一、串口協(xié)議1.1 串口通信協(xié)議簡(jiǎn)介
    發(fā)表于 12-24 18:37 ?8次下載
    STM32的<b class='flag-5'>串口</b><b class='flag-5'>通訊</b>協(xié)議

    串口通訊(Serial Communication) 簡(jiǎn)介1

    串口通訊 (Serial Communication) 是一種設(shè)備間極為常用的串行通訊方式,目前多存在于工控機(jī)及部分通信設(shè)備中。
    的頭像 發(fā)表于 04-23 11:25 ?6762次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>通訊</b>(<b class='flag-5'>Serial</b> <b class='flag-5'>Communication</b>) <b class='flag-5'>簡(jiǎn)介</b>1

    串口通訊(Serial Communication) 簡(jiǎn)介2

    串口通訊 (Serial Communication) 是一種設(shè)備間極為常用的串行通訊方式,目前多存在于工控機(jī)及部分通信設(shè)備中。
    的頭像 發(fā)表于 04-23 11:29 ?1048次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>通訊</b>(<b class='flag-5'>Serial</b> <b class='flag-5'>Communication</b>) <b class='flag-5'>簡(jiǎn)介</b>2

    串口通訊(Serial Communication) 簡(jiǎn)介3

    串口通訊 (Serial Communication) 是一種設(shè)備間極為常用的串行通訊方式,目前多存在于工控機(jī)及部分通信設(shè)備中。
    的頭像 發(fā)表于 04-23 11:30 ?2337次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>通訊</b>(<b class='flag-5'>Serial</b> <b class='flag-5'>Communication</b>) <b class='flag-5'>簡(jiǎn)介</b>3