STM32F427VIT6串口8接收不到数据,可以发送数据?
使用的型号是STM32F427VIT6,在使用串口8的时候,发现接收不到数据,但是可以发送数据。于是用STM32CubeMX只生成UART8的串口代码作为测试,在测试过程中,同样也是可以发数据,但是外接串口发数据时,单片机没有进入串口接收中断,也就是并没有收到数据(于是开始了漫长的找BUG之路,这是一条不归路....)。启动Keil的调试功能,发现打断点也没有进入串口接收中断。于是用示波器打波形,用电脑外接串口调试助手USB转串口,设置不停发数据,先不接单片机的串口8的接收引脚,USB转串口的TX引脚有波形,一接上单片机的RX引脚(当然也共地线了),示波器波形立刻直接拉低,没有任何波形。后来又尝试在串口接收中断中加入清除ORE中断,然后在判断RXNE中断的到来,再去接收数据,发现这样可以接到数据。在去尝试其他串口的收发,一切正常,没有发现类似的问题。换了好几块同样的芯片,发现少数芯片没有这样的问题,多数芯片会遇到同样的问题。于是困惑来了:1.为什么STM32F427VIT6唯独串口8接收不到数据,其它串口都是好的呢? 2.为什么串口8必须先清除ORE中断才能正常接收数据? 3.为什么同样的芯片有些串口8又可以正常使用呢?你说的“一接上单片机的RX引脚,示波器波形立刻拉低”,看样子,这个RX管脚是输出状态,两个输出干架了,USB转串口的TTL信号完败。
手头没有STM32F427VIT6,无法给你试。
再用示波器观察一下,当清除ORE中断后,能正常收数据的时候,单片机RX引脚的波形是什么样的,幅度、上升下降沿有没有有没有异常,连续发0x55,看看波特率高低电平宽度是否一致。 toofree 发表于 2018-1-23 00:21
你说的“一接上单片机的RX引脚,示波器波形立刻拉低”,看样子,这个RX管脚是输出状态,两个输出干架了,US ...
我换过一次片子,在想用以前的代码,通过清除ORE标志来接收数据,发现已经不行了,现在仍然可以发数据,还是接收不到数据,也没有进入串口接收回调函数。如果发送数据,会进入发送回调函数。这个芯片的串口8感觉很奇怪。 l546863256 发表于 2018-1-23 17:37
我换过一次片子,在想用以前的代码,通过清除ORE标志来接收数据,发现已经不行了,现在仍然可以发数据, ...
任何时候都不要怀疑芯片,有毒。
你说的那种现象,90%都是你配置有问题。除非你的芯片手册明确说有此问题。
亮出你的配置代码吧。
从你说的现象看,你的RX的确是输出状态了,不要太依赖cubemax,先把IO口配置好,再看现象! Inc_brza 发表于 2018-1-23 18:48
任何时候都不要怀疑芯片,有毒。
你说的那种现象,90%都是你配置有问题。除非你的芯片手册明确说有此问题 ...
先上Cube的配置(源码附件上传不了,我直接上代码),都是一些常规的配置下面是代码:
/**
******************************************************************************
* File Name : main.c
* Description : Main program body
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2017 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
#include "usart.h"
#include "gpio.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
int uart8_Rx_cnt = 0;
int uart8_Tx_cnt = 0;
uint8_t TxBuf[] = "Hello";
uint8_t RxBuf[] = {0};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_UART8_Init();
/* USER CODE BEGIN 2 */
__HAL_UART_ENABLE_IT(&huart8,UART_IT_RXNE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_UART_Transmit_IT(&huart8,TxBuf,6);
HAL_UART_Receive_IT(&huart8, RxBuf, 8);
HAL_Delay(500);
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USER CODE BEGIN 4 */
/* ´®¿Ú½ÓÊջص÷º¯Êý */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if ( huart->Instance == UART8 )
{
uart8_Rx_cnt++;
}
}
/* ´®¿Ú·¢Ëͻص÷º¯Êý */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if ( huart->Instance == UART8 )
{
uart8_Tx_cnt++;
}
}
/* USER CODE END 4 */
/**
* @briefThis function is executed in case of error occurrence.
* @paramNone
* @retval None
*/
void _Error_Handler(char * file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
下面是GPIO的初始化代码
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
}
接下来是串口初始化的代码:
/* UART8 init function */
void MX_UART8_Init(void)
{
huart8.Instance = UART8;
huart8.Init.BaudRate = 115200;
huart8.Init.WordLength = UART_WORDLENGTH_8B;
huart8.Init.StopBits = UART_STOPBITS_1;
huart8.Init.Parity = UART_PARITY_NONE;
huart8.Init.Mode = UART_MODE_TX_RX;
huart8.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart8.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart8) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/**
* @briefInitializes the UART mode according to the specified parameters in
* the UART_InitTypeDef and create the associated handle.
* @paramhuart: pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if(huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
{
/* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
}
else
{
assert_param(IS_UART_INSTANCE(huart->Instance));
}
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
if(huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
/* Init the low level hardware */
HAL_UART_MspInit(huart);
}
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the peripheral */
__HAL_UART_DISABLE(huart);
/* Set the UART Communication parameters */
UART_SetConfig(huart);
/* In asynchronous mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN, HDSEL and IRENbits in the USART_CR3 register.*/
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
/* Enable the peripheral */
__HAL_UART_ENABLE(huart);
/* Initialize the UART state */
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState= HAL_UART_STATE_READY;
huart->RxState= HAL_UART_STATE_READY;
return HAL_OK;
}我的想法是通过电脑端的串口调试助手每100ms不停的发送数据,查看串口8的接收回调函数HAL_UART_RxCpltCallback是否进入了,通过判断uart8_Rx_cnt是否在增加,通过观察一直没看到uart8_Rx_cnt的数值增加,打断点也没有进去。我在while循环中不停发送数据,可以看到发送回调函数HAL_UART_TxCpltCallback的uart8_Tx_cnt的数值不停的在增加。这说明串口没有收到数据。我又尝试过HAL_UART_Receive_IT(&huart8, RxBuf, 8);也没看到RxBuf有数值,RxBuf的数值一直是0。我又去看串口的中断函数,下面是我之前通过清除串口ORE中断标志,在去接收数据的代码:
/**
* @brief This function handles UART8 global interrupt.
*/
/* Test code */
uint8_t uc_receive_data = {0}, uc_index = 0, uc_receive_cnt = 0;
void UART8_IRQHandler(void)
{
/* USER CODE BEGIN UART8_IRQn 0 */
/* Test UART* code */
if(SET == __HAL_UART_GET_FLAG(&huart8, UART_FLAG_ORE))
{
__HAL_UART_CLEAR_OREFLAG(&huart8);
}
if(SET == __HAL_UART_GET_FLAG(&huart8, UART_FLAG_RXNE)) {
uc_receive_data[++uc_index] = huart8.Instance->DR;
uc_index = uc_index%35;
uc_receive_cnt++;
}
/* USER CODE END UART8_IRQn 0 */
//HAL_UART_IRQHandler(&huart8);
/* USER CODE BEGIN UART8_IRQn 1 */
/* USER CODE END UART8_IRQn 1 */
}现在换了一个芯片之后还是接收不到数据。请大神帮我看下,谢谢!(由于网络原因,一直没有及时回复。)
GPIO初始化代码不全,没有对GPIO进行完整的配置 qiutiandeqiu 发表于 2018-1-28 16:30
GPIO初始化代码不全,没有对GPIO进行完整的配置
代码是全的,因为我只初始化了UART8,串口8的初始化就在MX_UART8_Init();里面。MX_GPIO_Init();只需要开启时钟就行了。 有没有谁用过这个片子?对于我所遇到的串口8的问题谁能帮我解答下:'( l546863256 发表于 2018-1-23 17:37
我换过一次片子,在想用以前的代码,通过清除ORE标志来接收数据,发现已经不行了,现在仍然可以发数据, ...
有没有帮我看下,拿个STM32F427VIT6的片子,用一下串口8,这种奇怪的现象你也可以看得到。 l546863256 发表于 2018-1-29 10:08
代码是全的,因为我只初始化了UART8,串口8的初始化就在MX_UART8_Init();里面。MX_GPIO_Init();只需要开 ...
PE0和PE1的初始化代码贴出来,我在已经贴出来的代码中没有找到。
MX_UART8_Init();是对串口的参数进行初始化, MX_GPIO_Init();里面只有GPIO时钟使能,并没有对UART8使用的GPIO(PE0,PE1)进行初始化。
以下是一段没用Cube的串口初始化代码,楼主可以看一下:
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
//USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
页:
[1]
2