厂家提供了S32K14X系列的寄存器定义,如:
#define CAN_MCR_HALT_MASK 0x10000000u
#define CAN_MCR_HALT_SHIFT 28u
#define CAN_MCR_HALT_WIDTH 1u
#define CAN_MCR_HALT(x) (((uint32_t)(((uint32_t)(x))<
使用时方便,比如:
base->MCR = (base->MCR & ~CAN_MCR_HALT_MASK) | CAN_MCR_HALT(0U);
base->MCR = (base->MCR & ~CAN_MCR_FRZ_MASK) | CAN_MCR_FRZ(0U);
但是,在想要获取寄存器中某些位段的值时,需要使用寄存器的掩码和移位,比如:
while (((base->MCR & CAN_MCR_LPMACK_MASK) >> CAN_MCR_LPMACK_SHIFT) != 0U) {}
于是,想扩展以下格式的宏:
#define CAN_MCR_LPMACK_GET(r) (((r) & CAN_MCR_LPMACK_MASK) >> CAN_MCR_LPMACK_SHIFT)
这样,使用的时候只需要写
while(CAN_MCR_LPMACK_GET(base->MCR) != 0) {}
【解决办法】
在MATLAB中写一个脚本,自动从原始头文件中提取相关的定义,并生成全部GET宏。
脚本文件为:
%% 提取S32K的寄存器,补充GET宏
function S32K_GetMacro
[filename, pathname] = uigetfile('*.h', '请选择S32K的芯片寄存器头文件', 'S32K146.h');
if filename == 0
return;
end
% 生成完整的文件名
strFullFileName = fullfile(pathname, filename);
hfSrcHeaderFile = fopen(strFullFileName);
% 新生成的文件名
strDstFileName = strcat(filename(1:end - 2), '_get.h');
strDstFullFileName = fullfile(pathname, strDstFileName);
hfDstHeaderFile = fopen(strDstFullFileName, 'w+');
% 写文件头
fprintf(hfDstHeaderFile, '/*============================================================================*/\r\n');
fprintf(hfDstHeaderFile, '/**\r\n');
fprintf(hfDstHeaderFile, '*\r\n');
fprintf(hfDstHeaderFile, '* Copyright(c) 2000--2019 Shenzhen Technology Co.,Ltd\r\n');
fprintf(hfDstHeaderFile, '* ALL RIGHTS RESERVED\r\n');
fprintf(hfDstHeaderFile, '*\r\n');
fprintf(hfDstHeaderFile, '* @brief 用M脚本自动生成头文件,补充S32K硬件寄存器的GET宏定义\r\n');
fprintf(hfDstHeaderFile, '* @author [email protected]\r\n');
fprintf(hfDstHeaderFile, '* @date ');
fprintf(hfDstHeaderFile, datestr(now));
fprintf(hfDstHeaderFile, '\r\n');
fprintf(hfDstHeaderFile, '* @version 1000\r\n');
fprintf(hfDstHeaderFile, '*\r\n');
fprintf(hfDstHeaderFile, '*/\r\n');
fprintf(hfDstHeaderFile, '\r\n');
% #ifndef ...
strIfndef = upper(strDstFileName);
strIfndef = strrep(strIfndef, '.', '_');
fprintf(hfDstHeaderFile, ['#ifndef ', strIfndef, '\r\n', '#define ', strIfndef, '\r\n\r\n']);
while(1)
% 文件结尾
if feof(hfSrcHeaderFile)
break;
end
% 读取一行
strLine = fgetl(hfSrcHeaderFile);
SeperatorPosi = strfind(strLine, '(x)');
if isempty(SeperatorPosi)
continue;
end
strDefine = strLine(1 : SeperatorPosi(1) - 1); % 得到: #define ADC_SC1_ADCH
xPosi = strfind(strLine, '<<');
strShift = strLine(xPosi(1) + 2 : end); % ADC_SC1_ADCH_SHIFT))&ADC_SC1_ADCH_MASK)
xPosi = strfind(strShift, '&');
strMask = strShift(xPosi(1) + 1 : end); % ADC_SC1_ADCH_MASK)
xPosi2 = strfind(strMask, ')');
strMask = strMask(1: xPosi2(1) - 1); % 去掉最后的')'
strShift = strShift(1 : xPosi(1) - 1);
xPosi2 = strfind(strShift, ')');
strShift = strShift(1 : xPosi2(1) - 1);
% strRegGetLine = strcat(strDefine, '_GET(r) (((r)&', strMask, ')>>', strShift, ')');
% strRegGetLine = char(zeros(256, 1));
strRegGetLine = [strDefine, '_GET(r) '];
strRegGetLine = [strRegGetLine, blanks(52 - length(strRegGetLine))]; % 补齐到50个空格
strRegGetLine = [strRegGetLine, '(((r) & ', strMask, ') >> ', strShift, ')'];
fprintf(hfDstHeaderFile, strRegGetLine);
fprintf(hfDstHeaderFile, '\r\n\r\n');
end
% 写文件尾
% #endif
fprintf(hfDstHeaderFile, ['#endif', '\r\n', '\r\n\r\n']);
fclose(hfSrcHeaderFile);
fclose(hfDstHeaderFile);
disp('Complete!');
end