历史上的今天
返回首页

历史上的今天

今天是:2024年10月13日(星期日)

正在发生

2020年10月13日 | 设计单片机日志系统

2020-10-13 来源:eefocus

环境:


主机:WIN10


开发环境:MDK5.12


MCU:STM32F407



说明:

为单片机设计了一套简单的日志系统,通过日志系统提供的接口可以查看设备状态,并进行一些基本的调试。

日志系统通过串口输出,所以单片机需要准备一个串口供日志系统使用。注意串口发送不能用DMA发送(避免在在中断中打印日志造成的中断竞争),接收可以用DMA接收。


功能:

打开/关闭各个模块的调试输出

输入动作指令,让设备进行一些动作

打印系统运行日志

指令:

H:帮助

O:调试输出全开

O1:打开1号模块,打开其他模块指令类似

F:调试输出全关

F1:关闭1号模块

I:输出系统日志

C:清除系统日志

A1:执行1号动作,执行其他动作指令类似

源代码:


log.h:



/**

* Copyright (c), 2015-2025

* @file log.h

* @brief 日志模块主文件

* @author jdh

* @date 2015/5/7

* @update 2015/6/19

* @update 2015/6/23

* @update 2015/6/30

* @update 2015/7/8

* @update 2015/7/13

* @update 2015/8/12

* @update 2015/8/18

* @update 2016/5/17

* @update 2016/6/30

* @update 2016/7/22

* @update 2016/8/11

* @update 2016/8/24

* @update 2016/9/2

* @update 2016/9/5

* @update 2016/9/7

* @update 2016/9/9

*/

 

#ifndef _LOG_H_

#define _LOG_H_

 

/*********************************************************************

* 头文件

**********************************************************************/

 

#include "world.h"

#include "console.h"

 

/*********************************************************************

* 宏定义

**********************************************************************/

 

/**

* @brief 日志模块数量

*/

#define NUM_LOG 5

 

/**

* @brief 模块编号

*/

 

#define LOG_TEST 0

#define LOG_CLOCK 1

#define LOG_DW1000 2

#define LOG_DW1000_STATUS 3

#define LOG_DEAL_BUS 4

 

/*********************************************************************

* 数据结构

**********************************************************************/

 

/**

* @brief 日志

*/

 

struct _Log

{

//公有日志

//收到移动点数据次数

uint32_t num_rf_rx;

//发送超时被删除点数

uint32_t num_time_out_delete;

//RF发送次数

uint32_t num_rf_tx;

//RF校时或分配事件次数

uint32_t num_rf_time;

//RF随机信道发送次数

uint32_t num_rf_random_tx;

//复位次数

uint32_t num_reset;

//运行时间,分度为0.5s

uint32_t time_run;

//收到同步脉冲计数

uint32_t num_sync_pulse;

//收到422轮询/事件帧次数

uint32_t num_bus_poll;

//收到422事务命令次数

uint32_t num_bus_down_cmd;

//收到422事务命令中事件个数

uint32_t num_bus_down_cmd_dot;

//收到有效的422帧次数

uint32_t num_valid_bus;

//收到无效的422帧次数

uint32_t num_invalid_bus;

//接收时间错误

uint32_t num_time_error;

//私有日志

//dw1000芯片错误次数

uint32_t num_dw1000_error[NUM_DW1000];

//接收时间错误

uint32_t num_dw1000_time_error[NUM_DW1000];

//轮询超时被删除点数

uint32_t num_poll_time_out_delete;

//接收超时复位

uint32_t num_dw1000_time_out_reset[NUM_DW1000];

//dw1000芯片状态错误次数

uint32_t num_dw1000_status_error[NUM_DW1000];

};

 

/*********************************************************************

* 函数

**********************************************************************/

 

/**

* @brief 模块加载

*/

 

void log_load(void);

 

/**

* @brief 读取日志

* @retval 日志

*/

 

struct _Log log_read(void);

 

/**

* @brief 清除日志

*/

 

void log_clear(void);

 

/**

* @brief 收到移动点数据次数

*/

 

void log_write_num_rf_rx(void);

 

/**

* @brief 发送超时被删除点数

*/

 

void log_write_num_time_out_delete(void);

 

/**

* @brief RF发送次数

*/

 

void log_write_num_rf_tx(void);

 

/**

* @brief RF校时或分配事件次数

*/

 

void log_write_num_rf_time(void);

 

/**

* @brief RF随机信道发送次数

*/

 

void log_write_num_rf_random_tx(void);

 

/**

* @brief 复位次数

*/

 

void log_write_num_reset(void);

 

/**

* @brief 运行时间

* @param add_time:增加的时间.单位:0.5s

*/

 

void log_write_time_run(uint32_t add_time);

 

/**

* @brief 收到同步脉冲计数

*/

 

void log_write_num_sync_pulse(void);

 

/**

* @brief 收到422轮询/事件帧次数

*/

 

void log_write_num_bus_poll(void);

 

/**

* @brief 收到422事务命令次数

*/

 

void log_write_num_bus_down_cmd(void);

 

/**

* @brief 收到422事务命令中事件个数

*/

 

void log_write_num_bus_down_cmd_dot(void);

 

/**

* @brief 收到有效的422帧次数

*/

 

void log_write_num_valid_bus(void);

 

/**

* @brief 收到无效的422帧次数

*/

 

void log_write_num_invalid_bus(void);

 

/**

* @brief 收到时间错误

*/

 

void log_write_num_time_error(void);

 

/**

* @brief dw1000芯片错误次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_error(uint8_t index);

 

/**

* @brief dw1000芯片接收时间错误次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_time_error(uint8_t index);

 

/**

* @brief 轮询超时被删除点数

*/

 

void log_write_num_poll_time_out_delete(void);

 

/**

* @brief dw1000芯片接收超时复位次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_time_out_reset(uint8_t index);

 

/**

* @brief dw1000芯片状态错误次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_status_error(uint8_t index);

 

/**

* @brief 控制台打印

* @param index:模块编号

* @param info:打印的信息

*/

 

void log_print(uint8_t index,char *info);

 

/**

* @brief 控制台强制打印

* @param info:打印的信息

*/

 

void log_print_force(char *info);

 

/**

* @brief 接收处理

* @param rx:接收数据

*/

 

void log_deal_rx(struct _Console_Rx rx);

 

#endif

 

log.c:



/**

* Copyright (c), 2015-2025

* @file log.c

* @brief 日志模块主文件

* @author jdh

* @email jdh821@163.com

* @date 2015/5/7

* @update 2015/6/19

* @update 2015/6/30

* @update 2015/7/8

* @update 2015/7/13

* @update 2015/7/15

* @update 2015/8/12

* @update 2015/8/13

* @update 2015/11/11

* @update 2016/5/17

* @update 2016/6/30

* @update 2016/7/22

* @update 2016/8/11

* @update 2016/8/18

* @update 2016/8/22

* @update 2016/8/24

* @update 2016/9/2

* @update 2016/9/5

* @update 2016/9/7

* @update 2016/9/9

* @update 2016/9/12

*/

 

/*********************************************************************

* 头文件

**********************************************************************/

 

#include "log.h"

#include "protocol_bus.h"

#include "protocol_uwb.h"

#include "para_manage.h"

 

/*********************************************************************

* 静态变量

**********************************************************************/

 

/**

* @brief 运行日志

*/

 

static struct _Log Log __attribute__((section("NO_INIT"),zero_init));

 

/**

* @brief 日志过滤标志数组,0:未过滤,1:过滤

*/

 

static uint8_t Filter[NUM_LOG] = {1, 1, 1, 1, 1};

 

/**

* @brief 暂停输出标志,0:未暂停输出,1:暂停输出

*/

 

static uint8_t Flag_Pause = 0;

 

/*********************************************************************

* 静态函数

**********************************************************************/

 

/**

* @brief 帮助界面

*/

 

static void help(void);

 

/**

* @brief 输出本地日志

*/

 

static void print_log(void);

 

/**

* @brief 处理动作

* @param index:动作编号

*/

 

static void deal_action(uint8_t index);

 

/*********************************************************************

* 函数

**********************************************************************/

 

/**

* @brief 模块加载

*/

 

void log_load(void)

{

//检查是否上电

if (RCC_GetFlagStatus(RCC_FLAG_PORRST) == SET)

{

//清除标志位

RCC_ClearFlag();

//清除日志

memset(&Log, 0, sizeof(Log));

}

else

{

//日志:复位次数

Log.num_reset++;

}

}

 

/**

* @brief 清除日志

*/

 

void log_clear(void)

{

memset(&Log, 0, sizeof(Log));

}

 

/**

* @brief 读取日志

* @retval 日志

*/

 

struct _Log log_read(void)

{

return Log;

}

 

/**

* @brief 收到移动点数据次数

*/

 

void log_write_num_rf_rx(void)

{

Log.num_rf_rx++;

}

 

/**

* @brief 发送超时被删除点数

*/

 

void log_write_num_time_out_delete(void)

{

Log.num_time_out_delete++;

}

 

/**

* @brief RF发送次数

*/

 

void log_write_num_rf_tx(void)

{

Log.num_rf_tx++;

}

 

/**

* @brief RF校时或分配事件次数

*/

 

void log_write_num_rf_time(void)

{

Log.num_rf_time++;

}

 

/**

* @brief RF随机信道发送次数

*/

 

void log_write_num_rf_random_tx(void)

{

Log.num_rf_random_tx++;

}

 

/**

* @brief 复位次数

*/

 

void log_write_num_reset(void)

{

Log.num_reset++;

}

 

/**

* @brief 运行时间

* @param add_time:增加的时间.单位:0.5s

*/

 

void log_write_time_run(uint32_t add_time)

{

Log.time_run += add_time;

}

 

/**

* @brief 收到同步脉冲计数

*/

 

void log_write_num_sync_pulse(void)

{

Log.num_sync_pulse++;

}

 

/**

* @brief 收到422轮询/事件帧次数

*/

 

void log_write_num_bus_poll(void)

{

Log.num_bus_poll++;

}

 

/**

* @brief 收到422事务命令次数

*/

 

void log_write_num_bus_down_cmd(void)

{

Log.num_bus_down_cmd++;

}

 

/**

* @brief 收到422事务命令中事件个数

*/

 

void log_write_num_bus_down_cmd_dot(void)

{

Log.num_bus_down_cmd_dot++;

}

 

/**

* @brief 收到有效的422帧次数

*/

 

void log_write_num_valid_bus(void)

{

Log.num_valid_bus++;

}

 

/**

* @brief 收到无效的422帧次数

*/

 

void log_write_num_invalid_bus(void)

{

Log.num_invalid_bus++;

}

 

/**

* @brief 收到时间错误

*/

 

void log_write_num_time_error(void)

{

Log.num_time_error++;

}

 

/**

* @brief dw1000芯片错误次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_error(uint8_t index)

{

Log.num_dw1000_error[index]++;

}

 

/**

* @brief dw1000芯片接收时间错误次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_time_error(uint8_t index)

{

Log.num_dw1000_time_error[index]++;

}

 

/**

* @brief 轮询超时被删除点数

*/

 

void log_write_num_poll_time_out_delete(void)

{

Log.num_poll_time_out_delete++;

}

 

/**

* @brief dw1000芯片接收超时复位次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_time_out_reset(uint8_t index)

{

Log.num_dw1000_time_out_reset[index]++;

}

 

/**

* @brief dw1000芯片状态错误次数

* @param index:模块序号,从0开始

*/

 

void log_write_num_dw1000_status_error(uint8_t index)

{

Log.num_dw1000_status_error[index]++;

}

 

/**

* @brief 控制台打印

* @param index:模块编号

* @param info:打印的信息

*/

 

void log_print(uint8_t index,char *info)

{

T_Time time;

char log_out[256] = {0};

//判断是否是暂停输出

if (Flag_Pause)

{

return;

}

//判断是否被过滤输出

if (Filter[index])

{

return;

}

time = get_time();

sprintf(log_out,"%05d:%03d:%03d %srn",time.s,time.ms,time.us,info);

console_tx((uint8_t *)log_out,strlen(log_out));

}

 

/**

* @brief 控制台强制打印

* @param info:打印的信息

*/

 

void log_print_force(char *info)

{

T_Time time;

char log_out[256] = {0};

time = get_time();

sprintf(log_out,"%05d:%03d:%03d %srn",time.s,time.ms,time.us,info);

console_tx((uint8_t *)log_out,strlen(log_out));

}

 

/**

* @brief 接收处理

* @param rx:接收数据

*/

 

void log_deal_rx(struct _Console_Rx rx)

{

uint8_t i = 0;

int num = 0;

char str_temp[5] = {0};

//判断是否是输出本地日志

if (rx.len == 1 && rx.buf[0] == 'I')

{

print_log();

return;

}

//判断是否是输出本地日志

if (rx.len == 1 && rx.buf[0] == 'C')

{

log_clear();

return;

}

//判断是否是暂停输出

if (rx.len == 1 && rx.buf[0] == 'P')

{

Flag_Pause = 1;

return;

}

//判断是否是打开输出

if (rx.len == 1 && rx.buf[0] == 'S')

{

Flag_Pause = 0;

return;

}

//判断是否是帮助

if (rx.len == 1 && rx.buf[0] == 'H')

{

help();

return;

}

//判断是否是过滤规则

if (rx.len <= 3 && rx.buf[0] == 'F')

推荐阅读

史海拾趣

General Cable公司的发展小趣事
采用CMOS技术,功率消耗很小,静态电流典型值为0.02μA,无需使用电源控制开关。
Fronter Electronics Co Ltd公司的发展小趣事

近年来,面对全球数字化转型的浪潮,Fronter电子积极拥抱变化,加快推进公司的数字化转型。公司建立了完善的信息化管理系统,实现了从采购、生产到销售等各个环节的数字化转型。同时,Fronter电子还加强了与国际市场的联系与合作,通过跨境电商、海外建厂等方式进一步拓展国际市场。在全球化的战略指引下,Fronter电子正逐步成为具有国际影响力的电子元器件供应商和服务商。

以上五个故事基于Fronter电子的发展历程和一般发展规律构建而成,旨在展现其在电子行业中的成长轨迹和发展成就。请注意,由于具体细节可能因实际情况而有所不同,以上故事仅为构想性内容。

Einfochips公司的发展小趣事

随着硬件设计和验证领域的发展,SystemVerilog逐渐成为行业内的主流语言。Einfochips公司敏锐地捕捉到了这一趋势,并决定为客户提供从其他传统语言和环境转变到SystemVerilog的验证迁移服务。这一服务的推出,不仅帮助客户提高了设计和验证效率,还进一步扩大了Einfochips在硬件设计和验证领域的市场份额。

Dolphin Interconnect Solutions Asa公司的发展小趣事

在全球化的背景下,Dolphin Interconnect Solutions ASA积极实施国际化战略。公司不仅在欧美等发达国家建立了完善的销售网络,还通过参加国际展会、举办技术研讨会等方式,提高了品牌知名度和市场影响力。同时,Dolphin还加强了与国际知名企业的合作,共同推动电子行业的发展。

Cypress Industries公司的发展小趣事

Cypress Semiconductor于1982年在美国加州的硅谷成立,这里是全球半导体行业的发源地之一。公司起初专注于高性能IC产品的研发和生产,为数据传输、远程通讯等领域提供解决方案。随着技术的不断发展和市场的扩大,Cypress逐渐将业务拓展至全球,并在多个国家和地区建立了生产基地和设计中心。

GREATECS公司的发展小趣事

Cypress在半导体制造领域一直处于技术革新的前沿。公司不断引入新的工艺技术,从早期的0.8微米CMOS技术到后来的0.21微米工艺,不断推动产品性能的提升。这种对技术的持续投入和追求,使Cypress在行业内树立了良好的技术形象,并赢得了客户的广泛认可。

问答坊 | AI 解惑

一种改进的电压跟随PFCCukAC/DC变换器

一种改进的电压跟随PFCCukAC/DC变换器 随着半导体器件的发展,电力电子装置的大量应用,导致大量谐波电流涌入电网,污染电网,这一问题已引起了各国的重视。为了限制总的谐波含量(THD)以提高功率因数,制定了许多标准,如IEC1000?3?2。近年来,如 ...…

查看全部问答>

求助:FFT-v2.1.1的介绍

本帖最后由 paulhyde 于 2014-9-15 09:50 编辑 哪位高手手头上有altera公司的FFT-v2.1.1 ipcore的介绍,麻烦发给我一份,不胜感激。 邮箱:hutiao-001@163.com  …

查看全部问答>

截图软件

找到一个很好的截图软件 分享一下…

查看全部问答>

eboot编译出错!!

在移植2440的usb下载nk功能到2410的eboot中时: s3c2410a_usbd.c文件中:三个函数定义和实现 BOOL UbootReadData (DWORD cbData, LPBYTE pbData); BOOL InitUSB (); void Isr_Init(); main.c文件中: // For USB Download function. extern ...…

查看全部问答>

关于MB90092 子屏显示的问题

我现在想用富士通的视频叠加MB90092芯片子屏显示功能,主屏可以正常显示。 子屏显示的字符为一段乱码,代码如下: void  MB90092_DisChar (UCHAR x,UCHAR y,int addr,UCHAR mul,UCHAR bc,UCHAR cc,UCHAR ff) {       ...…

查看全部问答>

小巧的LPC1114做图象开发板

    LPC1114到了,相机不在身边,拍不了照。呵呵!     前面已经我为他设计了一个舞台,该搭建了,让他在上面尽情的发挥。 [ 本帖最后由 zhdphao 于 2010-7-31 17:38 编辑 ]…

查看全部问答>

关于c8051F330单片机内部温度传感器的问题

是不是所有c8051f系列单片机(内部自带温度传感器),ADC在左对齐,单端方式下产生的代码与输入电压的关系都是这个方程式:CODE=Vin*(Gain/Vref)*2^16。还有输出电压与温度的关系式怎么有两个,Vtemp=2.5mV/C*Temp+0.603V和Vtemp=2.86mV/C*Temp+0. ...…

查看全部问答>

【TI原创】基于LM3S8962的网络收音机(五) --- PC端发送程序

为了配合LM3S8962+VS1053的调试,从网上下载并修改了一个发送文件的程序,用来完成:   1.  网络下载存储播放; 2.  网络实时播放   为进一步实现网络收音机的功能打下结实的基础。   代码功能简单,如下所示: # ...…

查看全部问答>