历史上的今天
今天是: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')
史海拾趣
|
一种改进的电压跟随PFCCukAC/DC变换器 随着半导体器件的发展,电力电子装置的大量应用,导致大量谐波电流涌入电网,污染电网,这一问题已引起了各国的重视。为了限制总的谐波含量(THD)以提高功率因数,制定了许多标准,如IEC1000?3?2。近年来,如 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 09:50 编辑 哪位高手手头上有altera公司的FFT-v2.1.1 ipcore的介绍,麻烦发给我一份,不胜感激。 邮箱:hutiao-001@163.com … 查看全部问答> |
|
在移植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芯片子屏显示功能,主屏可以正常显示。 子屏显示的字符为一段乱码,代码如下: void MB90092_DisChar (UCHAR x,UCHAR y,int addr,UCHAR mul,UCHAR bc,UCHAR cc,UCHAR ff) { ...… 查看全部问答> |
|
LPC1114到了,相机不在身边,拍不了照。呵呵! 前面已经我为他设计了一个舞台,该搭建了,让他在上面尽情的发挥。 [ 本帖最后由 zhdphao 于 2010-7-31 17:38 编辑 ]… 查看全部问答> |
|
是不是所有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. 网络实时播放 为进一步实现网络收音机的功能打下结实的基础。 代码功能简单,如下所示: # ...… 查看全部问答> |




