機器人工程系列文章目錄
這里羅列了系列文章鏈接
概念總述
STM入門教學
還沒寫完組里急用
文章目錄
- 機器人工程系列文章目錄
- 概念總述
- STM入門教學
- 前言
- 串口
- 串口的概念
- cubemx
- keil5
- 實物實驗
- 關于cubemx生成邏輯
- printf升級
- usart.c
- main.h
- retarget.c
- 定時器
- 定時器的概念
- cubemx
- keil5
- stm32f4xx_it.c
- 關于參考資料
- 參考庫文件
- 參考數據手冊
- 樣例工程
- 參考別人的工程
前言
咳咳,最近出差,手邊沒實物,實物演示等我回實驗室慢慢更
串口
串口的概念
這個東西叫串口,也叫UART或者USART,他是實現單片機交互數據的一種方式,當然可以給你的電腦提供數據交互
觀察他的接口上會寫著TX(transmit)與RX(receive)兩個引腳,分別是他的嘴巴(TX)和他的耳朵(RX),顯而易見的是如果你希望讓兩個單片機進行交流,你需要讓A設備的RX(耳朵)接上B的TX(嘴巴),而B設備的RX(耳朵)接上A的TX(嘴巴)
cubemx
我們首先打開cubemx文件,選擇Connectivity中的USART1,并設置模式為Asynchronous,觀察到右側PA9與PA10被設置為了USART1的RX與TX,點擊生成代碼
keil5
打開main.c文件,并在main文件中相應位置添加
/* USER CODE BEGIN 2 */uint8_t usart1_tx_buf[] = "Hello world\r\n";/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_UART_Transmit(&huart1, usart1_tx_buf, sizeof(usart1_tx_buf), 0xffff);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
編譯并下載
實物實驗
打開設備管理器,如果你已經正常安裝了各個驅動設備,你大概能看見
打開XCOM,選擇
按下單片機的RST按鈕
關于cubemx生成邏輯
cubemx的功能是為了幫助你完成大部分的底層邏輯配置,并為提供大量的庫函數支持。
通常cubemx會幫你修改你的工程和代碼,考慮到用戶和cubeMX修改的內容不同,所以文件做了區分,
對于cubeMX生成的文件而言
printf升級
HAL_UART_Transmit();看起來不是很好用,我們會想能不能像平常寫C語言一樣簡單地輸出字符。
首先打開usart.c,并在文件最下方加入
usart.c
/* USER CODE BEGIN 1 */
int sendchar (int ch){HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 0xffff);return ch;
}
/* USER CODE END 1 */
以及main.h中加入
main.h
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
在文件管理器增加retarget.c文件,并用文本編輯器加入下述文字
retarget.c
#include <stdio.h>
#include <rt_misc.h>//#pragma import(__use_no_semihosting_swi)//ARM Compiler62??戝import£???a??μ??aoˉ?
__asm(".global __use_no_semihosting");extern int sendchar(int ch); /* in Serial.c */
//extern int getkey(void); /* in Serial.c */
extern long timeval; /* in Time.c *///struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;int fputc(int ch, FILE *f) {return (sendchar(ch));
}//int fgetc(FILE *f) {
// return (sendchar(getkey()));
//}int ferror(FILE *f) {/* Your implementation of ferror */return EOF;
}void _ttywrch(int ch) {sendchar (ch);
}void _sys_exit(int return_code) {while (1); /* endless loop */
}
回到keil中,雙擊Application/User/Core,將retarget.c添加到工程中,當然你也可以靠keil中的新建文件去添加,可以自己試試
接下來你可以將while里的函數做一定替換,可以更加方便的完成通訊。
/* USER CODE BEGIN 2 */uint8_t usart1_tx_buf[] = "Hello world\r\n";/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){printf("Hello World\r\n");//HAL_UART_Transmit(&huart1, usart1_tx_buf, sizeof(usart1_tx_buf), 0xffff);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
定時器
定時器的概念
比如你現在要看管一個鍋爐,每一小時需要放氣一次,放氣的工作需要花費你一分鐘。你會有以下幾種情況
- 你可以拿著一個計時器,每當計滿一小時后,你去放一次氣,這樣每次放氣的循環會維持在61分鐘,長期這么做設備可能就會出現損壞。
- 你可以估算下自己放氣的時間,如果是一分鐘的話,我用計時器計算59分鐘,這樣循環可以穩定在60分鐘。
- 你現在不止有放氣的一個任務,你還需要加煤,還需要加水,還需要寫報告,而且每個任務消耗的你時間是不確定的,可能是2分鐘,可能是10分鐘。為了更準確保證一小時放一次氣,你決定選一個鬧鐘,每一小時提醒你做一輪工作。
定時器的核心功能體現在可以保證任務按照一定頻率的完成,實際上單片機運行過程中任務時長是不確定的,為了確定一個穩定的工作頻率,定時器的引入是必須的。
cubemx
選擇Timers中的TIM11,勾選Activated。
Prescaler中寫為99,我們上一章設置主時鐘為100Mhz,意味著單片機一刻時鐘為0.01us,但通常高頻會造成更高的能耗,因此需要根據實際需求進行降頻并分配給子定時器。寫為99實際為100,這是因為程序通常從0開始計數,因此100Mhz會被分頻100轉換為1Mhz,也就是1us作為時鐘的一刻。
Counter Period設置為999,這意味著我們計數1000則重新開始計數,也就意味著這個定時器每1ms就會自動刷新一次。
這還不夠,定時器會單獨在那運行,但他不會提醒你,因此選擇NVIC Setting中,設置定時器中斷開啟,這樣每1ms都會被提醒完成一次工作。
keil5
所以中斷會怎么被提醒去工作呢,在stm32
做如下修改
stm32f4xx_it.c
void TIM1_TRG_COM_TIM11_IRQHandler(void)
{/* USER CODE BEGIN TIM1_TRG_COM_TIM11_IRQn 0 */static uint32_t counter;counter++;if(counter>999)counter=0;printf("Hello World\r\n");/* USER CODE END TIM1_TRG_COM_TIM11_IRQn 0 */HAL_TIM_IRQHandler(&htim11);/* USER CODE BEGIN TIM1_TRG_COM_TIM11_IRQn 1 *//* USER CODE END TIM1_TRG_COM_TIM11_IRQn 1 */
}
關于參考資料
寫到現在比較困惑的一個問題是,這些東西我怎么理解?有哪些功能?有哪些函數?通過ST官方文件我們可以做如下了解。
參考庫文件
函數右鍵Go to the Definition可以進入庫函數定義文件,可以閱讀英文注釋了解函數具體使用。
參考數據手冊
cubemx的Help->Docs&Resources,會有大量的stm32數據手冊,可以多多參考閱讀。
Description of STM32F4 HAL and low-layer drivers
樣例工程
除了上述文檔,ST提供了相關的工程文件作為參考
通常目錄會放在
C:\用戶\STM32Cube\Repository
其中的文件夾中有對應版本庫的相關資料,包含了大部分HAL庫與LL庫的使用范例,就不用頭疼的全網找資料了(一個個打開來看看吧)
參考別人的工程
學習學習別人的工作,了解了解別人如何應用設備芯片,可以幫助你更快的搭建自己的工程