#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