#include "user_uart.h" #include "stm32f10x.h" #include <stdio.h> /******************************************************************************************/ /*串口接收部分代码移植需要改动3处*/ /******************************************************************************************/ /******************************************************************************************/ /********************************串口接收部分代码*******************************************/ /******************************************************************************************/ /******************************************************************************************/ /*此结构体类型无需改动*/ /******************************************************************************************/ typedef struct { volatile unsigned int uart_delay_flag; //串口进入中断后,定时器开启标志位 volatile unsigned int uart_delay_count; //串口进入中断后,定时器计数变量,自加 volatile unsigned char uart_array_num; //接受数据的数组的序号 volatile unsigned char uart_receive_flag; //串口接收数据完成标志位 }User_Uart_InitTypeDef; /*******************************************************************************************/ /******************************************************************************************************/ /*串口结构体数组,预设5个串口,如增加新串口,可按格式增加,如不需要增加串口,此结构体无需改动*/ /******************************************************************************************************/ User_Uart_InitTypeDef uart_array[UART_NUM_ALL] = { {0,0,0,0,}, #if UART_NUM_ALL > 1 {0,0,0,0,}, #endif #if UART_NUM_ALL > 2 {0,0,0,0,}, #endif #if UART_NUM_ALL > 3 {0,0,0,0,}, #endif #if UART_NUM_ALL > 4 {0,0,0,0,}, #endif }; /***************************************************************************************************/ /***************************************************************************************************/ /*串口接收数组声明,预设5个串口,如增加新串口,可按格式增加,如不需要增加串口,此结构体无需改动*/ /***************************************************************************************************/ volatile unsigned char uart1_array_receive_buff[N1_UART]; #if UART_NUM_ALL > 1 volatile unsigned char uart2_array_receive_buff[N2_UART]; #endif #if UART_NUM_ALL > 2 volatile unsigned char uart3_array_receive_buff[N3_UART]; #endif #if UART_NUM_ALL > 3 volatile unsigned char uart4_array_receive_buff[N4_UART]; #endif #if UART_NUM_ALL > 4 volatile unsigned char uart5_array_receive_buff[N5_UART]; #endif /***************************************************************************************************/ /**********************************移植需改动的第1处***********************************/ /*串口初始化代码*/ /*************************************************************************************/ void user_uart_init(void) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART1, &USART_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, ENABLE); } /******************************************************************************************/ /***********************************移植需改动的第2处*******************************************************/ /*此函数放置到串口中断服务函数,移植需改动: 1串口清除中断标志位的函数 2串口接收数据函数*/ /*********************************************************************************************************/ void user_uart_intterrupt(unsigned char uart_id) { switch(uart_id) { case 1: USART_ClearITPendingBit(USART1, USART_IT_RXNE);break; #if UART_NUM_ALL > 1 case 2: USART_ClearITPendingBit(USART2, USART_IT_RXNE);break; #endif #if UART_NUM_ALL > 2 case 3: USART_ClearITPendingBit(USART3, USART_IT_RXNE);break; #endif #if UART_NUM_ALL > 3 case 4: USART_ClearITPendingBit(USART4, USART_IT_RXNE);break; #endif #if UART_NUM_ALL > 4 case 4: USART_ClearITPendingBit(USART5, USART_IT_RXNE);break; #endif } uart_array[uart_id - 1].uart_delay_flag = 1; //进入中断后开启定时 uart_array[uart_id - 1].uart_delay_count = 0; //清零定时器计数 if(uart_array[uart_id - 1].uart_array_num < N1_UART) { switch(uart_id) { case 1:uart1_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART1);break; #if UART_NUM_ALL > 1 case 2:uart2_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART2);break; #endif #if UART_NUM_ALL > 2 case 3:uart3_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART3);break; #endif #if UART_NUM_ALL > 3 case 4:uart4_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART4);break; #endif #if UART_NUM_ALL > 4 case 4:uart4_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART5);break; #endif } uart_array[uart_id - 1].uart_array_num++; } else { uart_array[uart_id - 1].uart_array_num = N1_UART; //不再接收接收数据 } } /*********************************************************************************************************/ /*********************************************************************************************************/ /*此函数放置到systick或者定时器中断函数去,此结构体无需改动*/ /*********************************************************************************************************/ void user_uart_scan(void) { unsigned char uart_index; for(uart_index =0;uart_index < UART_NUM_ALL;uart_index++) { if(uart_array[uart_index].uart_delay_flag == 1) //判断标志位,串口启动定时延时 { uart_array[uart_index].uart_delay_count++; //延时计数 if(uart_array[uart_index].uart_delay_count > UART_DELAY_TIME) //延时计数超过设定值 { uart_array[uart_index].uart_delay_count = 0; //延时计数清零 uart_array[uart_index].uart_delay_flag = 0; //延时计数的标志位清零,关串口计数定时器 uart_array[uart_index].uart_array_num = 0; //串口数组的下标归零,以便下次串口接收数据从0下标开始 uart_array[uart_index].uart_receive_flag = 1; //接收完成,标志位赋值 } } } } /**********************************************************************************************************/ /***********************************************************************************/ /*判断串口数据是否接收完成,一般在主函数使用,并处理串口接收到的数据,此结构体无需改动*/ /***********************************************************************************/ unsigned char user_uart_get_flag(unsigned char uart_id) { unsigned char uart_local_param = 0; if(uart_array[uart_id - 1].uart_receive_flag == 1) { uart_array[uart_id - 1].uart_receive_flag = 0; uart_local_param = 1; } else { uart_local_param = 0; } return uart_local_param; } /*****************************************************************************/ /******************************移植需要改动的第3处*******************************/ /*串口中断服务函数,如移植需重写串口对应的中断服务函数*/ /*****************************************************************************/ void USART1_IRQHandler() { user_uart_intterrupt(1); } #if UART_NUM_ALL > 1 void USART2_IRQHandler() { user_uart_intterrupt(2); } #endif /*****************************************************************************/ /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ /******************************************************************************************/ /******************************************************************************************/ /*串口发送部分代码移植需要改动2处*/ /******************************************************************************************/ /****************************************************************************/ /***************************串口发送部分代码*********************************/ /****************************************************************************/ /****************************************************************************/ /*不用勾选使用keil的Use MicroLIB,不需要改动*/ /****************************************************************************/ #if 1 #pragma import(__use_no_semihosting) void _sys_exit(int x){x = x;} //定义_sys_exit()以避免使用半主机模式 struct __FILE{int handle;}; //标准库需要的支持函数 FILE __stdout; #endif /*****************************************************************************/ /**************************移植需要改动的第1处********************************/ /*重定义print函数,如移植需重写串口发送单个字节函数,和获取标志位函数*/ /****************************************************************************/ int fputc(int ch, FILE *f) { USART_SendData(USART1,(uint8_t)ch); //发送一字节数据 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); //等待发送完成 return ch; } /*****************************************************************************/ /******************************************移植需要改动的第2处********************************************/ /*串口发送函数,如移植需重写串口发送单个字节函数,和获取标志位函数*/ /****************************************************************************/ void user_uart_send(unsigned char uart_id,unsigned char *uart_p,unsigned char uart_array_member_total) { unsigned char uart_local_param; switch(uart_id) { case 1: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++) { USART_SendData(USART1,(uint8_t)uart_p[uart_local_param]); //发送一字节数据 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); //等待发送完成 USART_ClearFlag(USART1,USART_FLAG_TC); //清除发送标志位 };break; #if UART_NUM_ALL > 1 case 2: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++) { USART_SendData(USART2,(uint8_t)uart_p[uart_local_param]); //发送一字节数据 while(USART_GetFlagStatus(USART2,USART_FLAG_TXE) == RESET); //等待发送完成 USART_ClearFlag(USART2,USART_FLAG_TC); //清除发送标志位 };break; #endif #if UART_NUM_ALL > 2 case 3: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++) { USART_SendData(USART3,(uint8_t)uart_p[uart_local_param]); //发送一字节数据 while(USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET); //等待发送完成 USART_ClearFlag(USART3,USART_FLAG_TC); //清除发送标志位 };break; #endif #if UART_NUM_ALL > 3 case 4: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++) { USART_SendData(USART4,(uint8_t)uart_p[uart_local_param]); //发送一字节数据 while(USART_GetFlagStatus(USART4,USART_FLAG_TXE) == RESET); //等待发送完成 USART_ClearFlag(USART4,USART_FLAG_TC); //清除发送标志位 };break; #endif #if UART_NUM_ALL > 4 case 5: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++) { USART_SendData(USART5,(uint8_t)uart_p[uart_local_param]); //发送一字节数据 while(USART_GetFlagStatus(USART5,USART_FLAG_TXE) == RESET); //等待发送完成 USART_ClearFlag(USART5,USART_FLAG_TC); //清除发送标志位 };break; #endif } } /**********************************************************************************************************/ /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ /******************************************************************************************/ /****************************************************************************/ /*串口数组数据清除,适用于所有数组*/ /****************************************************************************/ void array_clear(unsigned char *array_p,unsigned char array_num) { unsigned char array_local_param; for(array_local_param = 0;array_local_param < array_num;array_local_param++) { array_p[array_local_param] = 0; } } /****************************************************************************/
#ifndef _user_uart_h_ #define _user_uart_h_ /******************************************************************************************/ /*串口接收部分代码移植需要改动3处*/ /******************************************************************************************/ /***************移植需改动的第1处*********************/ /*宏定义串口的总个数*/ /****************************************************/ #define UART_NUM_ALL 1 /****************************************************/ /****************移植需改动的第2处********************/ /*宏定义串口延时接收时间设置*/ /****************************************************/ #define UART_DELAY_TIME 10 /****************************************************/ /****************移植需改动的第3处*******************/ /*宏定义串口接收数组的大小*/ /****************************************************/ #define N1_UART 10 #if UART_NUM_ALL > 1 N2_UART 10 #endif #if UART_NUM_ALL > 2 N3_UART 10 #endif #if UART_NUM_ALL > 3 N4_UART 10 #endif #if UART_NUM_ALL > 4 N5_UART 10 #endif /****************************************************/ /******************************************************************/ /*声明串口数据接收数组外部调用,无需改动*/ /******************************************************************/ extern volatile unsigned char uart1_array_receive_buff[N1_UART]; #if UART_NUM_ALL > 1 extern volatile unsigned char uart2_array_receive_buff[N2_UART]; #endif #if UART_NUM_ALL > 2 extern volatile unsigned char uart3_array_receive_buff[N3_UART]; #endif #if UART_NUM_ALL > 3 extern volatile unsigned char uart4_array_receive_buff[N4_UART]; #endif #if UART_NUM_ALL > 4 extern volatile unsigned char uart5_array_receive_buff[N5_UART]; #endif /*******************************************************************/ /****************************************************/ /*串口初始化*/ void user_uart_init(void); /****************************************************/ /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ /******************************************************************************************/ /*与串口发送有关的函数*/ /****************************************************/ /*此函数放置到串口中断服务函数*/ void user_uart_intterrupt(unsigned char uart_id); /****************************************************/ /****************************************************************/ /*此函数放置到systick或者定时器中断函数去*/ void user_uart_scan(void); /****************************************************************/ /******************************************************************/ /*判断串口数据是否接收完成,一般在主函数使用,并处理串口接收到的数据*/ unsigned char user_uart_get_flag(unsigned char uart_id); /******************************************************************/ /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ /******************************************************************************************/ /******************************************************************************************************/ /*串口发送函数*/ void user_uart_send(unsigned char uart_id,unsigned char *uart_p,unsigned char uart_array_member_total); /******************************************************************************************************/ /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ /******************************************************************************************/ /*****************************************************************/ /*串口数组数据清除,适用于所有数组*/ void array_clear(unsigned char *array_p,unsigned char array_num); /*****************************************************************/ #endif