STM32F407串口操作
发布日期:2021-06-30 22:01:41 浏览次数:2 分类:技术文章

本文共 37301 字,大约阅读时间需要 124 分钟。

前言

一般的开发板,最多只能试验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个串口收发都好使。

试验

假设硬件没问题(这是前提条件)。

如果写的程序,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(); // 触发任务切换软中断}

防止库函数参数设置错

打开 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]; // 任务堆栈 - 串口1static OS_STK	Task_Stack_UART2[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口2static OS_STK	Task_Stack_UART3[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口3static OS_STK	Task_Stack_UART4[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口4static OS_STK	Task_Stack_UART5[TASK_UART_STACK_SIZE]; // 任务堆栈 - 串口5static 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 串口2void 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//波特率默认9600void 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//波特率默认9600void 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//波特率默认9600void 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 串口6void 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****/

转载地址:https://lostspeed.blog.csdn.net/article/details/101562962 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:STM32调试时打开assert_failed
下一篇:Nodejs服务端js的调试

发表评论

最新留言

不错!
[***.144.177.141]2024年05月04日 05时32分11秒