STM32F407串口操作

前言 一般的开发板,最多只能试验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发送接收,只能被一个串口使用。串口上接的设备是被动的,采用一问一答的方式。
demo下载点 已经在产品板子上试验过了,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使能资源的独占是否正确。
看看是否因为任务调度函数使用不当,使发包后的延时函数不生效,导致发包没等回包。
每个串口的收发单独验证,是否每个串口任务都能重复多次执行到。是否每次回包都能重复多次收到。
调试中遇到的问题 仿真器无法进入main函数 要加入禁止半主机模式的代码
// //加入以下代码,支持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(); // 触发任务切换软中断 }

防止库函数参数设置错 【STM32F407串口操作】打开 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_TxGPIO_SetBits(GPIOE, GPIO_Pin_9) #define RS485_RxGPIO_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; } }

/** ****************************************************************************** * @fileProject/STM32F4xx_StdPeriph_Templates/stm32f4xx_it.c * @authorMCD Application Team * @version V1.4.0 * @date04-August-2014 * @briefMain 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 intuart_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*/ /******************************************************************************//** * @briefThis function handles NMI exception. * @paramNone * @retval None */ void NMI_Handler(void) { }void assert_failed(uint8_t* file, uint32_t line) { // 这里就为断点能停下,然后返回, 看看,哪里参数设置错了 while (0) { } }/** * @briefThis function handles Hard Fault exception. * @paramNone * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { SystemReset(); //复位 } }/** * @briefThis function handles Memory Manage exception. * @paramNone * @retval None */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } }/** * @briefThis function handles Bus Fault exception. * @paramNone * @retval None */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } }/** * @briefThis function handles Usage Fault exception. * @paramNone * @retval None */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } }/** * @briefThis function handles SVCall exception. * @paramNone * @retval None */ //void SVC_Handler(void) //{ //}/** * @briefThis function handles Debug Monitor exception. * @paramNone * @retval None */ void DebugMon_Handler(void) { }/** * @briefThis function handles PendSVC exception. * @paramNone * @retval None */ //void PendSV_Handler(void) //{ //}/** * @briefThis function handles SysTick Handler. * @paramNone * @retval None */ //void SysTick_Handler(void) //{ // OS_CPU_SRcpu_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).*/ /******************************************************************************//** * @briefThis function handles PPP interrupt request. * @paramNone * @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****/

    推荐阅读