STM32 cube工程建立和I2C, SPI, UART的簡單介紹
linux 平臺下stm32串口燒錄方法
- Rx, Tx 的跳線帽需要連接, 因爲使用了板載的串口模塊。
- 另外,燒錄時 BOOT 的B0 需要置高, 本機所用版本(stm32f103rct6)
stm32flash
stm32flash -w filename -v -g 0x0 /dev/ttyS0
爲命令加點包裝
- 創建文件 flashstm32.sh
#!/bin/sh
# author:combofish
# email:[email protected]
# Filename: flash_stm32.sh
port="/dev/ttyUSB0"
stm32flash -w $1 -v -g 0x0 $port
- 之後默認以命令加 xx.hex 文件燒錄
flash_stm32 f1rrct6.hex
STM32cubeIDE setting
添加hex output
你先得在工程屬性裏配置輸出hex文件,才能在Debug/Release文件夾下找到對應工程名的hex文件 右擊工程名,屬性->C/C++ Build->IAR Linker for ARM->Output Converter->勾選Generate additional output,並在output format下拉框裏選擇Intel extended
project setting
- Add necessary library files as reference in the toolchain project configuration file.
- Generate peripheral initialization as a pair of ‘.c/ .h’ files per peripheral.
參考鏈接
https://www.cnblogs.com/ChurF-Lin/p/10793111.html
usart
- 通用異步收發傳輸器 (Universal Asynchronous Receiver/Transmitter)
- USART(Universal Synchronous Asynchronous Receiver and Transmitter通用同步異步收發器) USART相當於UART的升級版,USART支持同步模式, 因此USART 需要同步始終信號USARTCK(如STM32 單片機),通常情況同步信號很少使用, 因此一般的單片機UART和USART使用方式是一樣的,都使用異步模式。因爲USART的使用方法上跟UART基本相同,所以在此就以UART來講該通信協議了。
uart 直接發送
int main() {
unsigned char uTx_Data[5] = {0x41, 0x42, 0x43, 0x44, 0x45}; //數組內十六進制代表“ABCDE”
//
while (1) {
//
HAL_UART_Transmit($huart2, uTx_Data, sizeof(uTx_Data), 0xffff);
}
}
-
uart 發送字符串
-
在頭文件添加聲明
void USER_UART_SendString(UART_HandleTypeDef* uartHandle, unsigned char* uData);
-
在對應的 .c 文件添加 函數
void USER_UART_SendString(UART_HandleTypeDef* uartHandle, unsigned char* uData){ while (*uData){ HAL_UART_Transmit(uartHandle, uData, 1, 1000); uData++; } }
-
在 main() 函數的主循環中調用
USER_UART_SendString(&huart2, uTx_Data2); USER_UART_SendString(&huart3, uTx_Data2); HAL_Delay(500);
uart 接收後就發送
-
接受字符串
-
接受後就發送
-
這種接收方式是直接在main函數裏的while循環裏不斷接收,會嚴重佔用程序的進程,且接收較長的數據時,會發生接收錯誤
int main() { unsigned char uRx_Data = 0; // if(HAL_UART_Receive(&huart2, &uRx_Data, 1, 1000) == HAL_OK){ HAL_UART_Transmit(&huart2, &uRx_Data, 1, 1000); } }
接收中斷併發送
-
在 HALUARTMspInit() 中使能中斷
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART2) { /* USER CODE BEGIN USART2_MspInit 0 */ /* USER CODE END USART2_MspInit 0 */ /* USART2 clock enable */ __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART2 interrupt Init */ HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspInit 1 */ //HAL_UART_Receive_IT(&huart2, rData, 1); __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE); /* USER CODE END USART2_MspInit 1 */ } }
-
在 USART1IRQHandler() 中處理數據
void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ unsigned char uRx_Data = 0; HAL_UART_Receive(&huart2, &uRx_Data, 1, 1000); HAL_UART_Transmit(&huart2, &uRx_Data, 1, 0xffff); /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ }
中斷接收,先接收完再去處理
-
在 HALUARTMspInit() 中使能中斷
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART2) { /* USER CODE BEGIN USART2_MspInit 0 */ /* USER CODE END USART2_MspInit 0 */ /* USART2 clock enable */ __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART2 interrupt Init */ HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspInit 1 */ //HAL_UART_Receive_IT(&huart2, rData, 1); __HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE); /* USER CODE END USART2_MspInit 1 */ } }
-
在 USART1IRQHandler() 中處理數據
void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ // 中斷接收和發送 /* unsigned char uRx_Data = 0; HAL_UART_Receive(&huart2, &uRx_Data, 1, 1000); HAL_UART_Transmit(&huart2, &uRx_Data, 1, 0xffff);*/ // 中斷接收完再發送 static unsigned char uRx_Data[1024] = {0}; static unsigned char* pRx_Data = uRx_Data; static unsigned char uLength = 0; HAL_UART_Receive(&huart2, pRx_Data, 1, 1000); if (*pRx_Data == '\n'){ HAL_UART_Transmit(&huart2, uRx_Data, uLength, 0xffff); }else { uLength++; pRx_Data++; } /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ }
參考連接
https://www.cnblogs.com/ChurF-Lin/p/10809000.html https://www.cnblogs.com/ChurF-Lin/p/10809000.html https://www.cnblogs.com/ChurF-Lin/category/1457221.html
spi
SPI 協議 Serial Peripheral Interface 串行外圍設備接口,是一種高速全雙工的通信總線。主要用在MCU與FLASH\ADC\LCD等模塊之間的通信。
4 條總線
- SS Slave Select
片選信號線,當有多個SPI 設備與 MCU 相連時,每個設備的這個片選信號線是與 MCU 單獨的引腳相連的, 而其他的 SCK、MOSI、MISO 線則爲多個設備並聯到相同的 SPI 總線上,低電平有效。
- SCK Serial Clock
時鐘信號線,由主通信設備產生,不同的設備支持的時鐘頻率不一樣,如 STM32 的 SPI 時鐘頻率最大爲 f PCLK /2。
- MOSI Master Output Slave Input
設備輸出 / 從設備輸入引腳。主機的數據從這條信號線輸出,從機由這條信號線讀入數據,即這條線上數據的方向爲主機到從機。
- MISO Maste Input Slave Output
主設備輸入 / 從設備輸出引腳。主機從這條信號線讀入數據,從機的數據則由這條信號線輸出,即在這條線上數據的方向爲從機到主機。
特性
- 單次傳輸可選擇爲 8 或 16 位。
- 波特率預分頻係數(最大爲 fPCLK/2) 。
- 時鐘極性(CPOL)和相位(CPHA)可編程設置。
- 數據順序的傳輸順序可進行編程選擇,MSB 在前或 LSB 在前。 注:MSB(Most Significant Bit)是“最高有效位”,LSB(Least Significant Bit)是“最低有效位”。
- 可觸發中斷的專用發送和接收標誌。
- 可以使用 DMA 進行數據傳輸操作。
cube 配置
- 配好時鐘源
- SPI mode Full-Duplex Master
- Hardware NSS Signal Disable
- PA4 gpiooutput Label SPICS
主要函數
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//發送數據
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//接收數據
參考鏈接
http://news.eeworld.com.cn/mcu/2019/ic-news021243150.html https://blog.csdn.net/u014470361/article/details/79015712
I2C
介紹
- I2C最少只需要兩根線,和異步串口類似,但可以支持多個slave設備。
- 和SPI不同的是,I2C可以支持mul-master系統,允許有多個master並且每個master都可以與所有的slaves通信
(master之間不可通過I2C通信,並且每個master只能輪流使用I2C總線)。
- I2C的數據傳輸速率位於串口和SPI之間,大部分I2C設備支持100KHz和400KHz模式。
- 使用I2C傳輸數據會有一些額外消耗:每發送8bits數據,就需要額外1bit的元數據(ACK或NACK)。
- I2C支持雙向數據交換,由於僅有一根數據線,故通信是半雙工的。
-
地址
- I2C 總線上的每個設備都有自己的獨立地址,主機發起通訊時,通過 SDA 信號線發送設備地址(SLAVEADDRESS)來查找從機。
- I2C 協議規定設備地址可以是7 位或10 位,實際中7 位的地址應用比較廣泛。
- 數據方向
- 數據方向位在設備地址後一位
- “1”——讀,“0”——寫
-
參考鏈接
https://blog.csdn.net/la_fe_/article/details/100315073
#include <stdio.h> #include <string.h> int main(){ unsigned char a[12] = {0}; printf("%s", sizeof(a)); return 0; }
常用函數
/* 第1個參數爲I2C操作句柄
第2個參數爲從機設備地址
第3個參數爲從機寄存器地址
第4個參數爲從機寄存器地址長度
第5個參數爲發送的數據的起始地址
第6個參數爲傳輸數據的大小
第7個參數爲操作超時時間 */
HAL_I2C_Mem_Write(&hi2c2,salve_add,0,0,PA_BUFF,sizeof(PA_BUFF),0x10);
HAL_I2C_Mem_Write_IT();
HAL_I2C_Mem_Read();
HAL_I2C_Mem_Read_IT();
HAL_I2C_Mem_Read_DMA();
HAL_I2C_Mem_Write_DMA();
HAL_I2C_Master_Receive();// STM32 主機接收,不需要用到寄存器地址
HAL_I2C_Master_Receive_IT();//中斷IIC接收
HAL_I2C_Master_Receive_DMA();// DMA 方式的IIC接收
HAL_I2C_Master_Transmit_IT(); //中斷IIC發送
HAL_I2C_Master_Transmit_DMA(); // DMA 方式的IIC發送
HAL_I2C_Master_Transmit(&hi2c2,salve_add,PA_BUFF,sizeof(PA_BUFF),0x10); //STM32 主機發送
HAL_I2C_Slave_Receive();// STM32 從機機接收,不需要用到寄存器地址
HAL_I2C_Slave_Transmit();// STM32 從機機發送,不需要用到寄存器地址
HAL_I2C_Slave_Receive_IT();
HAL_I2C_Slave_Receive_DMA();
HAL_I2C_Slave_Transmit_IT();
HAL_I2C_Slave_Transmit_DMA();
//舉個調用 HAL_I2C_Mem_Write()函數讀取16個字節的使用例子
HAL_I2C_Mem_Read(&hi2c2,U9_Save_Read_Add,ADC_Result_Add,I2C_MEMADD_SIZE_8BIT,Read_buff,2,0xff);
//再舉一個 HAL_I2C_Mem_Read( ) 函數寫16個字節的使用例子
uint8_t Configuration_config[2]={0x09,0xc0};
//設置U9的Configuration寄存器爲 0x09 0xc0
HAL_I2C_Mem_Write(&hi2c2,U9_Save_Write_Add,ADC_Configuration_Add,I2C_MEMADD_SIZE_8BIT,Configuration_config,2,0xff);
- 參考鏈接
https://www.cnblogs.com/xingboy/p/9566247.html