STM32F10x USART串列埠對映功能實現串列埠通訊 485初始化
這篇文章很有用!新手不要自以為是,STM32串列埠管腳重對映小樣你會嗎???
STM32F10x 系列微控制器中都包含了USART 模組,所謂USART,就是通用同步非同步收發器。通用同步非同步收發器(USART)提供了一種靈活的方法與使用工業標準NRZ非同步序列資料格式的外部裝置之間進行全雙工資料交換。它支援同步單向通訊和半雙工單線通訊,也支援LIN(區域性互連網),智慧卡協議和IrDA(紅外資料組織)SIR ENDEC規範,以及調變解調器(CTS/RTS)操作。它還允許多處理器通訊。
從前面的介紹可知USART模組功能非常的強大。這裡我只簡單講講如何用USART模組來實現標準EIA-232
用過微控制器的人肯定都接觸過串列埠,設定串列埠無非就是設定波特率、資料位、停止位、奇偶校驗位。傳送接收也就三種基本方式,輪詢、中斷和DMA。STM32F10x 的USART 模組也不過如此。所以我重點講講我在除錯程式碼時犯得各種錯誤,那些很容易得到的程式碼就不詳細的講解了。
首先說說我的硬體環境。還是那塊神舟4號開發板,用的是串列埠2,對應的是USART2。預設情況下USART2是連線到IO埠A的,但是我這裡需要將USART的管腿重定向到IO埠D上。具體的管腿的關係參見下表。這個表是從STM32參考手冊上拷下來的。
初始化USART的程式碼很簡單。USART2 連線到
- USART_InitTypeDef USART_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- USART_InitStructure.USART_BaudRate = 9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
-
USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART2, &USART_InitStructure );
這樣設定了還不能使用。因為我們將USART2 重定向了。重定向操作需要寫複用重對映和除錯I/O配置暫存器(AFIO_MAPR)。GPIO_PinRemapConfig() 可以完成這項任務。
- GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
光這樣操作還不夠。STM32參考手冊上有這麼一段話:
對暫存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX進行讀寫操作前,應當首先開啟AFIO的時鐘。參考第6.3.7節APB2外設時鐘使能暫存器(RCC_APB2ENR)。
所以需要先開啟AFIO的時鐘。因此,USART2的重定向需要兩步操作:
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
我原以為這樣就能工作了,可是結果還是什麼都沒有輸出。沒辦法只能繼續研究。在讀GPIO的相關章節時看到下圖讓我恍然大悟。
USART2的輸入輸出都是借用PD口管腿,PD 口的時鐘卻還沒給。用到的幾個IO 埠也沒有設定相應的輸入輸出狀態。在讀到8.1.9 複用功能配置這一小節時發現瞭如下的表格。
按照上面給出的配置,寫好程式:
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);
- /* Configure USART Tx as alternate function push-pull */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /* Configure USART Rx as input floating */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
再次測試,一切正常。
傳送一個字元的函式可以這麼寫:
- void UART_PutChar(USART_TypeDef* USARTx, uint8_t Data)
- {
- while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET ) {};
- USART_SendData (USARTx, Data);
- }
傳送字串的函式如下:
- void UART_PutStr (USART_TypeDef* USARTx, uint8_t *str)
- {
- while (0 != *str)
- {
- UART_PutChar(USARTx, *str);
- str++;
- }
- }
上面串列埠初始化的程式碼可以放到一個函式中:
- void USART2_init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
- /* Configure USART Tx as alternate function push-pull */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- /* Configure USART Rx as input floating */
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- USART_InitStructure.USART_BaudRate = 9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART2, &USART_InitStructure );
- USART_Cmd(USART2, ENABLE);
- }
今天先寫這麼多。接收字元的函式與傳送字元的函式差不多,但是這種輪詢方式效率很低,不建議使用。下次寫一篇介紹如何用中斷方式傳送接收串列埠資料,中斷方式的效率會高很多。如果有時間再寫一篇DMA方式傳送接收資料的文章。
相關推薦
STM32F10x USART串列埠對映功能實現串列埠通訊 485初始化
這篇文章很有用!新手不要自以為是,STM32串列埠管腳重對映小樣你會嗎??? STM32F10x 系列微控制器中都包含了USART 模組,所謂USART,就是通用同步非同步收發器。通用同步非同步收發器(USART)提供了一種靈活的方法與使用工業標準NRZ非同步序列資料格
STM32 USB Virtual COM USB轉串列埠的功能實現
/* USB標準裝置描述符*/ constuint8_tVirtual_Com_Port_DeviceDescriptor[VIRTUAL_COM_PORT_SIZ_DEVICE_DESC]= { 0x12,/*bLength:長度,裝置描述符的長度為18位元組*/ USB_DEVICE_DESC
python實戰串列埠助手---4實現串列埠功能
import sysimport threadingimport timeimport serialimport binasciiimport logging class serDeal(object): def __init__(self, Port="COM4", BaudRate="9600",
無需埠對映,實現外部網路訪問Docker叢集內部服務
注意:讀這篇文章之前最好先看看這個文章 https://blog.csdn.net/czk740960212/article/details/80393825背景Docker支援埠對映,即將主機的某一埠對映到容器的埠,這樣對主機這一埠的請求就會被轉發到容器內,實現外部網路與
內網ip埠對映外網ip+埠
時,先有DNS伺服器將域名翻譯成IP然後再訪問的。在adsl流行的現在,10多個人共用一個IP,那就意味這十多臺電腦中只能存在一臺對外提供網路服務的主機。剩下的通過主機連線上網。要讓剩下的這些機器都對外提供服務,則必須將擁有公網IP的主機接收到的請求轉發到內網的某一臺主機上,這就是埠對映!下面介紹一下埠對映
Nginx80埠轉發+域名——實現IP+埠隱藏
一.目的 1.相信大家會遇到這樣的問題:當一臺伺服器部署多個tomcat應用時,當我們訪問tomcat時,需要在瀏覽器中輸入伺服器IP+埠號,這看起來非常的low。 二. 環境 1臺服務伺服器 假如IP:192.168.1.10 一個ngnix 使
通過ssh將mysql伺服器埠對映到本機埠
一臺mysql伺服器192.168.1.108因安全問題,未開啟遠端資料訪問,可以通過ssh到服務埠對映到另一臺伺服器192.168.1.188,作為本機埠訪問。 1、在192.168.1.108伺服器上: ssh -R 3306:localhost:3306 [emai
[原創]unity3D學習【功能實現】之三:例項化
用處:一般當場景出現兩個及兩個以上,或者會出現重複的物體的時候,用例項化比較方便 目標:滑鼠點選後,在滑鼠點選的位置出現一個小球 涉及到:預製件,Instantiate(預製件,newVector(
(二)SPI通訊的初始化設定verilog實現
emmmmm,一下子跳到了SPI通訊,跨度有點大,剛好學到這裡,OK少廢話。 相信學過ARM的同學對SPI通訊也有一定的認識,很多模組都需要用到SPI通訊。我就直接用黑金開發板AX301的SPI_Flash例程裡面的SPI_master給大家講解一下。夠良心的啦,黑金開發板
建立一個數組, 實現函式init()初始化陣列, 實現empty()清空陣列、,實現reverse()函式完成陣列元素的逆置。自己設計函式的引數,返回值。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> void init(int arr[], int len) { for (int i = 0; i < len; ++i)
c++ 實現順序棧類(初始化,入棧,退棧。讀棧頂元素以及順序輸出棧頂指標與棧中的元素
/* 定義順序棧類(初始化,入棧,退棧。讀棧頂元素以及順序輸出棧頂指標與棧中的元素 */ #include<iostream> using namespace std; // template <class T> class sq_Stack {
redis叢集實現(一)叢集架構與初始化
redis是一個高可用、高效能、高可擴充套件性的基於記憶體也支援持久化儲存的kv儲存資料庫,redis相比較於之前的kv儲存memcached而言,不但支援的value型別大大增加,並且還支援資料的持久化,彌補了memcached的不能持久化的缺點,但是在3.0之前的red
stm32f103串列埠實現對映功能
在實際開發中,經常遇到串列埠的預設輸出IO口被其他模組佔用了,所以我們要用到串列埠IO口對映功能,是指將原來實現功能的IO口對映到其他指定IO口,其他不變。具體操作如下: 先貼出預設下的串列埠初始化設定: void USART1Conf(u32 baudRate) { U
c實現功能(13)實現單向連結串列的簡要功能
#include <stdio.h> #include <stdlib.h> //利用結構體建立節點 struct list{ //建立資料域 int data; //建立指標域 struct list *next; }; //實現建立一個
RTOS_TINY中實現串列埠傳送字串控制LED
題目內容 在RTOS_TINY作業系統下實現以下目標: 有四個LED,使用AT89S52的4個引腳驅動它們分別以5Hz,8Hz,20Hz,32Hz的頻率閃爍。設使用12MHz的晶振。用串列埠助手,通過傳送 “TURN on 1”,使得LED1持續閃爍,並回顯“LED1 on”;傳送
C++實現串列埠通訊上位機軟體
串列埠使用的是RS232匯流排進行通訊,通訊方式是半雙工。有兩種方式可以實現串列埠通訊,一種是通過ActiveX控制元件這種方法程式簡單,但欠靈活。第二個是可以通過呼叫Windows的API函式,本例程通過第二種方式。 一般通過四步來完成通訊(1)開啟串列埠(2)配置串列埠(3)讀寫串列埠(4)
【C語言實現串列埠通訊知識點整理(四)】關於執行緒和程序
轉載:https://www.cnblogs.com/fuchongjundream/p/3829508.html 因為在外部檔案中呼叫結構體沒有用extern修飾,導致獲取不到正確的值,一直糾結線上程上。現在大概總結執行緒和程序的特點: 概念 1、程序(process) 狹義定義:
【C語言實現串列埠通訊知識點整理(三)】串列埠開啟、設定資料成功後進行資料讀寫
int OpenDev(char *Dev) { int fd = open(Dev,O_RDWR | O_NOCTTY | O_NONBLOCK); if(-1 == fd) { perror("Can't Open Serial Port"); return -1;
【C語言實現串列埠通訊知識點整理(二)】遇到的問題整理(待續....)
1.c編譯錯誤--error:stray \357 in program UTF-8編碼問題。UTF-8編碼有BOM和無BOM格式。BOM,ByteOrderMark(位元組標記順序),表明使用UTF8來進行編碼。UTF-8的BOM通常為3個位元組EF BB BF。轉換成對應的字元檢視,就是‘\
【C語言實現串列埠通訊知識點整理(一)】執行緒、開啟串列埠、設定波特率、設定校驗位、互斥鎖等實現基本的通訊
部分程式碼借鑑地址:https://blog.csdn.net/wangqingchuan92/article/details/73497354/ 謝謝! 1.建立執行緒線上程內進行串列埠之間的收發 void CREAT_pthread(void) { pthr