串口操作
蛋疼得很,竟然忘记用NVIC了,太久没有操作STM32的底层了。
这里贴上原子的串口操作---
typedef struct { u8 Timeout; u16 RX_STA; u8 RX_BUF[1024]; //1024 u8 TX_BUF[30]; }Usart; Usart uart1; void nvic() { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel =USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=5; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void init() { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); /* A9 USART1_Tx */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;//GPIO_Mode_IN_FLOATING;// //推挽输出-TX GPIO_Init(GPIOA, &GPIO_InitStructure); /* A10 USART1_Rx */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入-RX GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate =115200; 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_Tx| USART_Mode_Rx; 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; USART_ClockInit(USART1, &USART_ClockInitStructure); USART_Init(USART1, &USART_InitStructure); /* Enable the USARTx */ USART_Cmd(USART1, ENABLE); //串口1使用接收中断 USART_ClearFlag(USART1,USART_FLAG_TC); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//只打开接收中断 } void main()//怎么操作串口,如下 { nvic(); init(); //接收 if((uart1.RX_STA&0x8000)==0x8000) { uart1.RX_BUF[1023]=0;//添加结束符 DBG("%s", uart1.RX_BUF); uart1.RX_STA=0; memset(uart1.RX_BUF,0,sizeof(uart1.RX_BUF)); } //发送,用usart1.TXBUF来发送就是了 } void USART1_IRQHandler(void) { u8 res; if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET) { USART_ClearITPendingBit(USART1,USART_IT_RXNE); res = USART_ReceiveData(USART1); if((uart1.RX_STA &(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据 { if(uart1.RX_STA < 1024) //还可以接收数据 { uart1.Timeout = RECMSGTIMEOUT; //10MS没有数据,则强制封包 uart1.RX_BUF[uart1.RX_STA++] = res; //记录接收到的值 } else { uart1.RX_STA |= 1<<15; //强制标记接收完成 uart1.Timeout = 0; } } } //溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题 if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET) { USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR USART_ReceiveData(USART1); //读DR } } //在定时器中,加入下面这个逻辑,用于上面的RECMSGTIMEOUT //RECMSGTIMEOUT=3 下面设置成10ms,则30ms没有接受到新的数据,则封包 if(uart1.Timeout>0) { uart1.Timeout--; if(uart1.Timeout==0) { uart1.RX_STA|=1<<15; } } //#define ECHO /*定义 fputc 此函数为printf所用*/ int fputc(int ch, FILE *f) { //if(DEBUG) { // #ifdef ECHO // xSemaphoreTake(xMutex,(portTickType)10); while((USART1->SR&0X40) == 0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; // xSemaphoreGive(xMutex); // #endif } return ch; } void uart1_putchar(u8 ch) //发送一个字符 { USART_ClearFlag(USART1,USART_FLAG_TC); USART_SendData(USART1,ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); } void UART1Write(u8 *data,u32 len) //发送n个字符 { if (DEBUG) { u16 i; if( len == 0) { for(i = 0;data[i] != '\0';i++) { uart1_putchar(data[i]); } } else { for(i = 0;i < len;i++) { uart1_putchar(data[i]); } } } }

浙公网安备 33010602011771号