主頁 >  其他 > 【嵌入式】串口通信及其案例

【嵌入式】串口通信及其案例

2021-04-18 11:47:42 其他

目錄

前言

1. 簡介

1.1 UART口與COM口

1.2 UART口的特征

1.3 UART口兼容COM口

2.使用場景

3.作業模式(僅了解即可)

3.1 單工模式(Simplex)

3.2 半雙工模式(Half duplex)

3.3 全雙工模式(Full duplex)

4.RS232串口通信標準和介面定義

4.1外觀

4.2物理層

4.3協議層

4.3.1 波特率

4.3.2 通訊的起始位和停止位

4.3.3 資料位

4.3.4 資料校驗

4.3.5 資料傳輸率

5. USB轉RS232串口電路

6.演示RS232串口協議

6.1 STM32F103芯片

6.2 下位機開發板介紹

6.2.1 下位機開發板中STM32F103ZET芯片引腳分配圖

6.2.2 下位機串口原理圖

6.3 下位機串口通信代碼實作

6.4 上位機串口通信代碼實作

6.5 USB轉RS232串口驅動安裝

6.6 效果展示

7.應用:讀取溫度傳感器(DS18B20)的傳感值

7.1 DS18B20溫度傳感器介紹

7.2 下位機開發板上DS18B20原理圖

7.3 下位機實作讀取DS18B20傳感器溫度值

7.4 實作上位機與下位機通信的串口指令

7.5 上位機溫度曲線顯示功能實作

7.6 效果展示

參考


前言

本文簡要介紹串口概念、物理介面、通信協議,最后借助串口從下位機將溫度傳感器的實測溫度上傳至上位機進行展示,本文不以詳細教授嵌入式編程技巧,僅展示串口通信和嵌入式編程的大概流程,僅作為“科普”目的,閱讀此文無需具備嵌入編程經驗,感興趣即可,

1. 簡介

串行通信埠( cluster communication port ),簡稱串口,即COM口,串行通信是指資料一位一位地順序傳送,其特點是通信線路簡單,只要一對傳輸線就可以實作雙向通信(可以直接利用電話線作為傳輸線),從而大大降低了成本,但傳送速度較慢(后文會計算其傳輸速度),

1.1 UART口與COM口

嵌入式里面說的串口,一般是指UART(Universal Asynchronous Receiver/Transmitter,通用異步收發傳輸器)口, 但是我們經常搞不清楚UART口和COM口的區別, 實際上UART、COM指的物理硬體介面形式,

圖1-1-1 UART介面

UART有4個引腳(VCC, GND, RX, TX), 用的TTL電平, 低電平為0(0V),高電平為1(3.3V或以上),如圖1-1-1所示,

圖1-1-2 RS232串口(母頭)

COM口是臺式機上面常用的介面(圖1-1-2),9個引腳, 用的RS-232標準電平, 使用負邏輯電平,定義+3 ~ +15V為低電平,而-15 ~ -3V為高電平,

1.2 UART口的特征

一般uart控制器在嵌入式系統里面都做在cpu一起,像飛思卡爾的IMX6芯片、意法半導體的STM32芯片就是這樣,有多個uart控制器,
UART引腳介紹(COM口有9個引腳,但是常用的也是下面這幾個):

VCC:供電引腳,一般是3.3v,在我們的板子上沒有過電保護,這個引腳一般不接更安全
GND:接地引腳,有的時候rx接受資料有問題,就要接上這個引腳,一般也可不接
RX:接收資料引腳
TX:發送資料引腳

1.3 UART口兼容COM口

由于UART口的VCC、GND、RX、RT引腳與COM口的這幾個引腳具有一樣的用途和功能,而絕大多數COM口通信中也僅需要使用這四個引腳,因此在很多場景下UART口可以作為COM口的兼容口使用,

2.使用場景

串行介面(COM口)是一種可以將接受來自CPU的并行資料字符轉換為連續的串行資料流發送出去,同時可將接受的串行資料流轉換為并行的資料字符供給CPU的器件,

  串口是計算機上一種非常通用的設備通信協議,大多數計算機(不包括筆記本電腦)包含兩個基于RS-232的串口,串口同時也是儀器儀表設備通用的通信協議,同時,串口通信協議也可以用于獲取遠程采集設備的資料,

  RS-232(ANSI/EIA-232標準)是IBM-PC及其兼容機上的串行連接標準,可用于許多用途,比如連接滑鼠、列印機或者Modem(調制解調器),同時也可以接工業儀器儀表,RS-232只限于PC串口和設備間點對點的通信,RS-232串口通信最遠距離是50英尺(15.24米),

3.作業模式(僅了解即可)

串行通信的基礎是單線傳輸,資料通常是在兩個站點之間進行傳輸,按照資料流的方向分為3種傳輸模式:

3.1 單工模式(Simplex)

單工模式的資料是單向的,通訊雙方一方為發送端,另一方則固定為接收端,資訊只能沿一個方向傳輸,使用一根資料線,例如收音機,只能接收發射塔給它的資料,并不能給發射塔發資料,

這里寫圖片描述
圖 3-1-1 單工通信模式


3.2 半雙工模式(Half duplex)

半雙工模式是指通訊雙方都具有發送器和接收器,雙方既可以發射也可以接收,但是接收和發射不能同時進行,半雙工一般用在兩個方向都傳輸資料的場合,例如對講機,

這里寫圖片描述
圖 3-2-1 半雙工通信模式

3.3 全雙工模式(Full duplex)

全雙工資料通訊分別由兩根可以在兩個不同的站點同時發送和接收的傳輸線進行傳輸資料,通訊雙方能在同一時刻進行發送和接收操作,

全雙工模式下,每一端都有發送器和接收器,有兩條傳輸線可以在互動式應用場合中使用,資訊傳輸效率高,例如手機,

這里寫圖片描述
圖 3-3-1 全雙工通信模式

此文我們研究的RS232串口標準通信就可以作業在全雙工通信模式下,因其將資料傳輸和接收采用獨立的2根線實作,因此可以同時發送和接收資料,接下來將詳細介紹RS232串口標準,

4.RS232串口通信標準和介面定義

4.1外觀

圖 4-1-1 RS232串口硬體介面

4.2物理層

這里講解RS-232標準,RS-232標準主要規定了信號的用途,通訊介面以及信號的電平標準,
使用RS-232標準串口的設備間通信結構圖如下:

這里寫圖片描述
圖4-2-1 RS232標注串口設備間通信結構 [注:DB9是舊式計算機中RS232標準介面的稱呼]

兩個通訊設備的“DB9介面”之間用串口線建立起連接,串口線中使用RS-232標準傳輸資料信號,由于RS-232電平標準的信號不能直接被控制器直接識別,所以信號需要經過一個“電平轉換芯片”轉換成控制器能識別的“TTL標準”電平[參看 表4-2-1]信號,
RS232通信使用的電平標準詳細表如下:

這里寫圖片描述
表 4-2-1 RS232通信使用的電平標準


常見的電子電路中常用TTL的電平標準,理想狀態下使用5V表示二進制邏輯1,使用0V表示二進制邏輯0,為了增加串口通訊的遠距離傳輸及抗干擾能力,它使用-15V表示邏輯1,+15V表示邏輯0,
其中接線口以針式引出信號線的稱為公頭(圖 4-1-1 右側),以孔式引出信號線的稱為母頭(圖 4-1-1 左側),
DB9 介面中的公頭及母頭的各個引腳的標準信號線接法:

這里寫圖片描述
圖4-2-2 RS232標準DB9公/母頭及其引腳

RS-232的每一個引腳都有它的作用,也有信號流動方向,原先的RS-232是用來連接調制解調器[注:俗稱“貓”,Modem,是Modulator(調制器)與Demodulator(解調器)的簡稱],因此它的引腳位意義通常也和調制解調器傳輸相關,隨著行業發展,RS-232標準介面被用到更多的設備上,
從功能上來看,全部信號線分為3類:資料線(TXD、RXD)、地線(GND)和聯絡控制線(DSR、DTR、RI、DCD、RTS、CTS)

這里寫圖片描述
表 4-2-2 RS232各引腳在上位機和下位機之間的作用以及信號流向


兩個通訊設備之間的地電位可能不一樣,這會影響收發雙方的電平信號,所以兩個串口設備之間必須要使用地線連接,即共地,
串口線中的聯絡控制線使用邏輯1表示信號有效,邏輯0表示信號無效,例如,當計算機端控制DTR信號線為邏輯1時,其目的是告知遠端的調制解調器本機已準備好接收資料,0表示還沒準備就緒,
在目前的其它工業控制使用的串口通訊中,一般只使用RXD、TXD以及GND三條信號線,直接傳輸資料信號,RTS、CTS等聯絡控制線被裁剪掉,

4.3協議層

根據通訊的資料同步方式,可分為同步和異步兩種,根據通訊程序中是否使用到時鐘信號進行區分
同步通信中,收發設備上方會使用一根信號線傳輸信號,在時鐘信號的驅動下雙方進行協調,同步資料,例如,通訊中通常雙方會統一規定在時鐘信號的上升沿或者下降沿對資料線進行采樣,
異步通信中,不使用時鐘信號進行資料同步,它們直接在資料信號中穿插一些用于同步的信號位,或者將主題資料進行打包,以資料幀的格式傳輸資料,通訊中還需要雙方規約好資料的傳輸速率等,以便更好地同步,
兩種同步方式優劣:在同步通訊中,資料信號所傳輸的內容絕大部分是有效資料,而異步通訊中會則會包含資料幀的各種識別符號,所以同步通訊效率高,但是同步通訊雙方的時鐘允許誤差小,稍稍時鐘出錯就可能導致資料錯亂,異步通訊雙方的時鐘允許誤差較大,

本文講解常用的“異步通信”資料同步方式,

串口通訊的資料包由發送設備通過自身的TXD介面傳輸到接收設備的RXD介面,通訊雙方的資料包格式要規約一致才能正常收發資料,串口通訊協議層中,規定了資料包的內容,它由起始位、主體資料位、校驗位以及停止位組成,如圖4-3-1所示,

這里寫圖片描述
圖 4-3-1 串口異步通信字符幀


4.3.1 波特率

講波特率之前首先了解一下通信速率,
通信速率通常是以位元率來表示,即每秒鐘傳輸的二進制位數,單位為位元每秒(bit/s),容易和位元率混淆的概念是“波特率”,它表示每秒傳輸了多少碼元,
碼元是通信信號調制的概念,時間間隔相同的符號來表示一個二進制數字,這樣的信號就稱為碼元,如常見的通信傳輸中,用0V表示數字0,5V表示數字1,那么一個碼元可以表示兩種狀態0和1,所以一個碼元等于一個二進制位元位,此時波特率的大小與位元率一致;若傳輸中,有0V、2V、4V和6V分別表示00、01、10、11,那么每個碼元可以表示四種狀態,兩個二進制位元位,所以碼元數是二進制位元位數的一半,這個時候的波特率為位元率的一半,因為很多常見的通信中一個碼元都是表示兩種狀態,人們常常直接以波特率來表示位元率,其實二者是有區別的,而RS232串口通信中,一個碼元等于一個二進制位,
異步通信由于沒有時鐘信號(DB9介面[RS232標準口的另一種稱呼]沒有信號線),所以兩個通信設備需要規約好波特率,即每個碼元的長度,以便對信號進行解碼,圖 4-3-1中一個矩形表示一個碼元,常見的波特率為4800,9600,115200,921600,

4.3.2 通訊的起始位和停止位

串口通訊的一個資料包從起始信號開始,直到停止信號結束,資料包的起始信號由一個邏輯0的資料位表示,而資料包的停止信號可由0.5、1、1.5或2個邏輯1的資料位表示,只要雙方約定一致即可,圖 4-3-1中約定起始位和停止位都是1個邏輯1的資料位表示,

4.3.3 資料位

在資料包的起始位之后緊接著的就是要傳輸的主體資料內容,也稱為有效資料,有效資料的長度常被約定為5、6、7 或8 位長,圖 4-3-1中的D0~D7,

4.3.4 資料校驗

在有效資料之后,有一個可選的資料校驗位,由于資料通信相對更容易受到外部干擾導致傳輸資料出現偏差,可以在傳輸程序加上校驗位來解決這個問題,校驗方法有奇校驗(odd)、偶校驗(even)、0 校驗(space)、1 校驗(mark)以及無校驗(noparity),
奇校驗:要求有效資料和校驗位中“1”的個數為奇數
偶校驗:與奇校驗要求剛好相反,要求幀資料和校驗位中“1”的個數為偶數
0/1校驗:不管有效資料中的內容是什么,校驗位總為0或者1

4.3.5 資料傳輸率

由圖4-3-1可以計算出一個“字符幀”的有效資料比率,一個字符幀由4部分組成:
資料位:D0~D7,占據8位
起始位:1位
奇偶校驗位:1位
停止位:1位
即一個字符幀一共有11位,那么“一個字符幀的有效資料傳輸比率= 8 / 11”,
在RS232串口通信中,一個碼元等于一個二進制位,即此時“波特率=位元率”,假設在某次資料傳輸程序中,字符幀連續傳輸,無空閑,則常用波特下的資料傳輸比率如下:
波特率4800,換算位元率即 4800bps: 有效資料傳輸率 = 4800 bps*( 8/11) = 3490 bps = 3490 bps / 8 = 436 B/s
波特率9600,換算位元率即 9600bps: 有效資料傳輸率 = 9600 bps*( 8/11) = 6981 bps = 6981 bps / 8 = 872 B/s
波特率115200,換算位元率即 115200bps: 有效資料傳輸率 = 115200 bps*( 8/11) = 83781 bps = 83781 bps / 8 = 10472 B/s
波特率921600,換算位元率即 921600bps: 有效資料傳輸率 = 921600 bps*( 8/11) = 670254 bps = 670254 bps / 8 = 83781 B/s
可見RS232串口傳輸速率相比以太網的確慢很多,因此不適合用于大資料傳輸場景,適合傳輸控制信號和小資料量,

5. USB轉RS232串口電路

隨著USB介面及其協議的普及,串口也逐漸退出了公眾視野,僅存于某些特定設備行業中,很多個人電腦已經不再有RS232串口硬體介面,如果需要使用RS232串口可以通過USB介面轉RS232串口線(如圖 5-1)來連接串口設備,

圖 5-1 USB轉RS232串口線

由于USB介面使用4根線(如圖 5-2),而且USB協議與RS232使用的9根線及其協議完全不一樣,因此需要一個USB轉RS232的電路(如圖 5-3)完成協議的轉換,

圖 5-2 USB TypeA 介面
圖 5-3 USB轉UART電路


6.演示RS232串口協議

本節將介紹如何基于STM(意法半導體)設計的STM32F103芯片(基于ARM Cotex-M3核心)演示RS232串口通信,STM32F103芯片內部已經實作了RS232標準的串口協議,接下來將詳細介紹,

6.1 STM32F103芯片

圖 6-1-1 STM32F103ZET系列芯片引腳布局

6.2 下位機開發板介紹

本文我們僅關注STM32F103ZET芯片(圖6-2-1中心的那塊芯片)、RS232串口、DS18B20溫度傳感器,

圖6-2-1 下位機開發板

6.2.1 下位機開發板中STM32F103ZET芯片引腳分配圖

圖 6-2-1-1下位機開發板中STM32F103ZET芯片引腳分配圖

6.2.2 下位機串口原理圖

圖 6-2-2-1 實作RS232標準的SP3232芯片引腳與COM口連接原理圖

6.3 下位機串口通信代碼實作

初始化串口配置

/****************************************************************************
* Function Name  : USART1_Config
* Description    : Configurates the USART1.
* Input          : baudRate:波特率
* Output         : None
* Return         : None
****************************************************************************/

void USART1_Config(uint16_t baudRate)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	/* 打開RCC時鐘 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	/* 設定TXD的GPIO引數 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               //復用推挽輸出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                     //串口輸出PA9

	/* 初始化串口輸入IO */
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* 設定RXD的GPIO引數 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //模擬輸入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                     //串口輸入PA10

	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* 設定USART的引數 */
	USART_InitStructure.USART_BaudRate = baudRate;                  //波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;     //資料長8位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;          //1位停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;             //無效驗
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//使能硬體流
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //開啟發送和接受模式
	
    /* 初始化USART1 */
	USART_Init(USART1, &USART_InitStructure);
	
	/* 使能USART1 */
	USART_Cmd(USART1, ENABLE);
#ifdef USE_USART1RX_INTERRUPT  
    USART1_NVIC_RxConfig();
    USART_ITConfig(USART1, USART_IT_RXNE ,ENABLE);
#endif 		
}

實作串口資料接收函式:串口的資料接收是通過硬體中斷(USART1中斷)發生時,呼叫中斷回應函式USART1_IRQHandler實作

/****************************************************************************
* Function Name  : USART1_NVIC_RxConfig
* Description    : 設定接收中斷的中斷等級,并打開總中斷
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/

void USART1_NVIC_RxConfig(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 設定NVIC引數 */
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級為0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //回應優先級為0
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   //打開USART1的全域中斷
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		      //使能,

    NVIC_Init(&NVIC_InitStructure);
}

/****************************************************************************
* Function Name  : USART1_IRQHandler
* Description    : 串口1的中斷函式
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/
uint8_t USART1_RX_Buff[64], USART1_RX_State;

void USART1_IRQHandler (void)
{
    uint8_t dat;

    /* 接收中斷(接收到的資料必須是0x0D 0x0A結尾(即回車))表示接收結束 */
    if(USART_GetITStatus(USART1, USART_IT_RXNE))
    {
        
        dat = USART_ReceiveData(USART1);
        /* 沒接收完,使用USART1_RX_State的最高位作結束標識 */
        if(((USART1_RX_State & 0x80) == 0) && ((USART1_RX_State & 0x3F) < 63)) 
        {   
            /* 已經接收到0x0D,使用USART1_RX_State的第6位(從0位開始)作接收到0x0D的標識 */
            if(USART1_RX_State & 0x40)    
            {
                if(dat == 0x0A)    //第二個位元組接收到0x0A接收結束
                {
                    USART1_RX_State |= 0x80;
                    USART1_RX_Buff[USART1_RX_State & 0x3F] = 0;   
                }
                else
                {
                    USART1_RX_State = 0; 
                }
            }
            else
            {
                if(dat == 0x0D)     //接收到0x0D,標識USART1_RX_State的第6位(從0位開始)
                {
                    USART1_RX_State |= 0x40;    
                }
                else
                {
                    USART1_RX_Buff[USART1_RX_State & 0x3F] = dat;
                    USART1_RX_State++;    
                }
            } 
        }
    }    
}

實作串口資料發送函式

/****************************************************************************
* Function Name  : USART1_SetWord
* Description    : 通過串口1發送字串.
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/

void USART1_SendWord(uint8_t *wd)
{	
	while(*wd)                      //檢測是否發送資料是否為空
	{
		USART_SendData(USART1, *wd);
		while (USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET); //等待發送完畢
		wd++;
	}		
}


// 串口資料發送函式
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_USART_DATA(Data)); 
    
  /* Transmit Data */
  USARTx->DR = (Data & (uint16_t)0x01FF);
}

6.4 上位機串口通信代碼實作

上位機服務程式采用Qt庫(C++ GUI庫以及框架)實作,

創建串口通信物件(QSerialPort類實作了串口通信客戶端功能)

serial = new QSerialPort(this);

初始化串口通信引數

void MainWindow::openSerialPort()
{
    SettingsDialog::Settings p = settings->settings();
    serial->setPortName(p.name);
    serial->setBaudRate(p.baudRate);
    serial->setDataBits(/*p.dataBits*/QSerialPort::Data8);
    serial->setParity(/*p.parity*/QSerialPort::NoParity);
    serial->setStopBits(/*p.stopBits*/QSerialPort::OneStop);
    serial->setFlowControl(/*p.flowControl*/QSerialPort::NoFlowControl);
    if (serial->open(QIODevice::ReadWrite)) {
        console->setEnabled(true);
        console->setLocalEchoEnabled(p.localEchoEnabled);
        ui->actionConnect->setEnabled(false);
        ui->actionDisconnect->setEnabled(true);
        ui->actionConfigure->setEnabled(false);
        showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
                    .arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
                    .arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
    } else {
        QMessageBox::critical(this, tr("Error"), serial->errorString());
        showStatusMessage(tr("Open error"));
    }
}

串口讀寫

void MainWindow::readData()
{
    QByteArray data = serial->readAll();
}
void MainWindow::writeData(const QByteArray &data)
{
    serial->write(data);
}

6.5 USB轉RS232串口驅動安裝

如果你使用的USB轉RS232串口線是非通用型,則需要到你所購買此線的廠家官網下載對應驅動,然后安裝到作業系統,例如我用的是“優越者Y-105系列USB轉串口線”,則需要在其官網下載“PL2303u2c_veryhuo.com.rar”驅動(如圖6-5-1),然后安裝到作業系統中:

圖6-5-1 特定廠商的USB轉串口驅動

安裝成功后,使用此USB轉RS232串口線接下位機,Windows“設備管理器”中的“埠(COM和LPT)”節點(如圖6-5-2)下即會出現如圖6-5-3所示的COM設備(COM設備節點是從1編號,如COM1、COM7)

圖6-5-2 COM設備節點

圖6-5-3 COM7設備

如果你購買的USB轉RS232串口線是通用型(CH340\CH341),則無需安裝驅動,Windows系統直接支持,即插即用!如圖6-5-4所示

圖6-5-4 通用型USB轉RS232串口線

6.6 效果展示

圖6-6-1 上位機連接下位機串口成功

7.應用:讀取溫度傳感器(DS18B20)的傳感值

7.1 DS18B20溫度傳感器介紹

圖 7-1-1 DS18B20 產品特性及引腳介紹

翻譯圖 7-1-1中DS18B20的產品特性介紹:

特征
% 獨特的1-Wire(1線)介面僅需一個埠引腳即可進行通信
% 多點功能簡化了分布式溫度感測應用
% 無需外部組件
% 可以通過資料線供電, 電源范圍為3.0V至5.5V
% 零待機功耗
% 可測量-55°C至+ 125°C的溫度, 華氏溫度等效值為-67°F至+ 257°F
% -10°C至+ 85°C的±0.5°C精度
% 溫度計解析度可在9到12位(bit位)之間編程
% 在750毫秒內(最大)將12位(bit位)溫度轉換為數字字(2Byte)
% 用戶定義的非易失性溫度警報設定
% 警報搜索命令可識別和尋址溫度超出編程限制的設備(溫度警報條件)
% 應用場景包括恒溫控制,工業系統,消費產品,溫度計或任何熱敏系統

7.2 下位機開發板上DS18B20原理圖

圖 7-2-1 DS18B20原理圖
圖 7-2-2 DS18B20產品檔案:使用VDD來供應溫度轉換電流

7.3 下位機實作讀取DS18B20傳感器溫度值

表7-3-1 DS18B20 輸出資料與溫度關系表

7.4 實作上位機與下位機通信的串口指令

上位機代碼

上位機向下位機發送"g\r\n"字串

void MainWindow::openSerialPort()
{
    // 略:串口初始化,參看第6節

    timer->start(TIMER_INTVAL);  // 開啟定時器,定時發送獲取溫度指令
    } else {
        // 略
    }
}

// 執行定時任務函式:發送獲取溫度指令
void MainWindow::sendTempCommand()
{
    writeData("g\r\n");
}

下位機代碼

下位機接收到指令后進行決議,如果收到"g\r\n"指令則向上位機發送DS18B20的溫度值,格式為: "+25.2\r\n" 或者 "-25.2\r\n"

int main(void)
{
	uint32_t i = 0;
    int16_t tempValue;
	uint8_t tempStr[8] = {0,0,0,0,0,0,0,0};  /*溫度字串*/
	uint16_t len;

    
    /* 初始化 */ 
    FLASH_Init();             //FLASH芯片初始化
    SYSTICK_Config();         //系統時鐘初始化
    USART1_Config(9600);      //USART1串口初始化
    NVIC_Config();            //初始化中斷分組
    DS18B20_Init();           //溫度傳感器初始化  

	while(1)
	{
	    /* 方案1:周期性主動發送DS18B20溫度資料 */


		// 方案2:收到獲取溫度指令后再發送溫度值
		tempValue = DS18B20_ReadTemp();            
        GUI_DisplayTempData(tempValue);

		// 檢測是否收到溫度獲取指令
        if((USART2_RX_State & 0x80))
        {
            // 取得接收到的資料長度
            USART2_RX_State = USART2_RX_State & 0x3F; 
			if( 'g' == USART2_RX_Buff[0]) // 收到獲取溫度指令:g\r\n
			{
				//將溫度發回串口
				memset(tempStr, 0, sizeof(tempStr)); 
				int16ToChar(tempValue, tempStr);
		        for(len=0; len < sizeof(tempStr); len++)
		        {
		            USART_SendData(USART2, tempStr[len]);
		        	while (USART_GetFlagStatus(USART2, USART_FLAG_TC) != SET); //等待發送完畢   
		        }
			
			}
            USART2_RX_State = 0;
        }
	} // end while
}


/****************************************************************************
* Function Name  : DS18B20_ReadTemp
* Description    : 讀取溫度值.
* Input          : None
* Output         : None
* Return         : temp:讀取到的溫度值,并保留兩位小數點(百倍),
****************************************************************************/
int16_t DS18B20_ReadTemp(void)
{
	int16_t tempValue = 0;
    uint16_t temp;

    DS18B20_Reset();
	DS18B20_WriteData(0xCC);		//跳過ROM操作命令		 
	DS18B20_WriteData(0x44);	    //溫度轉換命令

    /* 如果不是連續讀的話,這里加個延時,DS18B20轉換溫度需要時間 */
//    SYSTICK_Delay1ms(200);

	DS18B20_Reset();
	DS18B20_WriteData(0xCC);	    //跳過ROM操作命令
	DS18B20_WriteData(0xBE);	    //發送讀取溫度命令

	/* 讀取16位溫度值,先讀低位 */
	temp = DS18B20_ReadData();
	tempValue = DS18B20_ReadData();
    tempValue <<= 8;
    tempValue |= temp;
    temp = tempValue;

	/* 溫度處理,溫度保留兩位小數點 */
	if(tempValue < 0)
	{
		temp = temp - 1;
		temp = ~temp;
		temp = (float)temp * 6.25 + 0.5;
        return (-temp);   
	}
	else
	{
		temp = (float)temp * 6.25+ 0.5;
        return  temp;
	}
}

7.5 上位機溫度曲線顯示功能實作

void MainWindow::readData()
{
    QByteArray data = serial->readAll();
    QString str(data);
    tempStr += str;

    QStringList strList;
    QRegExp rx("(\\+\\d+\\.\\d+)\\r\\n");
    int pos = rx.indexIn(tempStr);
    if( -1 < pos)
    {
        qDebug() << tempStr;
        tempStr.clear();
        strList.append(rx.cap(1));
    }
    else
    {
        return;
    }

    for(int i = 0; i < strList.size(); ++i)
    {
        QString item = strList.at(i);
        if( item.length() < 5)  continue;
        float num = item.toFloat();
        qint64 current_time_total_ms = QDateTime::currentMSecsSinceEpoch();
        lineseries.append(current_time_total_ms + TIMER_INTVAL, num);
    }
}

7.6 效果展示

圖7-6-1中保鮮膜包裹的即為DS18B20溫度傳感器(為測驗水溫,包裹保鮮膜保護傳感器),

圖7-6-1 基于STM32F103 MCU的硬體平臺--DS18B20溫度傳感下位機搭建

上位機收到下位機的持續溫度值之后就可以繪制曲線了,圖7-6-2中的曲線是使用Qt的QtCharts::QChart類實作,
首先一小段平緩曲線是“室溫”,接下來將DS18B20放入溫水中,觀察曲線進入上升階段直至60.5度附近,然后將DS18B20從溫水中取出,曲線進入緩慢下降階段,向溫水中摻入一定量開水,再將DS18B20放入熱水中,觀察發現曲線陡然快速上升,達到80.8度附近將DS18B20從熱水中取出,最后放置在空氣中,靜待其降溫!
整個操作程序中完成溫度曲線如圖7-6-3所示,

注意:整個熱水溫度測量時長為10分鐘,觀察Gif圖片效果需要點耐心,

圖7-6-2 上位機顯示溫度傳感器的溫度變化(室溫-溫水-開水)

圖7-6-3 溫度傳感器溫度變化曲線

參考

[1] UART簡介及與COM口的區別

[2] 串口通信的具體用途是什么

[3] 串口通訊介紹

[4] 串口通信簡介

[5] DS18B20 Programmable Resolution 1-Wire? Digital Thermometer

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/277404.html

標籤:其他

上一篇:嵌入式藍橋杯G431RBT6 串口配置及使用方法cube MX

下一篇:P5707 【深基2.例12】上學遲到

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more