中間商網(wǎng)站怎么做市場調(diào)研報告包括哪些內(nèi)容
【?聲明:版權(quán)所有,歡迎轉(zhuǎn)載,請勿用于商業(yè)用途。 聯(lián)系信箱:feixiaoxing @163.com】
? ? ? ? 前面學(xué)習(xí)103和407的時候,當(dāng)時學(xué)過串口的收發(fā)。不過當(dāng)時使用的主要是阻塞的方式。這一次,我們看下應(yīng)該怎么利用中斷的形式進(jìn)行數(shù)據(jù)的收發(fā)。不僅如此,我們還可以看下,怎么把收到的數(shù)據(jù)放在一起,當(dāng)成一個完整的命令去處理。
1、基本串口信息定義
? ? ? ? 這邊的串口主要還是利用a9、a10來實(shí)現(xiàn)數(shù)據(jù)的收發(fā),其中a9負(fù)責(zé)數(shù)據(jù)的發(fā)送,a10負(fù)責(zé)數(shù)據(jù)的接收。除此之外,數(shù)據(jù)是采用中斷的形式進(jìn)行處理的。
#define DEBUG_USART USART1
#define DEBUG_USART_CLK_ENABLE() __USART1_CLK_ENABLE();#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_RX_PIN GPIO_PIN_10
#define DEBUG_USART_RX_AF GPIO_AF7_USART1#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_TX_PIN GPIO_PIN_9
#define DEBUG_USART_TX_AF GPIO_AF7_USART1#define DEBUG_USART_IRQHandler USART1_IRQHandler
#define DEBUG_USART_IRQ USART1_IRQn
2、串口的初始化
? ? ? ? 串口的初始化這邊基本上就是八股文,基本上按照套路下就可以了。一般就是配置時鐘、配置gpio、配置uart、配置中斷。對于我們來說,最重要的baudrate,也就是波特率,就是在這里配置的。
void DEBUG_USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct;RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;DEBUG_USART_RX_GPIO_CLK_ENABLE();DEBUG_USART_TX_GPIO_CLK_ENABLE();RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);DEBUG_USART_CLK_ENABLE();GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct); UartHandle.Instance = DEBUG_USART;UartHandle.Init.BaudRate = 115200;UartHandle.Init.WordLength = UART_WORDLENGTH_8B;UartHandle.Init.StopBits = UART_STOPBITS_1;UartHandle.Init.Parity = UART_PARITY_NONE;UartHandle.Init.Mode = UART_MODE_TX_RX;UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;UartHandle.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;HAL_UART_Init(&UartHandle);HAL_NVIC_SetPriority(DEBUG_USART_IRQ, 0, 0);HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ);__HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);
}
3、函數(shù)重定向
? ? ? ? 對于喜歡用getchar、printf進(jìn)行數(shù)據(jù)收發(fā)的同學(xué),一般還需要實(shí)現(xiàn)一下fputc、fgetc這兩個函數(shù)。實(shí)現(xiàn)了這兩個函數(shù),后續(xù)就可以使用getchar和printf了。
void Usart_SendString(uint8_t *str)
{unsigned int k=0;do {HAL_UART_Transmit( &UartHandle,(uint8_t *)(str + k) ,1,1000);k++;} while(*(str + k)!='\0');}int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 1000); return (ch);
}int fgetc(FILE *f)
{ int ch;HAL_UART_Receive(&UartHandle, (uint8_t *)&ch, 1, 1000); return (ch);
}
4、中斷處理
? ? ? ? 配置好了uart屬性部分,下面就是中斷處理。這里中斷是一個數(shù)據(jù)、一個數(shù)據(jù)進(jìn)行接收的,實(shí)際處理的時候,一般是進(jìn)入中斷之后循環(huán)接收數(shù)據(jù),直到?jīng)]有新的數(shù)據(jù)收到為止。
extern uint8_t Rxflag;
extern uint8_t ucTemp;void DEBUG_USART_IRQHandler(void)
{if(__HAL_UART_GET_IT( &UartHandle, UART_IT_RXNE ) != RESET){ Rxflag=1; HAL_UART_Receive(&UartHandle, (uint8_t *)&ucTemp, 1, 1000); }HAL_UART_IRQHandler(&UartHandle);
}
? ? ? ? 代碼中Rxflag是標(biāo)志位,ucTemp代表實(shí)際接收到的數(shù)據(jù)。
5、接收數(shù)據(jù)實(shí)際處理
? ? ? ? 單個接收到的數(shù)據(jù)一般是沒有辦法直接處理的,通常都是收集到一塊來處理。處理結(jié)束的標(biāo)志一般就是回車換行符,或者是某個特殊的標(biāo)志也可以的。
while (1){if(Rxflag){if (usRxCount < sizeof(ucaRxBuf)){ucaRxBuf[usRxCount++] = ucTemp;}else{usRxCount = 0;}if (ucTemp == 0x0A) { HAL_UART_Transmit( &UartHandle, (uint8_t *)ucaRxBuf,usRxCount,1000 );usRxCount = 0;}Rxflag=0;__HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE); }}
? ? ? ? 這邊做的比較簡單,整個while(1)部分是放在main函數(shù)里面的。如果Rxflag為1,那么把接收到的數(shù)據(jù)放到ucaRxBuf里面。接著檢查數(shù)據(jù)是不是0x0a,也就是換行,如果是,就把數(shù)據(jù)發(fā)送回去。最后把Rxflag重新置0,打開串口接收中斷,準(zhǔn)備新的數(shù)據(jù)進(jìn)來。
? ? ? ? 大家如果做的復(fù)雜一點(diǎn),數(shù)據(jù)上面可以用queue的形式來處理,函數(shù)也可以抽象出來,實(shí)現(xiàn)部分做成parse command的形式,這樣處理起來就會簡單的多。另外,數(shù)據(jù)接收部分要盡快打開中斷。
6、測試和驗(yàn)證
? ? ? ? 測試就比較簡單了,直接把代碼編譯、下載后,利用ATK-XCOM上位機(jī)打開串口,輸入123、abc這樣的內(nèi)容,看看有沒有回顯就知道代碼對不對了。