一般的开发板,最多只能试验2到3个串口。开发板厂商也不可能将MCU上的所有资源都引出来给你用。
除非自己来做开发板,但是要花时间的。细节蛮多的。
一般除了和当前的工作任务相关,没有领导会安排带薪的时间来做这种验证性任务。
但是,如果硬件接口没有引出,写出的代码,就有些细节问题,无法验证。虽然说串口1到串口6的初始化和使用都是一样的,但是没有全部验证完,谁敢说自己写的没问题,能直接用到产品上呢。
产品板子上用STM32F407, 6对串口线都已经引出。
还是产品板子好,6个串口都能验证收发。
MCU的串口引脚转成485引出到面板接口, 用485转232头 + 232转USB串口, 接到PC端作为COM口.
在PC端,运行串口调试助手,配合在下位机中的串口发送和串口中断中下断点,就能知道每个串口收发是否正常了。
工程为MDK5 + STM32F407库函数版本 + ucOSII, 对6个串口都做了初始化,用中断方式操作。
6个串口通过一个232转485的接口板接到面板的6个485RJ45插座上. 因为485接口板是半双工,所以同一时间点,只能有一个串口发送或接收。在发送前,打开485发送使能,发送数据,如果要等回答,接着打开485接收使能,延时等回包,处理回包。因为485发送接收使能是6个串口共用一个,所以,用一个互斥量来使485发送接收,只能被一个串口使用。串口上接的设备是被动的,采用一问一答的方式。
已经在产品板子上试验过了,6个串口收发都好使。
test_stm32f407_all_uart_on_ucosII.zip
假设硬件没问题(这是前提条件)。
如果写的程序,6个串口不能正常收发. 首先要看看串口的6对管脚是否选择错了(软件使用的串口管脚,一定要和原理图一致)。
串口号 | 发送引脚 | 接收引脚 |
---|---|---|
串口1 | PA9/PB6 | PA10/PB7 |
串口2 | PA2/PD5 | PA3/PD6 |
串口3 | PB10/PC10/PD8 | PB11/PC11/PD9 |
串口4 | PC10/PA0 | PC11/PA1 |
串口5 | PC12 | PD2 |
串口6 | PC6/PG14 | PC7/PG9 |
检查NVIC, 看看是否设置正确。可以统一将NVIC设置的代码放到主函数中。等有问题时,方便统计检查。
设备的初始化工作,如果和ucOS无关,可以统一放到main函数中。如果和ucOS函数相关,可以放到开始任务中做。初始化的工作尽早做。
检查串口的初始化方式,是中断方式,还是DMA方式。GPIO初始化使能,设备初始化参数,设备使能,中断设置是否正确。
看看任务的优先级是否设置正确,是否让出了时间片给其他任务。
如果有公用的485使能,看485使能资源的独占是否正确。
看看是否因为任务调度函数使用不当,使发包后的延时函数不生效,导致发包没等回包。
每个串口的收发单独验证,是否每个串口任务都能重复多次执行到。是否每次回包都能重复多次收到。
要加入禁止半主机模式的代码
//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
// 如果不加如下代码, 仿真器进入不了main入口点
#if 1
#pragma import(__use_no_semihosting)
// 标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
/*
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
*/
return ch;
}
#endif
//支持printf的定义
//
做demo时,没实现SysTick_Handler, 所以ucOS任务调度有问题。
// systick中断服务函数,使用ucos时用到
// 这个函数必须有, 否则串口收发都不正常(调用串口收发时,会死掉, 执行一个GPIO操作,都会死掉,单步一下,仿真器就没响应了)
void SysTick_Handler(void)
{
OSIntEnter(); // 进入中断
OSTimeTick(); // 调用ucos的时钟服务程序
OSIntExit(); // 触发任务切换软中断
}
打开 assert_failed,在自己的assert_failed中做死循环,下断点,如果哪个库函数参数输入错误,就能马上发现。
void assert_failed(uint8_t* file, uint32_t line)
{
// 这里就为断点能停下,然后返回, 看看,哪里参数设置错了
while (0) {
}
}
在程序入口点,HardFault_Handler(), SystemReset()处下断点,如果程序挂掉或跑飞,马上能发现。然后分析原因。
调度函数OSSchedLock()不能在发包前调用,这个函数调用后,OSTimeDlyHMSM()中的延时就失效了。
换用了互斥量解决。
OS_EVENT* g_osMutex_for_res_485; // 485收发操作资源的互斥量
// ...
// MY_OS_MUTEX_PRIO 等级要稍高于所有用到互斥量的子任务优先级
g_osMutex_for_res_485 = OSMutexCreate(MY_OS_MUTEX_PRIO, &err);
if (NULL == g_osMutex_for_res_485) {
printf("err : NULL == g_osMutex_for_res_485");
}
// ...
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart1(); // 串口操作中可以有发包后的延时函数,等回包
OSMutexPost(g_osMutex_for_res_485);
这里有2个情况
case1:
ucOSII不支持多个优先级相同的任务进行时间片轮转,必须每个任务优先级不同
如果多个子任务的优先级相同,那只有第一个子任务会被重复执行,其他子任务一次都执行不到(或只能被执行一次).
// ucOSII不支持相同优先级任务的时间片轮转,所以每个任务的优先级必须不同
// 如果一个互斥量在多个任务中使用, 那么互斥量的任务优先级要略大于这些使用互斥量的任务优先级, 防止任务优先级反转
#define MY_OS_MUTEX_PRIO 23 // 互斥量的优先级
#define TASK_UART1_PRIO 24 // 串口任务
#define TASK_UART2_PRIO 25 // 串口任务
#define TASK_UART3_PRIO 26 // 串口任务
#define TASK_UART4_PRIO 27 // 串口任务
#define TASK_UART5_PRIO 28 // 串口任务
#define TASK_UART6_PRIO 29 // 串口任务
case2:
用到了互斥量之后,如果6个子任务总的逻辑执行时间大于每个任务让出时间片的时间,就会导致后面的任务执行不到。
void task_UART1(void *p_arg)
{
INT8U err;
// 不能调用OSSchedLock(), 会使延时函数失效
// OSSchedLock(); // 停止任务调度
// OSSchedUnlock(); // 开启任务调度
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart1();
OSMutexPost(g_osMutex_for_res_485);
// g_osMutex_for_res_485 只在6个串口任务中用
// 如果每个串口任务的实际执行函数test_uartx()的总时间 > 下面的延时时间, 会导致不是每个串口任务都能被执行到
// 所以下面的延时时间, 要大于6个串口任务执行的总时间
// e.g. 每个串口执行函数的时间为600ms, 那6个串口执行的总时间就是600ms * 6 = 3.6s
// 那么每个串口任务让出时间片的时间,就必须大于3.6s, 那让出时间片的时间最小为是4s, 否则后面低优先级的串口任务,执行不到
// 实际测试,下面的让出时间片为3秒就可以,估计是ucOS延时不精确的原因
// 但是,如果延时时间为2秒,低优先级的串口任务就执行不到了
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
测试工程为了测试STM32F407自带的6个串口。设计实现成:
每个串口一个ucOSII任务,每个任务中发包后,延时600ms等回包。
串口中断函数只是收包到缓冲区,尽量少干活。
发包+延时后,如果缓冲区内有回包,加上"\r\n"回发回去。清掉缓冲区计数。
// @file \Project\main.c
#include "includes.h"
//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
// 如果不加如下代码, 仿真器进入不了main入口点
#if 1
#pragma import(__use_no_semihosting)
// 标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
/*
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
*/
return ch;
}
#endif
//支持printf的定义
//
// 如果没有通讯控制, 定义空宏
#define RS485_Tx GPIO_SetBits(GPIOE, GPIO_Pin_9)
#define RS485_Rx GPIO_ResetBits(GPIOE, GPIO_Pin_9)
// 因为6个串口通过一块232转485的半双工转接板,所以485的收发操作是要独占的(假设发送完成后,需要等回答)
// 那么RS485_Rx和延时函数之间的操作,就不允许有其他的任务执行RS485_Tx
// 这里弄一个互斥量对应485收发
OS_EVENT* g_osMutex_for_res_485; // 485收发操作资源的互斥量
// 串口参数
#define UART_BAUDRATE_DEFAULT 9600
#define UART1_BAUDRATE 9600
#define UART2_BAUDRATE 9600
#define UART3_BAUDRATE 9600
#define UART4_BAUDRATE 9600
#define UART5_BAUDRATE 9600
#define UART6_BAUDRATE 9600
// 任务等级
#define START_TASK_PRIO 11 // 开始任务
// ucOSII不支持相同优先级任务的时间片轮转,所以每个任务的优先级必须不同
// 如果一个互斥量在多个任务中使用, 那么互斥量的任务优先级要略大于这些使用互斥量的任务优先级
#define MY_OS_MUTEX_PRIO 23 // 互斥量的优先级
#define TASK_UART1_PRIO 24 // 串口任务
#define TASK_UART2_PRIO 25 // 串口任务
#define TASK_UART3_PRIO 26 // 串口任务
#define TASK_UART4_PRIO 27 // 串口任务
#define TASK_UART5_PRIO 28 // 串口任务
#define TASK_UART6_PRIO 29 // 串口任务
// 任务栈大小
#define START_STK_SIZE 128
#define TASK_UART_STACK_SIZE 128
// 任务栈
static OS_STK Task_Stack_START[START_STK_SIZE]; // 任务堆栈 - 开始任务
static OS_STK Task_Stack_UART1[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口1
static OS_STK Task_Stack_UART2[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口2
static OS_STK Task_Stack_UART3[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口3
static OS_STK Task_Stack_UART4[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口4
static OS_STK Task_Stack_UART5[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口5
static OS_STK Task_Stack_UART6[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口6
// 任务函数
void start_task(void *p_arg); // 开始任务
void task_UART1(void *p_arg); // 串口任务
void task_UART2(void *p_arg);
void task_UART3(void *p_arg);
void task_UART4(void *p_arg);
void task_UART5(void *p_arg);
void task_UART6(void *p_arg);
// 初始化函数
void sys_clock_init(u8 SYSCLK);
void my_NVIC_init(void);
void rs485_init(void);
void uart_init1(void);
void uart_init2(void);
void uart_init3(void);
void uart_init4(void);
void uart_init5(void);
void uart_init6(void);
void set_uart_param(int i_uart_sn, USART_InitTypeDef* p_USART_InitStructure, int baudrate, int parity, int word_length, int stop_bits);
// 普通函数
void STM32_UART_SendDatas(int i_uart_index, const uint8_t *buf,unsigned short size);
void STM32_UART1_SendDatas(const uint8_t *buf,uint16_t size);
void STM32_UART2_SendDatas(const uint8_t *buf,uint16_t size);
void STM32_UART3_SendDatas(const uint8_t *buf,uint16_t size);
void STM32_UART4_SendDatas(const uint8_t *buf,uint16_t size);
void STM32_UART5_SendDatas(const uint8_t *buf,uint16_t size);
void STM32_UART6_SendDatas(const uint8_t *buf,uint16_t size);
void test_uart1(void);
void test_uart2(void);
void test_uart3(void);
void test_uart4(void);
void test_uart5(void);
void test_uart6(void);
int main(void)
{
// 主函数只作一些必要的初始化操作
SCB->VTOR = FLASH_BASE | 0; // 中断指针向量跳转, 向量表地址在0x08000000
sys_clock_init(168); // 系统时钟初始化(主频168MHZ)
my_NVIC_init();
rs485_init();
uart_init1();
uart_init2();
uart_init3();
uart_init4();
uart_init5();
uart_init6();
OSInit(); // UCOS初始化
// 因为用到了ucOS, 和任务调度,延时操作相关的操作都放到任务中去作
OSTaskCreate(start_task,(void*)0, &Task_Stack_START[START_STK_SIZE - 1], START_TASK_PRIO); // 开始任务创建
OSStart();
return 0;
}
void start_task(void *p_arg)
{
INT8U err;
printf(">> start_task\n");
// 初始化设备
g_osMutex_for_res_485 = OSMutexCreate(MY_OS_MUTEX_PRIO, &err);
if (NULL == g_osMutex_for_res_485) {
printf("err : NULL == g_osMutex_for_res_485");
}
// 创建6个串口任务
OSTaskCreate(task_UART1, 0, &Task_Stack_UART1[TASK_UART_STACK_SIZE - 1], TASK_UART1_PRIO);
OSTaskCreate(task_UART2, 0, &Task_Stack_UART2[TASK_UART_STACK_SIZE - 1], TASK_UART2_PRIO);
OSTaskCreate(task_UART3, 0, &Task_Stack_UART3[TASK_UART_STACK_SIZE - 1], TASK_UART3_PRIO);
OSTaskCreate(task_UART4, 0, &Task_Stack_UART4[TASK_UART_STACK_SIZE - 1], TASK_UART4_PRIO);
OSTaskCreate(task_UART5, 0, &Task_Stack_UART5[TASK_UART_STACK_SIZE - 1], TASK_UART5_PRIO);
OSTaskCreate(task_UART6, 0, &Task_Stack_UART6[TASK_UART_STACK_SIZE - 1], TASK_UART6_PRIO);
while(1)
{
OSTimeDlyHMSM(0,0,1,0); // 让出时间片
}
}
void task_UART1(void *p_arg)
{
INT8U err;
// 不能调用OSSchedLock(), 会使延时函数失效
// OSSchedLock(); // 停止任务调度
// OSSchedUnlock(); // 开启任务调度
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart1();
OSMutexPost(g_osMutex_for_res_485);
// g_osMutex_for_res_485 只在6个串口任务中用
// 如果每个串口任务的实际执行函数test_uartx()的总时间 > 下面的延时时间, 会导致不是每个串口任务都能被执行到
// 所以下面的延时时间, 要大于6个串口任务执行的总时间
// e.g. 每个串口执行函数的时间为600ms, 那6个串口执行的总时间就是600ms * 6 = 3.6s
// 那么每个串口任务让出时间片的时间,就必须大于3.6s, 那让出时间片的时间最小为是4s, 否则后面低优先级的串口任务,执行不到
// 实际测试,下面的让出时间片为3秒就可以,估计是ucOS延时不精确的原因
// 但是,如果延时时间为2秒,低优先级的串口任务就执行不到了
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
void task_UART2(void *p_arg)
{
INT8U err;
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart2();
OSMutexPost(g_osMutex_for_res_485);
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
void task_UART3(void *p_arg)
{
INT8U err;
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart3();
OSMutexPost(g_osMutex_for_res_485);
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
void task_UART4(void *p_arg)
{
INT8U err;
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart4();
OSMutexPost(g_osMutex_for_res_485);
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
void task_UART5(void *p_arg)
{
INT8U err;
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart5();
OSMutexPost(g_osMutex_for_res_485);
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
void task_UART6(void *p_arg)
{
INT8U err;
while(1)
{
OSMutexPend(g_osMutex_for_res_485, 0, &err);
test_uart6();
OSMutexPost(g_osMutex_for_res_485);
OSTimeDlyHMSM(0, 0, 4, 0); // 让出时间片, 防止由于使用了互斥量, 又没有禁止任务调度,防止低优先级的任务执行不到
}
}
// systick中断服务函数,使用ucos时用到
// 这个函数必须有, 否则串口收发都不正常(调用串口收发时,会死掉, 执行一个GPIO操作,都会死掉,单步一下,仿真器就没响应了)
void SysTick_Handler(void)
{
OSIntEnter(); // 进入中断
OSTimeTick(); // 调用ucos的时钟服务程序
OSIntExit(); // 触发任务切换软中断
}
void sys_clock_init(u8 SYSCLK)
{
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
u32 reload;
#endif
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
reload=SYSCLK/8; //每秒钟的计数次数 单位为K
reload*=1000000/OS_TICKS_PER_SEC;//根据OS_TICKS_PER_SEC设定溢出时间
//reload为24位寄存器,最大值:16777216,在168M下,约合0.7989s左右
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
SysTick->LOAD=reload; //每1/OS_TICKS_PER_SEC秒中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
#else
fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数
#endif
}
void set_uart_param(int i_uart_sn, USART_InitTypeDef* p_USART_InitStructure, int baudrate, int parity, int word_length, int stop_bits) {
if (NULL != p_USART_InitStructure) {
p_USART_InitStructure->USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
p_USART_InitStructure->USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
// 9600
p_USART_InitStructure->USART_BaudRate = baudrate; // 比特率设定
// N
switch (parity) {
case 0:
p_USART_InitStructure->USART_Parity = USART_Parity_No; // 无校验
break;
case 1:
p_USART_InitStructure->USART_Parity = USART_Parity_Odd; // 奇验位
break;
case 2:
p_USART_InitStructure->USART_Parity = USART_Parity_Even; // 偶验位
break;
default:
p_USART_InitStructure->USART_Parity = USART_Parity_No; // 无校验
break;
}
switch (word_length) {
case 8:
p_USART_InitStructure->USART_WordLength = USART_WordLength_8b; // 8数据位长度
break;
case 9:
p_USART_InitStructure->USART_WordLength = USART_WordLength_9b; // 9数据位长度
break;
default:
p_USART_InitStructure->USART_WordLength = USART_WordLength_8b; // 8数据位长度
break;
}
switch (stop_bits) {
case 0:
p_USART_InitStructure->USART_StopBits = USART_StopBits_1; // 1停止位
break;
case 1:
p_USART_InitStructure->USART_StopBits = USART_StopBits_2; // 2停止位
break;
default:
p_USART_InitStructure->USART_StopBits = USART_StopBits_1; // 1停止位
break;
}
}
}
void my_NVIC_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断分组配置(2位抢占优先级, 2位子优先级, 优先级有效值范围 = (0 ~ 3))
// 串口中断优先级设置 - COM1
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
// 串口中断优先级设置 - COM2
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; // 串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
// 串口中断优先级设置 - COM3
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; // 串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
// 串口中断优先级设置 - COM 4
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; // 串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
// 串口中断优先级设置 - COM 5
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; // 串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
// 串口中断优先级设置 - COM 6
NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; // 串口中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器、
}
void rs485_init(void)
{
// 6个串口都通过rs485转接板到后面板
// rs485转接板是半双工, 发送和接收都需要切换方向
// 每个串口操作时,其他串口要互斥
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE); // 使能GPIOE的时钟
// 485收发引脚初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;// 输出
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 高速GPIO
GPIO_Init(GPIOE,&GPIO_InitStructure);
}
// 初始化IO - 串口1
void uart_init1(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能串口管脚所在端口时钟, 使能串口时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); // 使能GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); // 使能USART时钟
// 串口引脚复用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9, GPIO_AF_USART1); // GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10, GPIO_AF_USART1); // GPIOA10复用为USART1
// 串口管脚参数设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
// USART通讯参数设置
set_uart_param(1, &USART_InitStructure, UART1_BAUDRATE, 0, 8, 1);
USART_Init(USART1, &USART_InitStructure); // 初始化串口
USART_Cmd(USART1, ENABLE); // 使能串口
// 开启串口中断(必须在使能串口后, 再开启串口中断, 否则不进串口中断处理函数)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 清发送完成标志
while (USART_GetITStatus(USART1, USART_IT_TC) != RESET) {
USART_ClearFlag(USART1, USART_FLAG_TC);
}
// 清接收完成标志
while (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
USART_ClearFlag(USART1, USART_FLAG_RXNE);
}
}
//初始化IO 串口2
void uart_init2(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能串口管脚所在端口时钟, 使能串口时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART时钟
//串口2对应引脚复用映射
GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_USART2); //GPIOD5复用为USART1
GPIO_PinAFConfig(GPIOD,GPIO_PinSource6,GPIO_AF_USART2); //GPIOD6复用为USART1
// USART2端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; //GPIOD5与GPIOD6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化PD5,PD6
// 串口基本参数 初始化设置
set_uart_param(2, &USART_InitStructure, UART2_BAUDRATE, 0, 8, 1);
USART_Init(USART2, &USART_InitStructure); // 初始化串口
USART_Cmd(USART2, ENABLE); // 使能串口
// 开启串口中断(必须在使能串口后, 再开启串口中断, 否则不进串口中断处理函数)
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
// 清发送完成标志
while (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
USART_ClearFlag(USART2, USART_FLAG_TC);
}
// 清接收完成标志
while (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
USART_ClearFlag(USART2, USART_FLAG_RXNE);
}
}
//初始化IO 串口3
//波特率默认9600
void uart_init3(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能串口管脚所在端口时钟, 使能串口时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART时钟
//串口3对应引脚复用映射
GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_USART3); //GPIOD8复用为USART3
GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_USART3); //GPIOD9复用为USART3
//USART3端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //GPIOD8与GPIOD9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化GPIOD8, GPIOD9
//串口基本参数 初始化设置
set_uart_param(3, &USART_InitStructure, UART3_BAUDRATE, 0, 8, 1);
USART_Init(USART3, &USART_InitStructure); //初始化串口3
USART_Cmd(USART3, ENABLE); //使能串口3
// 开启串口中断(必须在使能串口后, 再开启串口中断, 否则不进串口中断处理函数)
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
// 清发送完成标志
while (USART_GetITStatus(USART3, USART_IT_TC) != RESET) {
USART_ClearFlag(USART3, USART_FLAG_TC);
}
// 清接收完成标志
while (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
USART_ClearFlag(USART3, USART_FLAG_RXNE);
}
}
//初始化IO 串口4
//波特率默认9600
void uart_init4(void)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能串口管脚所在端口时钟, 使能串口时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); // 使能GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE); // 使能USART时钟
// 串口引脚复用映射
GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_UART4); //GPIOC10复用为UART4
GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_UART4); //GPIOC11复用为UART4
// 串口管脚参数设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //GPIOC10与GPIOC11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PC10,PC11
//串口基本参数 初始化设置
set_uart_param(4, &USART_InitStructure, UART4_BAUDRATE, 0, 8, 1);
USART_Init(UART4, &USART_InitStructure); //初始化串口4
USART_Cmd(UART4, ENABLE); //使能串口4
// 开启串口中断(必须在使能串口后, 再开启串口中断, 否则不进串口中断处理函数)
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
// 清发送完成标志
while (USART_GetITStatus(UART4, USART_IT_TC) != RESET) {
USART_ClearFlag(UART4, USART_FLAG_TC);
}
// 清接收完成标志
while (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) {
USART_ClearFlag(UART4, USART_FLAG_RXNE);
}
}
//初始化IO 串口5
//波特率默认9600
void uart_init5(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //使能GPIOC时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //使能GPIOD时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE); //使能USART5时钟
//串口4对应引脚复用映射
GPIO_PinAFConfig(GPIOC,GPIO_PinSource12,GPIO_AF_UART5); //GPIOC12复用为UART5
GPIO_PinAFConfig(GPIOD,GPIO_PinSource2, GPIO_AF_UART5); //GPIOD2复用为UART5
//UART5端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //GPIOC12
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PC12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //GPIOD2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化PD2
//串口基本参数 初始化设置
set_uart_param(5, &USART_InitStructure, UART5_BAUDRATE, 0, 8, 1);
USART_Init(UART5, &USART_InitStructure); //初始化串口5
USART_Cmd(UART5, ENABLE); //使能串口5
// 开启串口中断(必须在使能串口后, 再开启串口中断, 否则不进串口中断处理函数)
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
// 清发送完成标志
while (USART_GetITStatus(UART5, USART_IT_TC) != RESET) {
USART_ClearFlag(UART5, USART_FLAG_TC);
}
// 清接收完成标志
while (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) {
USART_ClearFlag(UART5, USART_FLAG_RXNE);
}
}
//初始化IO 串口6
void uart_init6(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 使能串口管脚所在端口时钟, 使能串口时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //使能GPIOD时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);//使能USART2时钟
// 串口引脚复用映射
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6); //GPIOC6复用为USART6
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6); //GPIOC7复用为USART6
//USART2端口配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // GPIOC6与GPIOC7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PC6,PC7
//串口基本参数 初始化设置
set_uart_param(6, &USART_InitStructure, UART6_BAUDRATE, 0, 8, 1);
USART_Init(USART6, &USART_InitStructure); //初始化串口6
USART_Cmd(USART6, ENABLE); //使能串口6
// 开启串口中断(必须在使能串口后, 再开启串口中断, 否则不进串口中断处理函数)
USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);
// 清发送完成标志
while (USART_GetITStatus(USART6, USART_IT_TC) != RESET) {
USART_ClearFlag(USART6, USART_FLAG_TC);
}
// 清接收完成标志
while (USART_GetITStatus(USART6, USART_IT_RXNE) != RESET) {
USART_ClearFlag(USART6, USART_FLAG_RXNE);
}
}
void STM32_UART1_SendDatas(const uint8_t *buf,uint16_t size)
{
uint16_t i;
RS485_Tx; // RS485-发送使能
for(i=0; i= 4) {
memcpy(uart_send_buf[TRANS_INDEX_UART1], uart_recv_buf[TRANS_INDEX_UART1], uart_recv_len[TRANS_INDEX_UART1]);
Size = uart_recv_len[TRANS_INDEX_UART1] + 2;
uart_send_buf[TRANS_INDEX_UART1][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART1][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART1, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART1], Size);
uart_recv_len[TRANS_INDEX_UART1] = 0;
}
}
void test_uart2(void)
{
int i = 0;
uint8_t Size = 8;
for (i = 0; i < Size; i++) {
uart_send_buf[TRANS_INDEX_UART2][i] = 0x20 + i;
}
uart_send_buf[TRANS_INDEX_UART2][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART2][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART2, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART2], Size);
OSTimeDlyHMSM(0, 0, 0, 600); // delay
if (uart_recv_len[TRANS_INDEX_UART2] >= 4) {
memcpy(uart_send_buf[TRANS_INDEX_UART2], uart_recv_buf[TRANS_INDEX_UART2], uart_recv_len[TRANS_INDEX_UART2]);
Size = uart_recv_len[TRANS_INDEX_UART2] + 2;
uart_send_buf[TRANS_INDEX_UART2][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART2][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART2, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART2], Size);
uart_recv_len[TRANS_INDEX_UART2] = 0;
}
}
void test_uart3(void)
{
int i = 0;
uint8_t Size = 8;
for (i = 0; i < Size; i++) {
uart_send_buf[TRANS_INDEX_UART3][i] = 0x30 + i;
}
uart_send_buf[TRANS_INDEX_UART3][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART3][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART3, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART3], Size);
OSTimeDlyHMSM(0, 0, 0, 600); // delay
if (uart_recv_len[TRANS_INDEX_UART3] >= 4) {
memcpy(uart_send_buf[TRANS_INDEX_UART3], uart_recv_buf[TRANS_INDEX_UART3], uart_recv_len[TRANS_INDEX_UART3]);
Size = uart_recv_len[TRANS_INDEX_UART3] + 2;
uart_send_buf[TRANS_INDEX_UART3][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART3][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART3, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART3], Size);
uart_recv_len[TRANS_INDEX_UART3] = 0;
}
}
void test_uart4(void)
{
int i = 0;
uint8_t Size = 8;
for (i = 0; i < Size; i++) {
uart_send_buf[TRANS_INDEX_UART4][i] = 0x40 + i;
}
uart_send_buf[TRANS_INDEX_UART4][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART4][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART4, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART4], Size);
OSTimeDlyHMSM(0, 0, 0, 600); // delay
if (uart_recv_len[TRANS_INDEX_UART4] >= 4) {
memcpy(uart_send_buf[TRANS_INDEX_UART4], uart_recv_buf[TRANS_INDEX_UART4], uart_recv_len[TRANS_INDEX_UART4]);
Size = uart_recv_len[TRANS_INDEX_UART4] + 2;
uart_send_buf[TRANS_INDEX_UART4][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART4][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART4, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART4], Size);
uart_recv_len[TRANS_INDEX_UART4] = 0;
}
}
void test_uart5(void)
{
int i = 0;
uint8_t Size = 8;
for (i = 0; i < Size; i++) {
uart_send_buf[TRANS_INDEX_UART5][i] = 0x50 + i;
}
uart_send_buf[TRANS_INDEX_UART5][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART5][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART5, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART5], Size);
OSTimeDlyHMSM(0, 0, 0, 600); // delay
if (uart_recv_len[TRANS_INDEX_UART5] >= 4) {
memcpy(uart_send_buf[TRANS_INDEX_UART5], uart_recv_buf[TRANS_INDEX_UART5], uart_recv_len[TRANS_INDEX_UART5]);
Size = uart_recv_len[TRANS_INDEX_UART5] + 2;
uart_send_buf[TRANS_INDEX_UART5][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART5][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART5, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART5], Size);
uart_recv_len[TRANS_INDEX_UART5] = 0;
}
}
void test_uart6(void)
{
int i = 0;
uint8_t Size = 8;
for (i = 0; i < Size; i++) {
uart_send_buf[TRANS_INDEX_UART6][i] = 0x60 + i;
}
uart_send_buf[TRANS_INDEX_UART6][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART6][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART6, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART6], Size);
OSTimeDlyHMSM(0, 0, 0, 600); // delay
if (uart_recv_len[TRANS_INDEX_UART6] >= 4) {
memcpy(uart_send_buf[TRANS_INDEX_UART6], uart_recv_buf[TRANS_INDEX_UART6], uart_recv_len[TRANS_INDEX_UART6]);
Size = uart_recv_len[TRANS_INDEX_UART6] + 2;
uart_send_buf[TRANS_INDEX_UART6][Size - 2] = '\r';
uart_send_buf[TRANS_INDEX_UART6][Size - 1] = '\n';
STM32_UART_SendDatas(TRANS_INDEX_UART6, (const uint8_t*)uart_send_buf[TRANS_INDEX_UART6], Size);
uart_recv_len[TRANS_INDEX_UART6] = 0;
}
}
/**
******************************************************************************
* @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_it.c
* @author MCD Application Team
* @version V1.4.0
* @date 04-August-2014
* @brief Main Interrupt Service Routines.
* This file provides template for all exceptions handler and
* peripherals interrupt service routine.
******************************************************************************
* @attention
*
* © COPYRIGHT 2014 STMicroelectronics
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_it.h"
#include "includes.h"
unsigned int uart_recv_len[UART_PORT_NUM]; // 统计出的串口接收数据长度
unsigned char uart_recv_buf[UART_PORT_NUM][NET_UART_BUF_LEN]; // 收到的串口数据
unsigned char uart_send_buf[UART_PORT_NUM][NET_UART_BUF_LEN]; // 发送的串口数据
__asm void SystemReset(void)
{
MOV R0, #1 //; 这里可以下断点, 好使
MSR FAULTMASK, R0 //; 清除FAULTMASK 禁止一切中断产生
LDR R0, =0xE000ED0C //;
LDR R1, =0x05FA0004 //;
STR R1, [R0] //; 系统软件复位
deadloop
B deadloop //; 死循环使程序运行不到下面的代码
}
/** @addtogroup Template_Project
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/******************************************************************************/
/* Cortex-M4 Processor Exceptions Handlers */
/******************************************************************************/
/**
* @brief This function handles NMI exception.
* @param None
* @retval None
*/
void NMI_Handler(void)
{
}
void assert_failed(uint8_t* file, uint32_t line)
{
// 这里就为断点能停下,然后返回, 看看,哪里参数设置错了
while (0) {
}
}
/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
SystemReset(); //复位
}
}
/**
* @brief This function handles Memory Manage exception.
* @param None
* @retval None
*/
void MemManage_Handler(void)
{
/* Go to infinite loop when Memory Manage exception occurs */
while (1)
{
}
}
/**
* @brief This function handles Bus Fault exception.
* @param None
* @retval None
*/
void BusFault_Handler(void)
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{
}
}
/**
* @brief This function handles Usage Fault exception.
* @param None
* @retval None
*/
void UsageFault_Handler(void)
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{
}
}
/**
* @brief This function handles SVCall exception.
* @param None
* @retval None
*/
//void SVC_Handler(void)
//{
//}
/**
* @brief This function handles Debug Monitor exception.
* @param None
* @retval None
*/
void DebugMon_Handler(void)
{
}
/**
* @brief This function handles PendSVC exception.
* @param None
* @retval None
*/
//void PendSV_Handler(void)
//{
//}
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
//void SysTick_Handler(void)
//{
// OS_CPU_SR cpu_sr;
// OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR */
// OSIntNesting++;
// OS_EXIT_CRITICAL();
// OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */
// OSIntExit(); /* Tell uC/OS-II that we are leaving the ISR */
//}
/******************************************************************************/
/* STM32F4xx Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
/* available peripheral interrupt handler's name please refer to the startup */
/* file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* @brief This function handles PPP interrupt request.
* @param None
* @retval None
*/
/*void PPP_IRQHandler(void)
{
}*/
void uart1_rx_to_buf(u8 uc_rx)
{
int i_rx_buf_len = (int)sizeof(uart_recv_buf[TRANS_INDEX_UART1]);
// 这里只能向缓冲区中丢接收到的字节内容,不能浪费时间作其他事情,否则引起接收丢包
// uart_recv_len[TRANS_INDEX_UART1]
if (0 == uart_recv_len[TRANS_INDEX_UART1]) {
memset(uart_recv_buf[TRANS_INDEX_UART1], 0, i_rx_buf_len);
}
// 这里只管接收, 如果缓冲区满了, 就不向缓冲区存了
// 等有人处理了缓冲区的数据, 将缓冲区的内容拿走了, 再向缓冲区内存
if (uart_recv_len[TRANS_INDEX_UART1] < i_rx_buf_len) {
uart_recv_buf[TRANS_INDEX_UART1][uart_recv_len[TRANS_INDEX_UART1] % (i_rx_buf_len - 1)] = uc_rx;
uart_recv_len[TRANS_INDEX_UART1] ++;
}
}
void uart2_rx_to_buf(u8 uc_rx)
{
int i_rx_buf_len = (int)sizeof(uart_recv_buf[TRANS_INDEX_UART2]);
if (0 == uart_recv_len[TRANS_INDEX_UART2]) {
memset(uart_recv_buf[TRANS_INDEX_UART2], 0, i_rx_buf_len);
}
if (uart_recv_len[TRANS_INDEX_UART2] < i_rx_buf_len) {
uart_recv_buf[TRANS_INDEX_UART2][uart_recv_len[TRANS_INDEX_UART2] % (i_rx_buf_len - 1)] = uc_rx;
uart_recv_len[TRANS_INDEX_UART2] ++;
}
}
void uart3_rx_to_buf(u8 uc_rx)
{
int i_rx_buf_len = (int)sizeof(uart_recv_buf[TRANS_INDEX_UART3]);
if (0 == uart_recv_len[TRANS_INDEX_UART3]) {
memset(uart_recv_buf[TRANS_INDEX_UART3], 0, i_rx_buf_len);
}
if (uart_recv_len[TRANS_INDEX_UART3] < i_rx_buf_len) {
uart_recv_buf[TRANS_INDEX_UART3][uart_recv_len[TRANS_INDEX_UART3] % (i_rx_buf_len - 1)] = uc_rx;
uart_recv_len[TRANS_INDEX_UART3] ++;
}
}
void uart4_rx_to_buf(u8 uc_rx)
{
int i_rx_buf_len = (int)sizeof(uart_recv_buf[TRANS_INDEX_UART4]);
if (0 == uart_recv_len[TRANS_INDEX_UART4]) {
memset(uart_recv_buf[TRANS_INDEX_UART4], 0, i_rx_buf_len);
}
if (uart_recv_len[TRANS_INDEX_UART4] < i_rx_buf_len) {
uart_recv_buf[TRANS_INDEX_UART4][uart_recv_len[TRANS_INDEX_UART4] % (i_rx_buf_len - 1)] = uc_rx;
uart_recv_len[TRANS_INDEX_UART4] ++;
}
}
void uart5_rx_to_buf(u8 uc_rx)
{
int i_rx_buf_len = (int)sizeof(uart_recv_buf[TRANS_INDEX_UART5]);
if (0 == uart_recv_len[TRANS_INDEX_UART5]) {
memset(uart_recv_buf[TRANS_INDEX_UART5], 0, i_rx_buf_len);
}
if (uart_recv_len[TRANS_INDEX_UART5] < i_rx_buf_len) {
uart_recv_buf[TRANS_INDEX_UART5][uart_recv_len[TRANS_INDEX_UART5] % (i_rx_buf_len - 1)] = uc_rx;
uart_recv_len[TRANS_INDEX_UART5] ++;
}
}
void uart6_rx_to_buf(u8 uc_rx)
{
int i_rx_buf_len = (int)sizeof(uart_recv_buf[TRANS_INDEX_UART6]);
if (0 == uart_recv_len[TRANS_INDEX_UART6]) {
memset(uart_recv_buf[TRANS_INDEX_UART6], 0, i_rx_buf_len);
}
if (uart_recv_len[TRANS_INDEX_UART6] < i_rx_buf_len) {
uart_recv_buf[TRANS_INDEX_UART6][uart_recv_len[TRANS_INDEX_UART6] % (i_rx_buf_len - 1)] = uc_rx;
uart_recv_len[TRANS_INDEX_UART6] ++;
}
}
void USART1_IRQHandler(void) // 串口1中断服务程序
{
u8 uc_rx = 0;
OSIntEnter();
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// 接收中断
uc_rx =USART_ReceiveData(USART1); // 读取接收到的数据
uart1_rx_to_buf(uc_rx);
USART_ClearFlag(USART1, USART_FLAG_RXNE);
}
OSIntExit(); // 退出中断
}
void USART2_IRQHandler(void)
{
u8 uc_rx = 0;
OSIntEnter();
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
uc_rx =USART_ReceiveData(USART2);
uart2_rx_to_buf(uc_rx);
USART_ClearFlag(USART2, USART_FLAG_RXNE);
}
OSIntExit();
}
void USART3_IRQHandler(void)
{
u8 uc_rx = 0;
OSIntEnter();
if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
uc_rx =USART_ReceiveData(USART3);
uart3_rx_to_buf(uc_rx);
USART_ClearFlag(USART3, USART_FLAG_RXNE);
}
OSIntExit();
}
void UART4_IRQHandler(void)
{
u8 uc_rx = 0;
OSIntEnter();
if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
{
uc_rx =USART_ReceiveData(UART4);
uart4_rx_to_buf(uc_rx);
USART_ClearFlag(UART4, USART_FLAG_RXNE);
}
OSIntExit();
}
void UART5_IRQHandler(void)
{
u8 uc_rx = 0;
OSIntEnter();
if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
{
uc_rx =USART_ReceiveData(UART5);
uart5_rx_to_buf(uc_rx);
USART_ClearFlag(UART5, USART_FLAG_RXNE);
}
OSIntExit();
}
void USART6_IRQHandler(void)
{
u8 uc_rx = 0;
OSIntEnter();
if (USART_GetITStatus(USART6, USART_IT_RXNE) != RESET)
{
uc_rx =USART_ReceiveData(USART6);
uart6_rx_to_buf(uc_rx);
USART_ClearFlag(USART6, USART_FLAG_RXNE);
}
OSIntExit();
}
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/