www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 嵌入式 > 嵌入式云IOT技術圈
[導讀]之前買了一塊評估板,也寫了相應的評測文章,鏈接如下: TKM32F499高性能MCU評估板試用之萬事開頭難,先點個燈來壓壓驚! 我們在上面這篇文章已經(jīng)領會了TKM32F499的強大了,接下來進入主題,串口通信實驗。 1、TKM32F499通用異步收發(fā)器(UART)數(shù)據(jù)結(jié)構(gòu)及參數(shù)描

之前買了一塊評估板,也寫了相應的評測文章,鏈接如下:

TKM32F499高性能MCU評估板試用之萬事開頭難,先點個燈來壓壓驚!

我們在上面這篇文章已經(jīng)領會了TKM32F499的強大了,接下來進入主題,串口通信實驗。

1、TKM32F499通用異步收發(fā)器(UART)數(shù)據(jù)結(jié)構(gòu)及參數(shù)描述

在UART庫的頭文件里,UART由一個結(jié)構(gòu)體進行維護:

typedef struct
{
//波特率
uint32_t UART_BaudRate;
//數(shù)據(jù)長度
uint16_t UART_WordLength;
//停止位
uint16_t UART_StopBits;
//校驗位
uint16_t UART_Parity;
//模式
uint16_t UART_Mode;
//硬件流控
uint16_t UART_HardwareFlowControl;
} UART_InitTypeDef;

1.1 波特率

波特率是由波特率發(fā)生器產(chǎn)生的,這是一個專用16位的,UART波特率寄存器控制16 位自由運轉(zhuǎn)的計數(shù)器的計數(shù)周期。提供期望的波特率和 Fosc(APB 時鐘頻率)

X = SPBRG 寄存器值 (1 to 65535)


1.2 數(shù)據(jù)長度

/** @defgroup UART_Word_Length
* @{
*/
#define UART_WordLength_5b ((uint16_t)0x0000)
#define UART_WordLength_6b ((uint16_t)0x0010)
#define UART_WordLength_7b ((uint16_t)0x0020)
#define UART_WordLength_8b ((uint16_t)0x0030)

一般在工程應用中都是選擇UART_WordLength_8b

1.3 停止位

/** @defgroup UART_Stop_Bits
* @{
*/

#define UART_StopBits_1 ((uint16_t)0x0000)
#define UART_StopBits_2 ((uint16_t)0x0004)

#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_StopBits_1) || \
((STOPBITS) == UART_StopBits_2))

一般在工程應用中都是選擇UART_StopBits_1

1.4 校驗位

/** @defgroup UART_Parity
* @{
*/
#define UART_Parity_No ((uint16_t)0x0000)
#define UART_Parity_Even ((uint16_t)0x0003)
#define UART_Parity_Odd ((uint16_t)0x0001)
#define IS_UART_PARITY(PARITY) (((PARITY) == UART_Parity_No) || \
((PARITY) == UART_Parity_Even) || \
((PARITY) == UART_Parity_Odd))

一般在工程應用中都是選擇UART_Parity_No(無校驗)

1.5 串口模式

/** @defgroup UART_Mode
* @{
*/

#define UART_Mode_Rx ((uint16_t)0x0008)
#define UART_Mode_Tx ((uint16_t)0x0010)
#define IS_UART_MODE(MODE) ((((MODE) & (uint16_t)0xFFE7) == 0x00) && ((MODE) != (uint16_t)0x00))

這個指的是當前串口為可接收還是可發(fā)送,可以同時擁有,也可以單個選擇,具體根據(jù)項目需求制定。

1.6 硬件流控

/** @defgroup UART_Hardware_Flow_Control
* @{
*/
#define UART_HardwareFlowControl_None ((uint16_t)0x0000)

#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
(((CONTROL) == UART_HardwareFlowControl_None) || \
((CONTROL) == UART_HardwareFlowControl_RTS) || \
((CONTROL) == UART_HardwareFlowControl_CTS) || \
((CONTROL) == UART_HardwareFlowControl_RTS_CTS))

一般工程應用中會直接將這個設置為UART_HardwareFlowControl_None 在HAL_uart.h庫文件中提供了一系列操作接口:

void UART_DeInit(UART_TypeDef* UARTx);
void UART_Init(UART_TypeDef* UARTx, UART_InitTypeDef* UART_InitStruct);
void UART_StructInit(UART_InitTypeDef* UART_InitStruct);
void UART_Cmd(UART_TypeDef* UARTx, FunctionalState NewState);
void UART_ITConfig(UART_TypeDef* UARTx, uint16_t UART_IT, FunctionalState NewState);
void UART_DMACmd(UART_TypeDef* UARTx, uint16_t UART_DMAReq, FunctionalState NewState);
void UART_SendData(UART_TypeDef* UARTx, uint16_t Data);
uint16_t UART_ReceiveData(UART_TypeDef* UARTx);
FlagStatus UART_GetFlagStatus(UART_TypeDef* UARTx, uint16_t UART_FLAG);
void UART_ClearFlag(UART_TypeDef* UARTx, uint16_t UART_FLAG);
ITStatus UART_GetITStatus(UART_TypeDef* UARTx, uint16_t UART_IT);
void UART_ClearITPendingBit(UART_TypeDef* UARTx, uint16_t UART_IT);

跟STM32操作類似,我們直接調(diào)就完了,不明白的地方直接看數(shù)據(jù)手冊解決!

2、TKM32F499通用異步收發(fā)器(UART)使用

使用串口功能之前,還是一樣,先確定我這邊的需求,我這邊需要接收一串以下格式的數(shù)據(jù):

序號 信號值 差值\r\n

這個數(shù)據(jù)是我手上傳感器發(fā)過來的數(shù)據(jù),然后我用TKM32F499進行接收。

1、配置一路串口用于printf輸出,這里選擇UART4

電路原理圖如下:

根據(jù)原理圖寫出以下初始化函數(shù):

/*用于調(diào)試打印*/
void Uart4Init(int BaudRate)
{
UART_InitTypeDef UART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 復用推挽輸出
GPIO_Init(GPIOD, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入

GPIO_Init(GPIOD, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOD, GPIO_Pin_6 | GPIO_Pin_7, GPIO_AF_UART_2345);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART4, ENABLE);
UART_InitStructure.UART_BaudRate = BaudRate; //波特率
UART_InitStructure.UART_WordLength = UART_WordLength_8b;//數(shù)據(jù)位
UART_InitStructure.UART_StopBits = UART_StopBits_1;//停止位
UART_InitStructure.UART_Parity = UART_Parity_No ;
UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;//輸入輸出模式
UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
UART_Init(UART4, &UART_InitStructure);
UART_Cmd(UART4, ENABLE); //UART 模塊使能

UART_ClearITPendingBit(UART4, 0xff);
}

調(diào)試不用增加接收功能,所以不需要寫接收回調(diào)函數(shù),但需要寫一個串口重定向,并把微庫勾上才能使用printf。

編寫重定向函數(shù):

int fputc(int ch, FILE *f)
{
while((UART4->CSR & 0x1) == 0) {}
UART4->TDR = (u8) ch;
return ch;
}

2、配置一路串口用于接收傳感器數(shù)據(jù)(這里選擇接UART1)

電路原理圖如下:

實現(xiàn)代碼邏輯:

/*用于接收傳感器數(shù)據(jù)*/
void Uart1Init(int BaudRate)
{
UART_InitTypeDef UART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //uart1_tx pa9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 推挽復用輸出
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //uart1_rx pa10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_Pin_9 | GPIO_Pin_10, GPIO_AF_UART_1); //PA9、PA10復用為串口1
GPIO_PinAFConfig(GPIOA, GPIO_Pin_15, GPIO_AF_GPIO); //PA15復用為普通GPIO

RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE);
UART_InitStructure.UART_BaudRate = BaudRate; //波特率
UART_InitStructure.UART_WordLength = UART_WordLength_8b;//數(shù)據(jù)位
UART_InitStructure.UART_StopBits = UART_StopBits_1;//停止位
UART_InitStructure.UART_Parity = UART_Parity_No ;
UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;//輸入輸出模式
UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
UART_Init(UART1, &UART_InitStructure);
UART_Cmd(UART1, ENABLE); //UART 模塊使能

UART_ClearITPendingBit(UART1, 0xff);
//這里需要進行接收,所以要打開接收中斷
UART_ITConfig(UART1, UART_IT_RXIEN, ENABLE);//使能接收中斷
NVIC_SetPriority(UART1_IRQn, 3);
NVIC_EnableIRQ(UART1_IRQn);
}

定義回調(diào)函數(shù),編寫接收邏輯,傳感器用一個結(jié)構(gòu)體進行維護:

#define SENSOR_BUFFER_SIZE       42

typedef struct
{
uint8_t BufferReady;
uint16_t Sensor_rx_count ;
uint8_t SensorRxBuffer[SENSOR_BUFFER_SIZE];
uint8_t SensorTxBuffer[SENSOR_BUFFER_SIZE];
} Sensor_HandleTypeDef;
extern Sensor_HandleTypeDef Sensor;

接收回調(diào)函數(shù)處理:

//串口1接收中斷處理函數(shù),打印傳感器數(shù)據(jù)
void UART1_IRQHandler(void)
{
u8 ucCh;

/*當ISR位1為1時,表示接收到有效字節(jié)數(shù)據(jù)*/
if(UART1->ISR & (1 << 1))
{
/*接收到了一個字節(jié)的數(shù)據(jù)*/
ucCh = UART1->RDR;
if('\n' != ucCh)
{
Sensor.SensorRxBuffer[Sensor.Sensor_rx_count++] = ucCh ;
}
else
{
/*如果接收的是\n,則上一個接收的數(shù)據(jù)為'\r'結(jié)束*/
if('\r' == Sensor.SensorRxBuffer[Sensor.Sensor_rx_count - 1])
{
/*添加結(jié)束符*/
Sensor.SensorRxBuffer[Sensor.Sensor_rx_count - 1] = 0x00 ;
/*接收計數(shù)清0*/
Sensor.Sensor_rx_count = 0 ;
Sensor.BufferReady = 1 ;
}
}
/*清除中斷接收標志*/
UART1->ICR |= 1 << 1;
}
}

接收這里主要用到串口的接收數(shù)據(jù)寄存器、中斷狀態(tài)寄存器、中斷清除寄存器

接收數(shù)據(jù)在程序里就是一個RDR的寄存器。其中在接收邏輯里需要去判斷接收數(shù)據(jù)有效,最重要的是位1:

在每次收到一次有效數(shù)據(jù),即發(fā)生了一次串口接收中斷,我們接收完數(shù)據(jù)后需要及時對中斷標志進行清除,這里最重要的是第一位:這些寄存器都是通過一個結(jié)構(gòu)體進行維護:

/**
* @brief Universal Synchronous Asynchronous Receiver Transmitter
*/

typedef struct
{
__IO uint32_t TDR;
__IO uint32_t RDR;
__IO uint32_t CSR;
__IO uint32_t ISR;
__IO uint32_t IER;
__IO uint32_t ICR;
__IO uint32_t GCR;
__IO uint32_t CCR;
__IO uint32_t BRR;
__IO uint32_t FRABRG;

} UART_TypeDef;

具體使用方法請參考TKM32F499的芯片數(shù)據(jù)手冊,當然如果不習慣用寄存器進行操作,也可以使用好炬潤官方的HAL lib,調(diào)用相應的庫函數(shù)。串口應用邏輯編寫完畢以后,接下來我們在主函數(shù)的循環(huán)內(nèi)判斷BufferReady標志就可以了:

while(1)
{
if(1 == Sensor.BufferReady)
{
Sensor.BufferReady = 0;
/*解析傳感器數(shù)據(jù)*/
Sensor_Detect_Process(Sensor.SensorRxBuffer);
printf("流水號:%d 信號值:%d 差值:%d\n",sensor_data.Sensor_Serial_Number
,sensor_data.Sensor_TP1_Singal_Value,sensor_data.Sensor_TP1_Devalue
);
LCD_PutString(100, 60, (char *)Sensor.SensorRxBuffer, Red, Yellow, 1);
status = !status;
GPIO_WriteBit(GPIOA,GPIO_Pin_15,status);
}
}

最終效果,這里面還有我的其它邏輯:

如果對該評估板軟件編程感興趣的話,歡迎加我微信私聊交流~

TKM32F499評估板例程及資料下載

鏈接:https://pan.baidu.com/s/1xujEO4vJ7i7UUK7v_fGNgw
提取碼:g1y2

或者后臺回復TK499即可獲取。

往期精彩

bin文件轉(zhuǎn)換為hex文件C語言實現(xiàn)

最近收集的開源項目專欄(持續(xù)更新,收好車輪,方便造車)

推薦三個我工作中經(jīng)常使用的驅(qū)動大全wiki(建議收藏并轉(zhuǎn)發(fā)讓更多人知道!)

變量命名還在谷歌百度翻譯?OUT啦!分享一個我日常工作中常用的變量命名神器!

若覺得本次分享的文章對您有幫助,隨手點[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。

免責聲明:本文內(nèi)容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構(gòu)授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅(qū)動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅(qū)動性能的關鍵。

關鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質(zhì)量和效率直接關系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅(qū)動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關鍵字: LED 驅(qū)動電源 開關電源

LED驅(qū)動電源是把電源供應轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅(qū)動電源
關閉