STM32串口通訊

1、基於寄存器與基於固件庫編寫的差別

固件庫編寫方式,特色是簡單易於理解,資料多。新手適合用這種方式入門。
寄存器的可移植性強,更貼近底層,要求對外設的工做原理和運行機理有更深的理解。
編程

2、stm32串口通訊實戰

1.燒錄方式

我使用的是stm32f103指南者,從電腦中下載程序到stm32有兩種方式:
1.使用仿真線下載程序;(須要仿真線)
2.使用串口下載程序;(已經快被淘汰了,因爲只須要一根USB線,因此在沒有仿真線的狀況下,仍是實用)

ubuntu

接下來我使用的是第二種方法。
先下載圖中圈出的三個壓縮包
在這裏插入圖片描述

windows

連接: 野火STM32F103指南者開發板.
提取碼:pmf1
失效了就去這裏找到stm32f013指南者點進去下:
連接: 野火全部產品資料下載連接.


函數

而後用usb線把stm32開發板和電腦相鏈接,stm32端鏈接的 ‘usb轉串口’這個接口,再打開stm32開關,能夠看到紅色的小燈亮起。
在這裏插入圖片描述
開發板上有黃色的跳帽,是至關於導線的做用,此處要求BOOT0和BOOT1接地,RXD接A9,TXD接A10,開發板買來默認就是這樣接的,因此不須要改動。
在這裏插入圖片描述


測試

鏈接事後打開CH341SER.EXE,點擊安裝,顯示安裝成功便可。
在這裏插入圖片描述
而後打開串口下載助手mcuisp
在這裏插入圖片描述
按以下方式配置:①搜索串口,設置波特率 115200(儘可能不要設置的過高) ,②選擇要下載的 HEX 文件、③校驗、編程後執行、④DTR 低電平復位,RTS 高電平進入 bootloader、⑤開始編程。(前4步必定要調試正確,不然可能鏈接不上)
在這裏插入圖片描述




ui

2.代碼及效果圖

該處串口通訊實現如下功能:
1)設置波特率爲115200,1位中止位,無校驗位。
spa

2)STM32系統給上位機(win10)連續發送「hello windows!」,.net

3)當上位機給stm32發送「Stop stm32!」後,stm32中止發送。3d

此處的代碼在野火的代碼模板上改動。
先在前面的百度雲連接中下載模板
在這裏插入圖片描述
解壓後打開第21個串口通訊文件中的USART1接發中的工程文件
在這裏插入圖片描述
在這裏插入圖片描述而後把其中stm32f10x_it.c文件的串口中斷服務函數部分改成以下:




指針

int i=0;
uint8_t ucTemp[50];
void DEBUG_USART_IRQHandler(void)
{ 
	if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
	{ 
		ucTemp[i] = USART_ReceiveData(USART1);	
	}
  if(ucTemp[i] == '!')
	{ 
		if(ucTemp[i-1] == '2'&&ucTemp[i-2] == '3'&&ucTemp[i-3] == 'm'&&ucTemp[i-4] == 't'&&ucTemp[i-5] == 's'&&ucTemp[i-6] == ' ')
			if(ucTemp[i-7] == 'p'&&ucTemp[i-8] == 'o'&&ucTemp[i-9] == 't'&&ucTemp[i-10] == 's')
			{ 
				printf("ÊÕµ½£¡");
        while(1);
			}
	}
	i++;
}

在這裏插入圖片描述
而後把main.c函數改成

#include "stm32f10x.h"
#include "bsp_usart.h"


void delay(uint32_t count)
{ 
	while(count--);
}
int main(void)
{ 	
  USART_Config();
  while(1)
	{ 	
		printf("hello windows 10!\n");
		delay(5000000);
	}	
}

在這裏插入圖片描述
而後就能夠編譯生成hex文件了,按照上面的方式把hex文件燒錄到stm32中,而後打開最開始下載的串口調試助手,點擊打開串口,便可以看到stm32發給電腦的信息
在這裏插入圖片描述
最終效果以下(中止命令中的感嘆號是英文狀態下的):
在這裏插入圖片描述



3、C語言程序裏全局變量、局部變量、堆、棧等概念

看如下代碼:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char g_buf[16];
char g_buf2[16];
char g_buf3[16];
char g_buf4[16];

int main()
{ 

        printf("g_buf: 0x%x\n", g_buf);
        printf("g_buf2: 0x%x\n", g_buf2);
        printf("g_buf3: 0x%x\n", g_buf3);
        printf("g_buf4: 0x%x\n", g_buf4);
        return 0;
 
 
}

該代碼定義了4個全局變量並輸出它們的地址,
在這裏插入圖片描述
它們儲存到了全局區裏,地址依次遞增。

再看如下代碼

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main()
{ 

        char l_buf[16];
        char l_buf2[16];
        char l_buf3[16];
        printf("l_buf: 0x%x\n", l_buf);
        printf("l_buf2: 0x%x\n", l_buf2);
        printf("l_buf3: 0x%x\n", l_buf3);
 
}

定義了4個局部變量,並輸出它們的地址
在這裏插入圖片描述
它們的地址也是遞增的,暫時不知道儲存到了哪裏。(我在ubuntu定義的全部變量地址都是遞增,多是cpu的關係)

4、stm32的堆、棧、全局變量的分配地址

仍然使用以前野火的串口通訊模板,把main.c(分別在stm32中定義了全局變量和局部變量,並把它們的地址返回給windows)改成以下:

#include "stm32f10x.h"
#include "bsp_usart.h"

char global1[16];
char global2[16];
char global3[16];
	
int main(void)
{ 	
	char part1[16];
  char part2[16];
  char part3[16];

  USART_Config();

  printf("part1: 0x%p\n", part1);
  printf("part2: 0x%p\n", part2);
  printf("part3: 0x%p\n", part3);
	 
  printf("global1: 0x%p\n", global1);
  printf("global2: 0x%p\n", global2);
  printf("global3: 0x%p\n", global3);
  while(1)
	{ 	
		
	}	
}

生成hex文件後,燒錄到stm32中,打開串口調試助手,點擊打開串口,而後點擊stm32上的reset按鈕,就能夠看到以下結果。
在這裏插入圖片描述
前3個part變量爲局部變量,它們儲存到了棧中,地址依次減少。
後三個global爲全局變量,它們儲存到了靜態區,地址依次增長。


再試試如下函數(定義了靜態變量和指針),

#include "stm32f10x.h"
#include "bsp_usart.h"
#include <stdlib.h>

int main(void)
{ 	
  static char st1[16];
  static char st2[16];
  static char st3[16];
  char *p1;
  char *p2;
  char *p3;

 
  USART_Config();

  printf("st1: 0x%p\n", st1);
  printf("st2: 0x%p\n", st2);
  printf("st3: 0x%p\n", st3);
	 
  p1 = (char *)malloc(sizeof(char) * 16);
  p2 = (char *)malloc(sizeof(char) * 16);
  p3 = (char *)malloc(sizeof(char) * 16);
	
  printf("p1: 0x%p\n", p1);
  printf("p2: 0x%p\n", p2);
  printf("p3: 0x%p\n", p3);
  while(1)
	{ 	
		
	}	
}

在這裏插入圖片描述
前三個靜態變量儲存到了靜態區,地址依次增長。
後三個指針儲存到了堆中,地址依次增長。(堆棧具體知識請看參考博客)

結合兩次結果看(針對於測試的3個區域),能夠大概看出棧在頂層(地址最大),而後依次是堆,靜態區。對比如下地址分配圖,大體符合。
在這裏插入圖片描述

參考博客:
C語言中,局部變量、全局變量、靜態變量、堆、棧的內存地址.
C/C++程序內存的各類變量存儲區域和各個區域詳解.

相關文章
相關標籤/搜索