本文共 5736 字,大约阅读时间需要 19 分钟。
今天把stm32的串口配置起来,把经验跟大家共享下
总的函数如下
void USART1Configuration(void)
{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1,ENABLE); USART1_GPIO_Configuration(); USART1_Param_Configuration(); NVIC_Configuration(); /*串口使用中断方式才用到*/ //打开发送接收中断 USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1,ENABLE); /*使能串口*/}
时间配置就不讲了 首先是配置USART的GPIO口 /******************************************************************************* * Name : UART1_GPIO_Configuration * Deion : Configures the uart1 GPIO ports. * Input : None * Output : None * Return : None *******************************************************************************/void USART1_GPIO_Configuration(void)
{ GPIO_InitTypeDef GPIO_InitStructure; // Configure USART1_Tx as alternate push-pull 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);// Configure USART1_Rx as input floating
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); }然后是配置串口参数
/******************************************************************************* * Name : UART1_Configuration * Deion : Configures the uart1 * Input : None * Output : None * Return : None *******************************************************************************/void USART1_Param_Configuration(void)
{ USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure;USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; /* Configure the USART1 synchronous paramters */ USART_ClockInit(USART1, &USART_ClockInitStructure);USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USART1 basic and asynchronous paramters */ USART_Init(USART1, &USART_InitStructure); } 然后是在中断设置,需要修改stm32f10x_it.c 中的串口中断函数 并且需要修改void NVIC_Configuration(void)函数 修改NVIC_Configuration函数 /******************************************************************************* * Name : NVIC_Configuration * Deion : Configures NVIC and Vector Table base location. * Input : None * Output : None * Return : None *******************************************************************************/void NVIC_Configuration(void)
{ NVIC_InitTypeDef NVIC_InitStructure;#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endifNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; /*这个串口中断入口可以查询stm32f10.h得到看有哪些中断入口*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
串口中断处理函数文件
/* Private macro -------------------------------------------------------------*/
#define countof(a) (sizeof(a) / sizeof(*(a)))/* Private variables ---------------------------------------------------------*/
uint8_t TxBuffer[160]; uint8_t RxBuffer[RxBufferSize]; uint8_t NbrOfDataToTransfer = TxBufferSize; uint8_t NbrOfDataToRead = RxBufferSize; uint8_t TxCounter = 0; uint16_t RxCounter = 0; //串口中断void USART1_IRQHandler(void)
{ /*接收中断*/ u16 i; if(USART_GetFlagStatus(USART1,USART_IT_RXNE)== SET) { i = USART_ReceiveData(USART1); USART_SendData(USART1,i); /*回显*/ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } }//发送中断,很少用到 if (USART_GetITStatus(USART1, USART_IT_TXE) == SET) { USART_SendData(USART1, TxBuffer[TxCounter++]); if (NbrOfDataToTransfer==TxCounter) /*最后一个字节不要,因为字符串最后一个是\0*/ { //发送字节结束 USART_ITConfig(USART1, USART_IT_TXE, DISABLE); } } }
至此 串口就可以工作起来了,但是还有很重要一点,就是编译时要打开target-Use MicroLIB勾上,就可以了。 发送中断应该说有两个一个是发送完中断,一个是缓冲区空中断,你说的问题应该是发生在缓冲区空中断中. 当发送一帧数据时,如果发生缓冲区空中断或发送完毕中断时,还有数据要继续发送,那就发送下一个数据,如果数据已经都发送完了,则处理方式上有点区别,如果用缓冲区空中断,则而将中断关闭,如果用发送完毕中断,则直接返回就可以了
但是要用到printf来打印到串口1的话,需要对printf重定向到usart1,printf函数不用到中断
/*******************************************************************************
* Function Name : int fputc(int ch, FILE *f) * Description : Retargets the C library printf function to the USART.printf重定向 * Input : None * Output : None * Return : None *******************************************************************************/ int fputc(int ch, FILE *f) {/* Write a character to the USART */
USART_SendData(USART1, (u8) ch); /* Loop until the end of transmission */ while((USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)) { } return ch; } /******************************************************************************* * Function Name : int fgetc(FILE *f) * Description : Retargets the C library printf function to the USART.fgetc重定向 * Input : None * Output : None * Return : 读取到的字符 *******************************************************************************/ int fgetc(FILE *f) { /* Loop until received a char */ while((USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)) { } /* Read a character from the USART and RETURN */ return (USART_ReceiveData(USART1)); }到这里,usart1就能打印出printf的内容了
转载地址:http://fmxxi.baihongyu.com/