📄 kw_config.c
字号:
/**************************************************************************************
Copyright (C), 1988-1999, Xi'an Keyway Control & Measurement Technology Co., Ltd
FileName: kw_config.c
Description :config file 接口模块。
Version :1.0
Function List :
History: // 历史修改记录
<author> <time> <version > <desc>
LigangWang 07/08/08 1.0 build this moudle
LigangWang 07/10/09 1.1 增加错误处理,重新整理CM_ReadConfigToParam函数
以加强其健壮性,增加错误日志
*************************************************************************************/
#include "globals.h"
#include "kw_config.h"
#define CM_CONFIG_FILE_NAME "KWCONFIG.INI" // 配置文件名
xdata struct Config_PARAM CM_ConfigParameter; // 全局变量,配置参数
/*************************************************************************************
Function: SM_GetStringLength
Description: 获取字符串长度
Called By:
Input: str1 @ BYTE*: 字符串
Output: N/A
Return: length 字符串长
Others:
*************************************************************************************/
BYTE SM_GetStringLength(BYTE * str)
{
BYTE xdata length = 0;
while(*str != 0)
{
length++;
str++;
}
return length;
}
void CM_LogError(BYTE * err)
{
FM_OpenFileInRoot("KWSYSTEM.LOG");
FM_WriteFile("******************************\n",31);
FM_WriteFile(LOG_ERROR,SM_GetStringLength(LOG_ERROR));
FM_WriteFile(LOG_DEFAULT_P,SM_GetStringLength(LOG_DEFAULT_P));
FM_WriteFile(LOG_CONFIG_FILE,SM_GetStringLength(LOG_CONFIG_FILE));
FM_WriteFile(err,SM_GetStringLength(err));
}
/*************************************************************************************
Function: SM_CmpString
Description: 字符串比较是否相同
Called By:
Input: str1 @ BYTE*: 字符串1
str2 @ BYTE*: 字符串2
length @ BYTE: 比较长度
Output: N/A
Return: 若字符串相等则返回1;否则返回0
Others:
*************************************************************************************/
bit SM_CmpString(BYTE * str1, BYTE * str2, BYTE length)
{
while(length--)
{
if(*str1 != *str2)
{
return 0;
}
str1++;
str2++;
}
return 1;
}
/*************************************************************************************
Function: SM_CmpString2
Description: 字符串比较,从第start个字符开始比较字符串(按ASIIC码值比较)
Called By:
Input: str1 @ BYTE*: 字符串1
str2 @ BYTE*: 字符串2
length @ BYTE: 比较长度
start @ BYTE: 开始长度
Output: N/A
Return: 若字符串2大于字符串1相等则返回1;否则返回0
Others:
*************************************************************************************/
bit SM_CmpString2(BYTE * str1, BYTE * str2, BYTE length,BYTE start)
{
str1 += start;
str2 += start;
while(length--)
{
if(*str2 > *str1)
{
return 1;
}
if(*str2 < *str1)
{
return 0;
}
str1++;
str2++;
}
return 0;
}
/*************************************************************************************
Function: SM_CpyString
Description: 字符串复制,将src字符中length个字符复制到dst
Called By:
Input: dst @ BYTE*: 目的字符串
src @ BYTE*: 源字符串
length @ BYTE: 复制长度
Output: N/A
Return: 无意义
Others:
*************************************************************************************/
bit SM_CpyString(BYTE * dst, BYTE * src, BYTE length)
{
while(length--)
{
*dst = *src;
dst++;
src++;
}
return 1;
}
/*************************************************************************************
Function: SM_Char2BCD
Description: 将字符串str起始的2个字符转换成BCD码,例如"50"转换成0x50
Called By:
Input: str @ BYTE*: 源字符串
Output: N/A
Return: BYTE:转换结果
Others:
*************************************************************************************/
BYTE SM_Char2BCD(BYTE * str)
{
return ((*str - 0x30)<<4) | ((*(str+1) - 0x30) & 0x0f);
}
/*************************************************************************************
Function: CM_SkipNote(BYTE ** str)
Description: 处理配置文件中的注释
Called By:
Input: str
Output: N/A
Return: void
Others:
*************************************************************************************/
void CM_SkipNote(BYTE ** str)
{
SkipSpace(*str);
if(*(*str) == '#')
{
while(*(*str) != '\n' && *(*str) != '\r')
{
(*str) ++;
}
}
SkipSpace(*str);
}
/*************************************************************************************
Function: CM_CheckFlag(BYTE ** str)
Description: 检查标志
Called By:
Input: str
Output: N/A
Return: bit 0:失败,1:成功
Others:
*************************************************************************************/
bit CM_CheckFlag(BYTE ** str,BYTE * flag,BYTE length)
{
CM_SkipNote(str);
if(SM_CmpString(flag, *str, length) == 0)
{
return 0; //标志错
}
*str += length;
CM_SkipNote(str);
return 1;
}
/*************************************************************************************
Function: CM_ReadRS232Param(BYTE ** str)
Description: 读取RS232配置参数
Called By:
Input: str
Output: N/A
Return: bit 0:失败,1:成功
Others:
*************************************************************************************/
bit CM_ReadRS232Param(BYTE ** str)
{
CM_SkipNote(str);
if(SM_CmpString("115200", *str, 6) == 1) //读取BPS
{
CM_ConfigParameter.RS232_bps = RS232_115200;
*str += 6;
}
else if(SM_CmpString("57600", *str, 5) == 1)
{
CM_ConfigParameter.RS232_bps = RS232_57600;
*str += 5;
}
else if(SM_CmpString("38400", *str, 5) == 1)
{
CM_ConfigParameter.RS232_bps = RS232_38400;
*str += 5;
}
else if(SM_CmpString("19200", *str, 5) == 1)
{
CM_ConfigParameter.RS232_bps = RS232_19200;
*str += 5;
}
else if(SM_CmpString("9600", *str, 4) == 1)
{
CM_ConfigParameter.RS232_bps = RS232_9600;
*str += 4;
}
else if(SM_CmpString("4800", *str, 4) == 1)
{
CM_ConfigParameter.RS232_bps = RS232_4800;
*str += 4;
}
else
{
return 0; //BPS错误
}
SkipSpace(*str);
CM_ConfigParameter.RS232_Data = Char2Byte(**str); //读取数据位数
if(CM_ConfigParameter.RS232_Data != 8)
{
return 0;
}
(*str)++;
SkipSpace(*str); //读取校验位
CM_ConfigParameter.RS232_CH = (**str);
if(CM_ConfigParameter.RS232_CH != 'N')
{
return 0;
}
(*str)++;
SkipSpace(*str); //读取停止位数
CM_ConfigParameter.RS232_Stop = Char2Byte(**str);
if(CM_ConfigParameter.RS232_Stop != 1)
{
return 0;
}
(*str)++;
return 1;
}
/*************************************************************************************
Function: CM_ReadFileNameParam
Description: 从配置文件中读取参数到CM_ConfigParameter中
Called By:
Input: N/A
Output: N/A
Return: 1:读取成功,0:失败
Others:
*************************************************************************************/
bit CM_ReadFileNameParam(BYTE ** str)
{
CM_SkipNote(str);
CM_ConfigParameter.File_StartLength = Char2Byte(**str); //读取文件名前缀长度
if(CM_ConfigParameter.File_StartLength < 0 || CM_ConfigParameter.File_StartLength >8)
{
return 0;
}
(*str)++;
SkipSpace(*str);
SM_CpyString(CM_ConfigParameter.File_Start,*str,CM_ConfigParameter.File_StartLength);
(*str) += CM_ConfigParameter.File_StartLength;
SkipSpace(*str);
CM_ConfigParameter.File_End = Char2Byte(**str); //读取文件命名方式
if(CM_ConfigParameter.File_End != 0 && CM_ConfigParameter.File_End != 1)
{
return 0;
}
(*str)++;
SkipSpace(*str);
SM_CpyString(CM_ConfigParameter.File_Ext, *str,3); //读取文件扩展名
(*str) += 3;
return 1;
}
/*************************************************************************************
Function: CM_ReadConfigToParam
Description: 从配置文件中读取参数到CM_ConfigParameter中
Called By:
Input: N/A
Output: N/A
Return: 1:读取成功,0:失败
Others:
*************************************************************************************/
bit CM_ReadConfigToParam()
{
xdata BYTE * tmp;
xdata WORD i,clus,current_clus;
xdata DWORD fp_start_sector,file_length;
Dir_tag * fp = FM_OpenFileInRoot(CM_CONFIG_FILE_NAME); //打开配置文件
if(fp == 0)
{
CM_LogError(LOG_OPEN_FILE);
return 0; //文件打开失败
}
NM_ReadPage(FM_CurrentDirLBA);
file_length = (fp->FileLength[0] | fp->FileLength[1]<<8 //获取文件长度
| fp->FileLength[2]<<16 | fp->FileLength[3]<<24);
if(file_length == 0) //文件长度错误
{
FM_WriteFile(DEFAULT_CONFIG,SM_GetStringLength(DEFAULT_CONFIG));
CM_LogError(LOG_OPEN_FILE);
return 0;
}
((BYTE*)¤t_clus)[1] = fp->StartClus[0]; //获取开始簇
((BYTE*)¤t_clus)[0] = fp->StartClus[1];
fp_start_sector = (current_clus-2) * FM_sectors_clus + FM_ptr_data; //获取首扇区
clus = file_length/(FM_sectors_clus * 512); //计算总簇数
NM_ReadPage(fp_start_sector); //读取首扇区
tmp = EP6FIFOBUF;
//读取并检查文件标志[KW_CONFIG]
if(CM_CheckFlag(&tmp, CONFIG_FILE_FLAG, CONFIG_FILE_FLAG_LENGTH) == 0)
{
CM_LogError(LOG_FILE_FLAG);
return 0;
}
//读取并检查RS232字段标志
if(CM_CheckFlag(&tmp, CONFIG_RS232_FLAG, CONFIG_RS232_FLAG_LENGTH) == 0)
{
CM_LogError(LOG_RS232_F);
return 0; //标志错
}
if(CM_ReadRS232Param(&tmp) == 0)
{
CM_LogError(LOG_RS232_P);
return 0; //格式错误
}
//读取并检查文件名字段标志
if(CM_CheckFlag(&tmp, CONFIG_NAME_FLAG, CONFIG_NAME_FLAG_LENGTH) == 0)
{
CM_LogError(LOG_FILENAME_F);
return 0; //标志错
}
if(CM_ReadFileNameParam(&tmp) == 0)
{
CM_LogError(LOG_FILENAME_P);
return 0; //标志错
}
CM_SkipNote(&tmp);
//读取并检查RTC字段标志
if(CM_CheckFlag(&tmp, CONFIG_RTC_FLAG, CONFIG_RTC_FLAG_LENGTH) == 0)
{
CM_LogError(LOG_RTC_F);
return 0; //标志错
}
SkipSpace(tmp);
for(i = 0; i<6; i++) //读取6个字节作为年月日时分秒
{
CM_ConfigParameter.RTC_Time[i] = SM_Char2BCD(tmp);
tmp += 3;
}
SkipSpace(tmp); //读取RTC有效标志
CM_ConfigParameter.RTC_Valid = Char2Byte(*tmp);
if(CM_ConfigParameter.RTC_Valid != 0 && CM_ConfigParameter.RTC_Valid != 1)
{
CM_LogError(LOG_RTC_P);
return 0;
}
if(CM_ConfigParameter.RTC_Valid == 1)
{
*tmp = '0'; //修改标志为无效
NM_WritePages(fp_start_sector); //回写数据
}
return 1;
}
/*************************************************************************************
Function: CM_SetConfigParameterDefault
Description: 设置配置参数为默认参数
Called By:
Input: N/A
Output: N/A
Return: void
Others: 仅当CM_ReadConfigToParam函数调用识别时才调用本函数
*************************************************************************************/
void CM_SetConfigParameterDefault()
{
CM_ConfigParameter.RS232_bps = RS232_115200; //默认BPS为115200
CM_ConfigParameter.RS232_Data = 8; //默认数据8位
CM_ConfigParameter.RS232_Stop = 1; //默认停止位1
CM_ConfigParameter.RS232_CH = 'N'; //默认不校验
CM_ConfigParameter.File_StartLength = 3; //默认文件前缀3个字符
SM_CpyString(CM_ConfigParameter.File_Start,"DAT", //默认文件前缀"DAT"
CM_ConfigParameter.File_StartLength);
CM_ConfigParameter.File_End = CONFIG_FILE_SN; //默认命名方式但序号
SM_CpyString(CM_ConfigParameter.File_Ext,"TXT", //默认文件扩展名"TXT
CM_ConfigParameter.File_StartLength);
CM_ConfigParameter.RTC_Valid = 0; //默认RTC参数无效
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -