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 |
设备的初始化工作,如果和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****/
推荐阅读
- 2.6|2.6 Photoshop操作步骤的撤消和重做 [Ps教程]
- MongoDB,Wondows下免安装版|MongoDB,Wondows下免安装版 (简化版操作)
- 在线版的迅捷思维导图怎么操作()
- 操作系统|[译]从内部了解现代浏览器(1)
- 数据库总结语句
- JS常见数组操作补充
- 7、前端--jQuery简介、基本选择器、基本筛选器、属性选择器、表单选择器、筛选器方法、节点操作、绑定事件
- 炒股知识(超级短线操作的秘籍|炒股知识:超级短线操作的秘籍 玩转股市)
- 1.2序列通用操作
- MySQL数据库的基本操作