基于单片机的数字安匝仪
技术领域
本发明属于电子检测仪器领域。
背景技术
目前,一般的数字安匝仪系统有两种检测方式,一种通过供电检测,另一种是供磁检测,对于供电检测的优点是可以很好地控制电路的电压电流,而一般的供电检测方案不仅检测周期比较长,而且检测出来的干簧管的AT值得精度不高,尤其是航天领域的设备,根本无法满足系统对器件稳定程度的要求,以往只能是多次检测,但是多次检测时间长,容易增加干簧管的物理故障率,因此国内的干簧管检测设备重复操作,精度不高,而且容易带来不稳定的因素。
发明内容
本发明的目的是通过单片机利用多路AD将基准电压分成多份,从而提高了干簧管检测精度的基于单片机的数字安匝仪。
本发明是由CPU处理器、丝杠电机、图像采集单元、键盘单元、图像存储单元、电压调节单元组成:
CPU处理器:采用MC9SXS128最小系统;
丝杠电机:通过步进电机驱动,将电机连接到CPU处理器的主控芯片上;电机的OUT1~OUT4接到ULN2003的16~13脚;
图像采集单元:通过主控芯片的控制来切换摄像机,摄像头OV7620的11~18脚连接到CPU处理器的24~31脚,3、4接CPU处理器的8、7脚;摄像头NV628电源接升压电路的12V输出端,视频输出端接到PDS模块,然后经过AV转USB模块连接到USB转SCI中的USB端;
键盘单元:4X4键盘的PA0~PA7接到CPU的57~64脚;
图像存储单元:将采集到的图像存储在存储工具中,为了以后的图像融合,SD卡中的1、2、7、8、9脚经电阻接VCC,2脚接CPU处理器的96脚,5脚接CPU的95脚,7脚接CPU的93脚,8脚接CPU的94脚;
电压调节单元:5V端接供电电源的5V,12V端接nv628的电源端;
其具体流程是:
1、系统初始化阶段:锁相环初始化函数、模数转换初始化函数、PIT定时器初始化函数、SCI串口通信初始化函数、LCD显示屏初始化函数、GPIO口初始化函数、SAMPLE采样初始化函数;
2、系统检测阶段:
①等待干簧管的插入,如果没有干簧管插入,处于一直扫描状态,直到有干簧管插入;当有干簧管插入时,等待100毫秒,再次检测是否有干簧管插入;
②处于吸合状态,通过提高电压值来促使干簧管内部导通,当增加的叫压使干簧管导通时,将当前的DA输出电压值赋给变量ActuationDAData,此时的吸合标志位被置位,通过公式计算吸合时的AT值,公式:
ActuationSensitivity[MeasureCounter]=0.9544*ActuationDAData/4096*供电电压值/(线圈电阻+限流电阻1+限流电阻2)*线圈匝数;
③定时器每0.1ms扫描下是否释放,由于释放时的AT值比吸合时大,因此在减少电压时,是增加电压的2倍,当释放完时,定时器将释放标志置位,同时将当前的DA输出值赋给ReleaseDAData,这些都是在PIT定时器中完成;
④测量完成,检测干簧管是否拔出,即判断测量是否结束了,将DA的输出值清零;
3、显示阶段:设置固定时间,将测量的结果送到显器显示。
本发明解决了以往的干簧管检测设备检测周期长和检测精度低的问题,设计了一套由单片机和显示单元组成的检测系统。本系统通过12路AD检测,提高了检测精度,很大程度上解决了一般检测设备的检测精度问题,同时通过程序设计和优化降低了检测程序的运行时间,解决了检测设备检测周期长的问题,而且将各个单元集成在一起,节省了空间,并且线路连接简单方便,操作比较简单。本数字安匝仪的突出特点是将单片机与高精度AD结合,提高了检测精度,同时程序的优化,降低了检测周期,提高了检测效率。
附图说明
图1是本发明工艺流程图;
图2是本发明检测单元电路图;
图3是本发明主控单元电路图;
图4是本发明输出显示单元电路图;
图5是本发明安匝管的线圈驱动单元电路图;
图6是本发明安匝管的供电电源单元电路图;
图7是本发明安匝管的系统整体框图。具体实施方式
本发明是由CPU处理器、丝杠电机、图像采集单元、键盘单元、图像存储单元、电压调节单元组成:
CPU处理器:采用MC9SXS128最小系统;
丝杠电机:通过步进电机驱动,将电机连接到CPU处理器的主控芯片上;电机的OUT1~OUT4接到ULN2003的16~13脚;
图像采集单元:通过主控芯片的控制来切换摄像机,摄像头OV7620的11~18脚连接到CPU处理器的24~31脚,3、4接CPU处理器的8、7脚;摄像头NV628电源接升压电路的12V输出端,视频输出端接到PDS模块,然后经过AV转USB模块连接到USB转SCI中的USB端;
键盘单元:4X4键盘的PA0~PA7接到CPU的57~64脚;
图像存储单元:将采集到的图像存储在存储工具中,为了以后的图像融合,SD卡中的1、2、7、8、9脚经电阻接VCC,2脚接CPU处理器的96脚,5脚接CPU的95脚,7脚接CPU的93脚,8脚接CPU的94脚;
电压调节单元:5V端接供电电源的5V,12V端接nv628的电源端;
其具体流程是:
1、系统初始化阶段:锁相环初始化函数、模数转换初始化函数、PIT定时器初始化函数、SCI串口通信初始化函数、LCD显示屏初始化函数、GPIO口初始化函数、SAMPLE采样初始化函数;
2、系统检测阶段:
①等待干簧管的插入,如果没有干簧管插入,处于一直扫描状态,直到有干簧管插入;当有干簧管插入时,等待100毫秒,再次检测是否有干簧管插入;
②处于吸合状态,通过提高电压值来促使干簧管内部导通,当增加的叫压使干簧管导通时,将当前的DA输出电压值赋给变量ActuationDAData,此时的吸合标志位被置位,通过公式计算吸合时的AT值,公式:
ActuationSensitivity[MeasureCounter]=0.9544*ActuationDAData/4096*供电电压值/(线圈电阻+限流电阻1+限流电阻2)*线圈匝数;
③定时器每0.1ms扫描下是否释放,由于释放时的AT值比吸合时大,因此在减少电压时,是增加电压的2倍,当释放完时,定时器将释放标志置位,同时将当前的DA输出值赋给ReleaseDAData,这些都是在PIT定时器中完成;
④测量完成,检测干簧管是否拔出,即判断测量是否结束了,将DA的输出值清零;
3、显示阶段:设置固定时间,将测量的结果送到显器显示。
以下结合附图对本发明做进一步详细的描述:
本数字安匝仪是有检测单元、主控单元、输出显示单元、程序烧录单元组成:
检测单元:正极探针与主控单元的MC9S12XS128芯片的51脚相连,微动开关的2脚与主控单元的MC9S12XS128芯片的54脚相连;
主控单元:采用MC9S12XS128芯片的最小系统;
输出显示单元:LCD的1~4脚与主控单元的MC9S12XS128芯片的14~11脚相连,LCD的8~12脚与主控单元的MC9S12XS128芯片的21~17脚相连;
程序烧录单元:JA1为BDM烧录模块,BDM的BKGD脚与主控单元的MC9S12XS128芯片的23脚相连;
线圈驱动单元:AD转换芯片AD7541的1和18脚接LMC6482的2脚和1脚,AD7541的4~15脚接主控单元的MC9S12XS128的IO口,LMC6482的6和7脚接主控单元的32脚;
图2中的S1为待检测的干簧管,由于需要将是否有干簧管放入和检测干簧管的AT值的数据传输给单片机,故将微动开关的2脚接主控单元MC9S12XS128的54脚,将整机探针接MC9S12XS128的51脚。
图3中的P1A和P1B是主控芯片MC9S12XS128的引脚图,由于需要将检测的数据传输给主控芯片,因此将IO口连接到检测单元。
图4中的LCD为输出显示屏,本系统将检测的数据显示在此LCD,以便检测人员记录。
图5是线圈驱动电路,通过AD7541将检测到的模拟信号转换为数字信号传递给单片机,以便系统判定干簧管的优劣。
本发明通过12路AD转换芯片和16位单片机组成的系统,以期望提高干簧管检测的检测精度同时缩短检测周期,从而达到又快又高精度的完成检测过程。本数字安匝管是由检测单元、主控单元、输出显示单元、线圈驱动单元、供电电源单元共同组成。将干簧管放入线圈中后,开启电源给系统供电,系统将逐步增加电压进而使干簧管的簧片接触,检测单元将检测到的信号传递给主控单元的主控芯片,通过主控芯片的处理得到干簧管的AT值,然后显示在显示屏上,方便检测人员的读取与记录。由于本数字安匝管的检测精度高、检测周期短,所以适用于那些对于干簧管的稳定性和精度要求高的工业方面,例如航空方面。
干簧管检测步骤:
打开检测系统的电源,给硬件提供电源,同时软件系统开始工作:
1)系统初始化阶段:
锁相环初始化函数:
设置总线频率为80Mhz,设置锁相环频率为160Mhz,同时设置PLLCLK作为系统时钟,并且使能锁相环,使之能为系统使用,由于系统时钟的确定,那么相应的内部那些依赖系统时钟的部分就可以以该频率为基准频率进行相应的操作来满足那些工作频率不同于此频率的片内模块的使用;
模数转换初始化函数:
启动AD模块,模块设置为转换完成后,标志位快速自动清零,禁止使用中断,选用12位模数转换,每次只转换一个通道,并且AD模块的时钟频率为BUSCLOCK/2/(PRS+1)=80M/2/(4+1)=8M;
该部分对应的外部电路是线圈驱动电路中的AD7541引脚,由系统的A和B口给AD7541的BIT0~11脚按位写数据,相应的输出作用于运算放大器LMC6482的INA-端口,经过放大器的模拟信号经由AD7引脚接入到单片机内,由于采用12位模数转换,而供电电压是5V直流电源,则理论上的分辩力为5*1/4096,就是约等于0.00125V,即1.25mV;
PIT定时器初始化函数:
装载8位计数器0和1的初值,并将16位计数器0和8位计数器1相连,同时装载16计数的初值,使能通道0的溢出中断,使能16位计数器通道0,使能PIT模块;在定时器中断中对系统的一些参数进行变更,以方便对于干簧管状态的判断;
SCI串口通信初始化函数:
计算波特率并设置:ubgs=fsys/(波特率*16)(其中fsys=sysclk*1000000);根据函数的给定参数计算ubgs=40*1000000/(115200*16),设置允许SCI正常码输出8位数据,无校验,允许SCI0接收和发送,通过串口的通信来观察程序运行中的一些错误,另外,当系统检测的数据存在问题时,可以通过串口通信的方式,来判断是检测过程有问题,还是后边的显示部分有问题,能够更快的判系统的故鄣出在什么位置,更利于对系统缺陷的发现与改进,能够缩短系统的开发周期;
LCD显示屏初始化函数:
通过对一些引脚的电平设置以及高低电平转换,完成启动之前的准备工作,然后将显示屏的对比度进行设置,分别为粗调和微调以达到最好的显示效果,设置完这些之后,控制显示屏使其将整个屏幕从上支下、从左到右的扫描一下,并且从第一行开始,使整个显示屏都开显示。
由于显示器的反应速度不如单片机,在初始化时,需要慢慢的进行,并且需要一步步的进行,当没有外部的电位器可以改变对比度时(通常的电位器的精度不够,会使调节中的显示器的对比度变化比较大),只能通过对该部分的函数调用的参数的修改来达到改变对比度的效果,由于系统中分为粗调和细调,则会达到更好的显示效果,LCD的初始化是整个系统中最慢的,本部分对应于LCD显示屏的电路图PORTM,PORTP为对应的数据控制端和位选控制端;
GPIO口初始化函数:
设置PORTA、B口为输出,并同时将PORTA、B口的电压设置为低电平,从而使该IO口用于从单片机向外部传输数据。
本部分对应于线圈驱动中的AD7541芯片,通过A、B口向BIT0~11写入数据,从而为其提供不同的电平值;
SAMPLE采样初始化函数:
设定判断是否插入干簧管和干簧管是否导通的IO口的状态为输入状态,从而根据这两个端口的电平判断干簧管当前的状态。
当没有干簧管插入时,相应的E6引脚的电压为高电平,当有干簧管插入时,开关的引脚接到2处,由于E6所在的回路形成闭合回路,且此回路能正常导通,当导通后对应的E6引脚的电平由高电平转换为低电平,本系统就是通过这个E6的电平高低来判断是否有干簧管插入。当插入的干簧管没有导通时,相应的E5引脚为高电平,当插入的干簧管导通后,则在干簧管两端的电路组成闭合回路,由于干簧管的导通,整个闭合回路导通,相应的E5的电平被拉低,本系统就是利用这个来判断干簧管是否导通。
当导通后,需要判断干簧管是否由导通变换为断开,当导通时,相应的E6引脚是低电平,如果是干长簧管断开了,则E6引脚的电平就会由低电平转化为高电平,从而判断是否释放了干长簧管,如果干簧管已经被取走,则相应的E5引脚的电平就会由低电平转变为主高电平,从而判断干簧管被取走。
2)系统检测阶段:
第一步:
等待干簧管的插入,如果没有干簧管插入,处于一直扫描状态,直到有干簧管插入;当有干簧管插入时,等待100毫秒,再次检测是否有干簧管插入,再次检测的目的是防止第一次的是由于检测过程中的干扰影响的,两次检测可以减少产生这种出错的机率,当两次的扫描都显示有干簧管插入,则通过标志将函数转到第二步,同时计算DA的输出电压值,
导通时的电流值=电压/线圈匝数,线圈电压为5V;
导通时的DA_Rf处的电压值=电流*(线圈电阻+限流电阻1+限流电阻2);
DA输出的电压值=导通时的DA_Rf处的电压值/供电电压值*4096;
第二步:
如果仍然处于吸合状态,通过提高电压值来促使干簧管内部导通,即干簧管所在的电路导通(由于考虑到检测时间的问题,本系统并没有一下加的电压是1/4096*供电电压值,而是增加的是上述值的10倍,精度也从原来的1.25mV变为12.5mV=0.0125V);当增加的叫压使干簧管导通时,将当前的DA输出电压值赋给变量ActuationDAData(本步骤是通过PIT定时器完成的,定时器每0.1MS判断下是否干簧管导通,当导通时完成赋值操作),此时的吸合标志位被置位,通过公式计算吸合时的AT值,公式:
ActuationSensitivity[MeasureCounter]=0.9544*ActuationDAData/4096*供电电压值/(线圈电阻+限流电阻1+限流电阻2)*线圈匝数,将吸合标志位清除,并且转到第三步;
否则如果此时的DA输出值比DA的限制数据最大值大,则跳到第三步;
如果此时的干簧管没有处在吸合状态,并且此时的DA输出值比DA的限制数据的最大值大,则跳到出错状态,同时反馈出来出错的标志,标志为1;
第三步:
本阶段定时器也是每0.1ms扫描下是否释放,由于释放时的AT值比吸合时大,因此在减少电压时,是增加电压的2倍,当释放完时,定时器将释放标志置位,同时将当前的DA输出值赋给ReleaseDAData,这些都是在PIT定时器中完成的。
如果现在的状态是释放状态,并且释放标志位存在,开始计算释放时的AT值:
ReleaseSensitivity[MeasureCounter]=0.8592*ReleaseDAData/4096*供电电压值/(线圈电阻+限流电阻1+限流电阻2)*线圈匝数,将释放标志位清除,如果取样的次数超过了3次,则取其前3次,并且对于这3次取样的AT值先进行排序,然后取其中央的值作为最后显示的值(这实际就是一次中值滤波的过程,对于一定量的采样数据,取其最中间的数据或是中间的两个的数据的平均值作为最终测量的结果,从而能免除一些因为操作或是别的原因引起的误差,使测试的结果的准确性更高),对于吸合AT值和释放AT值都是采用此方法进行的滤波处理,
如果采样的数据不够3个,则跳到第二步进行再次测量,由于此处理器的处理速度比较快,在测量时只有一个用于防止误判断的100毫秒的廷时,因此每多一次采样所多出来的时间不超过0.2秒,3次不多于0.4秒,考虑到准确性的原因,所以采用了这种牺牲时间的代价来换取更高的准确率,执行完这些,就跳到第四步;
如果标志位不存在,并且DA的输出值比DA数据的最小值小,则采用同上述方法一样的中值滤波进行去除误差及干扰来提高准确度,同样也是如果是数据量够3个,则计算相应的吸合和释放时的AT值,然后使程序跳转到第四步,如果数据数量不够,那么跳到第二步,继续进行测量,同时将所有的标志置位。
如果没有释放,并且DA的输出值比DA数据的最小值小,则将DA输出的值清零,然后跳到出错状态,同时返回错误代码2,用于提示用户是系统的哪一部分出现了错误,方便用户找出原因,并纠正。
第四步:
测量完成,检测干簧管是否拔出,即判断测量是否结束了,将DA的输出值清零,由于已经测量完成,不需要继续浪费能量来提供DA输出了,当干簧管拔出后,相应电路中的E6引脚的电平由原来的低电平转换为高电平,通过这个来判断干簧管是否拔出,当判断到已经拔出后,清掉所有的标志,并将当前的AT值,以防止引起用户的误解,到此为止,所有的测量已经完成。
PIT定时器:
前面提到通过提高电压值和降低电压值来使干簧管达到吸合和释放状态,而这些功能正是在PIT定时器中完成的,定时器每隔1MS扫描一下,通过标志位来判断是否处于第二或第三步。
如果处于第二步,则将DA的输出增加10*1/4096*供电电压值,当电压加到一定程度,干簧管吸合,则将此时的DA输出值作为计算AT值的参数同时将吸合标志置起,用于程序判断别的状态;
如果是处于第三步,则将DA的输出值减少20*1/4096*供电电压值,更快的使干簧管释放,从而测取干簧管的释放AT值,当干簧管断开时,将干簧管断开标志置位,并且将此时的DA输出值作为计算释放时AT值的参数;
如果干簧管处于这两步中,但没有达到释放或是吸合的状态,那么将前面计算的DA输出值重新输出到AD7541的BIT0~11引脚,使其进行下一次的判断,定时器时时刻刻都在扫描干簧管的各个标志,从而判断应该进行什么样的操作,定时器与前面的程序是同时执行的,将定时器的处理结果用于判断此时的状态是否该继续下一步,还是跳到上一步,或者是继续本步骤不动。
3)显示阶段:
每隔一段时间进行一次将测量的结果送到显器显示,在显示阶段,首先根据当前的DA输出值计算此时的AT值,计算完之后,开始在屏幕显示,在显示屏的第一行显示的是干簧管检测仪”六个字,第二行显示的是当前的AT值,第三行显示的是吸合时的AT值,在第四行显示的是释放时的AT值。为了让用户更方便的记录数据,本系统会在测试完之后,在显示屏上一直显示此结果。
用户关闭电源,干簧管检测结束。
实例:
精度测量:
由于本系统采用12位AD转换,理论上的精度为1/4096*供电电压值,但是考虑到时间成本,本系统没有直接用这个精确度,而是采用了10/4096*供电电压值,分辩力约为0.01,其他的测试AT值的系统的精度只是0.1,因此本系统的精度更高。
稳定性和故障率:
以上两张表是对于两个不同的干簧管,用以前的系统和本系统的测量AT值的对比。
通过这两张表可以明显看出本系统在稳定性方面的优势:
1)对于第一张图:此前的系统的最大吸合和释放的AT值的差分别是0.4和4,而本系统的最大吸合和释放AT值的差分别是0.26和0.56,明显比以前的系统的稳定怕性更好。
2)对于第二张图:此前的系统的最大吸合和释放的AT值的差分别是0.8和4.4,而本系统的最大吸合和释放AT值的差分别是0.08和0.57,很显然本系统的稳定性能更好。
由于本系统得到的数据都是在手工焊接的电路板上进行测试的结果,其稳定性肯定不如做成的PCB板的数据准确,并且本手工测试系统的稳定性都这么高,则相应的PCB板的稳定性会更高,相应的稳定性提高的系统它的故障率就会相对的降低,并且系统内部有中值滤波程序,可以去除一部分的干扰和误判的结果,可以进一步降低系统的故障率。
本发明的源代码:
函数
#include<hidef.h>
#include"derivative.h"
#include"Include.h"
floatDAOutVoltage;u16DisplayUpdataCounter;floatMaxSensi,MinSensi,Diff;
unsignedcharjiong1[]={
0x00,0xFE,0x82,0x42,0xA2,0x9E,0x8A,0x82,0x86,0x8A,0xB2,0x62,0x02,0xFE,0x00,0x00,
0x00,0x7F,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x7F,0x00,0x00};
unsignedcharlei1[]={
0x80,0x80,0x80,0xBF,0xA5,0xA5,0xA5,0x3F,0xA5,0xA5,0xA5,0xBF,0x80,0x80,0x80,0x00,
0x7F,0x24,0x24,0x3F,0x24,0x24,0x7F,0x00,0x7F,0x24,0x24,0x3F,0x24,0x24,0x7F,0x00};
unsignedcharbmp1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xE0,0x60,0xE0,0xE0,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,
0x60,0x60,0xE0,0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0xC0,0xE0,0x70,0x38,0x18,0x1C,0x0C,0x0E,0x07,0x03,0x03,0x01,0x81,0xE0,0x78,0x1C,0x0E,0x07,0x03,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x79,0xE1,0x83,
0x03,0x07,0x0E,0x0C,0x1C,0x18,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xF0,0x78,0x1E,0x07,0x03,0x81,0x80,0xC0,0xC0,0xC0,0xE0,0x60,0x60,0x60,0x70,0xF0,0xFE,
0x3F,0x19,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x38,0x31,0x3F,0xFE,0xF0,0x60,0x60,0xE0,0xC0,0xC0,0xC0,0x80,0x81,0x03,0x07,0x1E,
0x78,0xF0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0xFF,0x7F,0x07,0x0F,0x1F,0x3D,0x79,0x71,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xE0,0xF0,0x71,0x79,0x3D,0x1F,0x0F,0xFF,0xFE,0xFC,0x00,0x00,0x00,0x00,0x00,0x80,0xFE,0xFF,0xF9,0x1C,0x0E,0x07,0x03,0x03,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x07,0x0E,0x1C,0xF9,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0F,0x0E,0x9E,0xFC,0xF8,0xF0,0xE0,0xC0,0xC0,0x80,0x00,0x00,
0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,0xF0,0xF8,0xF8,0xFC,0x9E,0x0F,0x07,0x03,0x03,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xDF,0x38,0x70,0xE0,0xC0,0xC0,0x80,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xE0,0x70,0x38,0xDF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0x78,0x3C,0x1E,0x0F,0x07,0x03,0x01,0x00,0x01,0x01,0x03,0x07,0x0F,0x1E,0x1E,0x0E,0x0F,0x07,0x03,0x01,0x01,0x00,0x01,0x01,0x03,0x07,0x0F,0x1E,0x3C,0x78,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x3C,0x70,0xE0,0xC1,0x81,0x03,0x03,0x03,0x07,0x06,0x06,0x06,0x0E,0x0F,0x7F,0xFC,0x98,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x0C,0x8C,0xFC,0x7F,
0x0F,0x06,0x06,0x07,0x03,0x03,0x03,0x81,0xC1,0xE0,0x70,0x3C,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0F,0x1F,0x3F,0x7C,0xFC,0xFE,0xEF,0xE7,0xE3,0xE1,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE1,0xE3,0xE7,0xEF,0xFE,0x7C,0x3F,0x1F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x0C,0x1C,0x18,0x38,0x70,0x60,0xE0,0xC0,0xC1,0x87,0x9E,
0xB8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,
0xB8,0xDE,0xC7,0xE1,0x60,0x70,0x38,0x18,0x1C,0x0C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x03,0x03,0x03,0x03,0x03,0x07,0x07,0x07,0x07,0x07,0x07,
0x07,0x07,0x07,0x03,0x03,0x03,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};u8MeasureStep;u16DA_OutData;
u8ErrorCode;u8ActuationRecordFlag;u8ActuationFlag;u16ActuationDAData;floatActuationSensFinal;
floatActuationSensitivity[SAMPLE_TIMES];u8ReleaseRecordFlag;u8ReleaseFlag;u16ReleaseDAData;
floatReleaseSensFinal;floatReleaseSensitivity[SAMPLE_TIMES];u8MeasureCounter;floatSensitivityNow;
unsignedlongfontaddr=0;u8CANDataBuffer[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8sendDataLength=8;CANFramesendFrame,rcvFrame;u8CANSendErrorFlag;u32CANSendErrorCounter;
u32CANRcvErrorCounter;u8CANRcvDataUpdateFlag;u32CANSendError1Counter;u32CANSendError2Counter;
u32CANSendError3Counter;u32CANSendError4Counter;u8CANRcvErrorFlag;u32CANRcvDataCounter;u32CANSendDataCounter;unsignedlongT_DECI1MS_Counter;u16PWMPeriod[4]={5000,5000,5000,5000};
voidmain(void){System_Init();MaxSensi=0;MinSensi=30;Diff=0;for(;;){switch(MeasureStep){case0:{
if(REED_NOT_INSERT_STATUS==0){DelayMs(100);if(REED_NOT_INSERT_STATUS==0){ActuationSensFinal=0;ReleaseSensFinal=0;DA_OutData=CalculateDAOutData(5);MeasureStep=1;}}}break;case1:{if(ActuationFlag==1){
if(ActuationRecordFlag==0){ActuationSensitivity[MeasureCounter]=CalculateSensitivity(1,ActuationDAData);
ActuationRecordFlag=1;MeasureStep=2;}else{if(DA_OutData>DA_DATA_LIMITING_MAX){MeasureStep=2;}}}else{if(DA_OutData>DA_DATA_LIMITING_MAX){DA_OutData=0;MeasureStep=3;ErrorCode=1;}}}break;case2:{
if(ReleaseFlag==1){if(ReleaseRecordFlag==0){ReleaseSensitivity[MeasureCounter]=CalculateSensitivity(2,ReleaseDAData);ReleaseRecordFlag=1;{MeasureCounter++;if(MeasureCounter>=SAMPLE_TIMES){MeasureCounter=0;
ActuationSensFinal=MedianFilter(SAMPLE_TIMES,ActuationSensitivity);ReleaseSensFinal=MedianFilter(
SAMPLE_TIMES,ReleaseSensitivity);if(ActuationSensFinal>MaxSensi)MaxSensi=ActuationSensFinal;elseif(ActuationSensFinal<MinSensi)MinSensi=ActuationSensFinal;MeasureStep=3;}else{DA_OutData=
CalculateDAOutData(15);MeasureStep=1;}ActuationRecordFlag=0;ReleaseRecordFlag=0;ActuationFlag=0;
ReleaseFlag=0;}}else{if(DA_OutData<DA_DATA_LIMITING_MIN){MeasureCounter++;if(MeasureCounter>=
SAMPLE_TIMES){MeasureCounter=0;ActuationSensFinal=Average(SAMPLE_TIMES,ActuationSensitivity);
ReleaseSensFinal=Average(SAMPLE_TIMES,ReleaseSensitivity);MeasureStep=3;}else{DA_OutData=
CalculateDAOutData(15);MeasureStep=1;}ActuationRecordFlag=0;ReleaseRecordFlag=0;ActuationFlag=0;
ReleaseFlag=0;}}}else{if(DA_OutData<DA_DATA_LIMITING_MIN){DA_OutData=0;MeasureStep=3;ErrorCode=2;}}}break;case3:{DA_OutData=0;if(REED_NOT_INSERT_STATUS==1){MeasureStep=0;ErrorCode=0;SensitivityNow=0;}}break;default:break;}Diff=MaxSensi-MinSensi;DisplayUpdataCounter++;if(DisplayUpdataCounter>=30000){
DisplayUpdataCounter=0;SensitivityNow=CalculateSensitivity(1,DA_OutData);
display_GB2312_string(1,3,"干簧管检测仪");DisplayFloatVariable2312(3,1,"AT_NOW:%5.2f",SensitivityNow);
DisplayFloatVariable2312(5,1,"AT_ON:%5.2f",ActuationSensFinal);
DisplayFloatVariable2312(7,1,"AT_OFF:%5.2f",ReleaseSensFinal);}}}
voidSystem_Init(void){DisableInterrupts;PLL_Init();AD_Init();PIT_Init();SCIInit(0,40,115200);LCD_Init();
ControlInit();SampleInit();MeasureStep=0;MeasureCounter=0;EnableInterrupts;}voidtransfer_command_lcd(intdata1){chari;LCD_RS=0;for(i=0;i<8;i++){LCD_SCLK=0;if(data1&0x80)LCD_SDA=1;elseLCD_SDA=0;LCD_SCLK=1;
data1=data1<<=1;}}voidtransfer_data_lcd(intdata1){chari;LCD_RS=1;for(i=0;i<8;i++){LCD_SCLK=0;
if(data1&0x80)LCD_SDA=1;elseLCD_SDA=0;LCD_SCLK=1;data1=data1<<=1;}}voidLCDPort_Init(void){
Rom_IN_DIR=1;Rom_OUT_DIR=0;Rom_SCK_DIR=1;Rom_CS_DIR=1;LCD_SCLK_DIR=1;LCD_SDA_DIR=1;
LCD_RS_DIR=1;LCD_RES_DIR=1;LCD_CS_DIR=1;}
voidLCD_Init(void){LCDPort_Init();Rom_CS=1;LCD_CS=0;Rom_CS=1;LCD_RES=0;DelayUs(1000);
LCD_RES=1;DelayUs(1000);transfer_command_lcd(0xe2);DelayUs(559);transfer_command_lcd(0x2c);
DelayUs(559);transfer_command_lcd(0x2e);DelayUs(559);transfer_command_lcd(0x2f);DelayUs(559);
transfer_command_lcd(0x23);transfer_command_lcd(0x81);transfer_command_lcd(0x20);
transfer_command_lcd(0xa2);transfer_command_lcd(0xc8);transfer_command_lcd(0xa0);
transfer_command_lcd(0x40);transfer_command_lcd(0xaf);clear_screen();}
voidlcd_address(unsignedintpage,unsignedintcolumn){column=column-0x01;
transfer_command_lcd(0xb0+page-1);transfer_command_lcd(0x10+(column>>4&0x0f));transfer_command_lcd(column&0x0f);}
voidclear_screen(void){unsignedchari,j;LCD_CS=0;Rom_CS=1;for(i=0;i<9;i++){transfer_command_lcd(0xb0+i);
transfer_command_lcd(0x10);transfer_command_lcd(0x00);for(j=0;j<132;j++){transfer_data_lcd(0x00);}}
LCD_CS=1;}
voiddisplay_128x64(unsignedchar*dp){unsignedinti,j;LCD_CS=0;for(j=0;j<8;j++){lcd_address(j+1,1);
for(i=0;i<128;i++){transfer_data_lcd(*dp);dp++;}}LCD_CS=1;}
voiddisplay_graphic_16x16(unsignedintpage,unsignedintcolumn,unsignedchar*dp){unsignedinti,j;
LCD_CS=0;Rom_CS=1;for(j=0;j<2;j++){lcd_address(page+j,column);for(i=0;i<16;i++){transfer_data_lcd(*dp);
dp++;}}LCD_CS=1;}
voiddisplay_graphic_8x16(unsignedintpage,unsignedcharcolumn,unsignedchar*dp){unsignedinti,j;
LCD_CS=0;for(j=0;j<2;j++){lcd_address(page+j,column);for(i=0;i<8;i++){transfer_data_lcd(*dp);dp++;}}
LCD_CS=1;}
voiddisplay_graphic_5x7(unsignedintpage,unsignedcharcolumn,unsignedchar*dp){
unsignedintcol_cnt;unsignedcharpage_address;unsignedcharcolumn_address_L,column_address_H;
page_address=0xb0+page-1;LCD_CS=0;column_address_L=(column&0x0f)-1;column_address_H=((column>>4)&0x0f)+0x10;transfer_command_lcd(page_address);transfer_command_lcd(column_address_H);
transfer_command_lcd(column_address_L);for(col_cnt=0;col_cnt<6;col_cnt++){transfer_data_lcd(*dp);dp++;}
LCD_CS=1;}
voidsend_command_to_ROM(unsignedchardatu){unsignedchari;for(i=0;i<8;i++){if(datu&0x80)Rom_IN=1;elseRom_IN=0;datu=datu<<1;Rom_SCK=0;Rom_SCK=1;}}
staticunsignedcharget_data_from_ROM(){unsignedchari;unsignedcharret_data=0;
Rom_SCK=1;for(i=0;i<8;i++){Rom_OUT=1;Rom_SCK=0;ret_data=ret_data<<1;if(Rom_OUT)
ret_data=ret_data+1;elseret_data=ret_data+0;Rom_SCK=1;}return(ret_data);}
voidget_n_bytes_data_from_ROM(unsignedcharaddrHigh,unsignedcharaddrMid,unsignedcharaddrLow,unsignedchar*pBuff,unsignedcharDataLen){unsignedchari;Rom_CS=0;LCD_CS=1;Rom_SCK=0;
send_command_to_ROM(0x03);send_command_to_ROM(addrHigh);send_command_to_ROM(addrMid);
send_command_to_ROM(addrLow);for(i=0;i<DataLen;i++)*(pBuff+i)=get_data_from_ROM();Rom_CS=1;}
voiddisplay_GB2312_string(unsignedchary,unsignedcharx,unsignedchar*text){unsignedchari=0;
unsignedcharaddrHigh,addrMid,addrLow;unsignedcharfontbuf[32];
while((text[i]>0x00)){if(((text[i]>=0xb0)&&(text[i]<=0xf7))&&(text[i+1]>=0xa1)){
fontaddr=(text[i]-0xb0)*94;fontaddr+=(text[i+1]-0xa1)+846;fontaddr=(unsignedlong)(fontaddr*32);
addrHigh=(fontaddr&0xff0000)>>16;addrMid=(fontaddr&0xff00)>>8;addrLow=fontaddr&0xff;
get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32);display_graphic_16x16(y,x,fontbuf);i+=2;x+=16;}elseif(((text[i]>=0xa1)&&(text[i]<=0xa3))&&(text[i+1]>=0xa1)){fontaddr=(text[i]-0xa1)*94;
fontaddr+=(text[i+1]-0xa1);fontaddr=(unsignedlong)(fontaddr*32);addrHigh=(fontaddr&0xff0000)>>16;
addrMid=(fontaddr&0xff00)>>8;addrLow=fontaddr&0xff;
get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,32);display_graphic_16x16(y,x,fontbuf);i+=2;x+=16;}elseif((text[i]>=0x20)&&(text[i]<=0x7e)){unsignedcharfontbuf[16];fontaddr=(text[i]-0x20);fontaddr=(unsignedlong)(fontaddr*16);fontaddr=(unsignedlong)(fontaddr+0x3cf80);addrHigh=(fontaddr&0xff0000)>>16;
addrMid=(fontaddr&0xff00)>>8;addrLow=fontaddr&0xff;
get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,16);display_graphic_8x16(y,x,fontbuf);i+=1;
x+=8;}elsei++;}}
voiddisplay_string_5x7(unsignedchary,unsignedcharx,unsignedchar*text){unsignedchari=0;unsignedcharaddrHigh,addrMid,addrLow;while((text[i]>0x00)){if((text[i]>=0x20)&&(text[i]<=0x7e)){unsignedcharfontbuf[8];
fontaddr=(text[i]-0x20);fontaddr=(unsignedlong)(fontaddr*8);fontaddr=(unsignedlong)(fontaddr+0x3bfc0);
addrHigh=(fontaddr&0xff0000)>>16;addrMid=(fontaddr&0xff00)>>8;addrLow=fontaddr&0xff;
get_n_bytes_data_from_ROM(addrHigh,addrMid,addrLow,fontbuf,8);display_graphic_5x7(y,x,fontbuf);i+=1;x+=6;}elsei++;}}
voidDisplayFloatVariable5x7(u8row,u8col,consts8*format,floatdat){s8array[21];
display_string_5x7(row,col,array);}
voidDisplayFloatVariable2312(u8row,u8col,consts8*format,floatdat){s8array[21];
display_GB2312_string(row,col,array);}
unsignedintGetSmoothADValue0(unsignedintoriginal_ad_value){staticunsignedint
ad_value_buffer[SMOOTH_NUM];staticunsignedcharcurrent_count;unsignedchari;
unsignedlongad_value_sum;unsignedintsmooth_ad_value;ad_value_buffer[current_count++]=
original_ad_value;if(current_count>=SMOOTH_NUM)current_count=0;ad_value_sum=0;for(i=0;i<SMOOTH_NUM;i++)ad_value_sum+=ad_value_buffer[i];smooth_ad_value=(unsignedint)
(ad_value_sum/SMOOTH_NUM);returnsmooth_ad_value;}floatAverage(u8num,float*dat){u8i;floatsum;sum=0;for(i=0;i<num;i++)sum+=dat[i];sum/=num;returnsum;}floatCalculatePressure(unsignedintad_value){
floattemp,pressure;temp=((float)ad_value*5/4096-0.5)/0.016+0.5;temp=temp-6;pressure=(temp<0)?(0):(temp);
returnpressure;}floatCalculateVacuumDegree(unsignedintad_value){floatvoltage,vacuum_degree;
voltage=(float)ad_value*5/4096;vacuum_degree=-25*voltage+12.5;returnvacuum_degree;}
floatCalculateCurrent(unsignedintad_value){floatU_is,R_is,K_ilis,current;U_is=(float)ad_value*5/4096;
R_is=1000;K_ilis=19500/3;current=K_ilis*U_is/R_is;returncurrent;}
floatCalculateSensitivity(u8mod,unsignedintDA_Data){floatvoltage,current,sensitivity;
voltage=(float)DA_Data/4096*(-REFERENCE_VOLTAGE_N15V);current=voltage/(R_CURRENT_LIMITING_1+R_CURRENT_LIMITING_2+R_COIL);sensitivity=current*COIL_TURNS;if(mod==1)returnsensitivity*0.9455;else
returnsensitivity*0.8592;}
floatCalculateDAOutVoltage(u16dat){floatU;U=(float)dat*REFERENCE_VOLTAGE_P5V/4096*(
R_CURRENT_LIMITING_1+R_CURRENT_LIMITING_2+R_COIL)/R_CURRENT_LIMITING_1;returnU;}
u16CalculateDAOutData(floatat){floatda_current,da_voltage;u16da_out_dat;da_current=
at/COIL_TURNS;da_voltage=da_current*(R_CURRENT_LIMITING_1+R_CURRENT_LIMITING_2+R_COIL);
da_out_dat=(u16)(s16)(da_voltage/(-REFERENCE_VOLTAGE_N15V)*4096);returnda_out_dat;}
floatMedianFilter(u8num,float*value_buf){u8i,j;floattemp;for(j=0;j<num-1;j++){for(i=0;i<num-j-1;i++){
if(value_buf[i]>value_buf[i+1]){temp=value_buf[i];value_buf[i]=value_buf[i+1];value_buf[i+1]=temp;}}}returnvalue_buf[(num-1)/2];}
voidSampleInit(void){REED_NOT_INSERT_STATUS_DIR=0;REED_NOT_BREAKOVER_STATUS_DIR=0;}
unsignedintCRC16_Calculate(unsignedchar*ptr,unsignedcharlen,unsignedintweight){unsignedintcrc=0;unsignedchari;while(len-->0){crc=(crc^(((unsignedint)*ptr)<<8));for(i=0;i<8;i++)
{if(crc&0x8000)crc=((crc<<1)^weight);elsecrc<<=1;}ptr++;}returncrc;}
voidSerialProtocolSend(unsignedchar*SendData,unsignedcharLength,unsignedcharMode){
unsignedchari,CRC16H,CRC16L;unsignedshortintCRC16;if(Mode==0)
CRC16=CRC16_Calculate(SendData,Length,0x1021);elseCRC16=CRC16_Calculate(SendData,Length,0x8005);
CRC16L=(unsignedchar)CRC16;CRC16H=CRC16>>8;for(i=0;i<Length;i++)SCISendByte(0,SendData[i]);
SCISendByte(0,CRC16H);SCISendByte(0,CRC16L);}
voidControlInit(void){GPIO_Init();DA_SetData(0);}
voidDA_SetData(u16dat){PORTAB=dat;}
voidAD_Init(void){ATD0CTL2=0xc0;ATD0CTL1_SRES=2;ATD0CTL3=0x88;ATD0CTL4_PRS=4;}unsignedintAD_Sample(unsignedcharchannel){ATD0CTL5=channel;while(!ATD0STAT0_SCF);returnATD0DR0;}
voidDFlash_Init(void){while(FSTAT_CCIF==0);FCLKDIV=0x0F;FCNFG=0x00;while(FCLKDIV_FDIVLD==0);}
voidDFlash_Write4Word(unsignedshortintADDR16,unsignedshortintdat[]){
while(FSTAT_CCIF==0);if(FSTAT_ACCERR)FSTAT_ACCERR=1;if(FSTAT_FPVIOL)FSTAT_FPVIOL=1;
FCCOBIX_CCOBIX=0x00;FCCOB=0x1100|(DFLASH_START>>16);FCCOBIX_CCOBIX=0x01;FCCOB=ADDR16;
FCCOBIX_CCOBIX=0x02;FCCOB=dat[0];FCCOBIX_CCOBIX=0x03;FCCOB=dat[1];FCCOBIX_CCOBIX=0x04;
FCCOB=dat[2];FCCOBIX_CCOBIX=0x05;FCCOB=dat[3];FSTAT_CCIF=1;while(FSTAT_CCIF==0);}
unsignedshortintDFlash_ReadWord(unsignedshortintADDR16){unsignedcharlastepage,epage;unsignedshortintdat;lastepage=EPAGE;epage=(unsignedchar)((DFLASH_LOWEST_START_PAGE)+(ADDR16>>10));
EPAGE=epage;dat=READword((ADDR16&(DFLASH_PAGE_SIZE-1))+DFLASH_PAGE_WINDOW_START);
EPAGE=lastepage;returndat;}
voidDFlash_EraseSector(unsignedshortintADDR16){while(FSTAT_CCIF==0);if(FSTAT_ACCERR)
FSTAT_ACCERR=1;if(FSTAT_FPVIOL)FSTAT_FPVIOL=1;FCCOBIX_CCOBIX=0x00;
FCCOB=0x1200|(DFLASH_START>>16);FCCOBIX_CCOBIX=0x01;FCCOB=ADDR16;FSTAT_CCIF=1;
while(FSTAT_CCIF==0);}
voidCANInit(void){CAN0CTL1_CANE=1;CAN0CTL0_INITRQ=1;while(CAN0CTL1_INITAK==0);
CAN0IDMR0=0xFF;CAN0IDMR1=0xFF;CAN0IDMR2=0xFF;CAN0IDMR3=0xFF;CAN0IDMR4=0xFF;
CAN0IDMR5=0xFF;CAN0IDMR6=0xFF;CAN0IDMR7=0xFF;CAN0BTR0=0x07;CAN0BTR1=0x25;
CAN0CTL1_CLKSRC=1;CAN0CTL1_LISTEN=0;CAN0CTL0_INITRQ=0;while(CAN0CTL1_INITAK==1);
while(CAN0CTL0_SYNCH==0);CAN0TIER=0x00;CAN0RIER_RXFIE=1;CANDataInit();}
voidCANDataInit(void){CANSendErrorFlag=0;CANSendErrorCounter=0;CANRcvErrorFlag=0;
CANRcvErrorCounter=0;CANRcvDataUpdateFlag=0;CANRcvDataCounter=0;CANSendDataCounter=0;}
u8CANSendFrame(CANFrame*sendFrame){u8txEmptyBuf;u8i;if(sendFrame->m_dataLen>8){
return1;}if(CAN0CTL0_SYNCH==0){return2;}txEmptyBuf=0;for(i=0;i<16&&!txEmptyBuf;i++){
CAN0TBSEL=CAN0TFLG;txEmptyBuf=CAN0TBSEL;}if(i>=16)return3;if(sendFrame->m_IDE==0){
CAN0TXIDR0=(u8)(sendFrame->m_ID>>3);CAN0TXIDR1=(u8)(sendFrame->m_ID<<5);
CAN0TXIDR1_SRR=sendFrame->m_RTR;CAN0TXIDR1_IDE=sendFrame->m_IDE;}else{return4;}
if(sendFrame->m_RTR==0){for(i=0;i<sendFrame->m_dataLen;i++){
*((&CAN0TXDSR0)+i)=sendFrame->m_data[i];}CAN0TXDLR=sendFrame->m_dataLen;}else{
CAN0TXDLR=0;}CAN0TXTBPR=sendFrame->m_priority;CAN0TFLG=txEmptyBuf;return0;}
u8CANRcvFrame(CANFrame*receiveFrame){u8i;if(CAN0RFLG_RXF==0){return1;}
if(CAN0RXIDR1_IDE==0){receiveFrame->m_ID=(u32)(CAN0RXIDR0<<3)|(u32)(CAN0RXIDR1>>5);
receiveFrame->m_RTR=CAN0RXIDR1_SRR;receiveFrame->m_IDE=0;}else{return2;}
if(CAN0RXIDR1_SRR==0){receiveFrame->m_dataLen=CAN0RXDLR_DLC;
for(i=0;i<receiveFrame->m_dataLen;i++){receiveFrame->m_data[i]=*((&CAN0RXDSR0)+i);}}
else{receiveFrame->m_dataLen=0;}CAN0RFLG_RXF=1;return0;}
u8CANFillFrame(CANFrame*frame,u32id,u8ide,u8rtr,u8*data,u8len,u8priority){u8i;frame->m_ID=id;if(ide>2){return1;}frame->m_IDE=ide;if(rtr>2){return2;}frame->m_RTR=rtr;if(len>8){return3;}frame->m_dataLen=len;for(i=0;i<frame->m_dataLen;i++){frame->m_data[i]=data[i];}frame->m_priority=priority;return0;}
voidDelayMs(unsignedinti){unsignedintj,k;for(k=0;k<i;k++)for(j=0;j<6665;j++);}
voidDelayUs(unsignedinti){unsignedintj;for(j=0;j<i;j++);}
voidGPIO_Init(void){DDRAB=0XFFFF;}voidLED_Init(void){LED_STATUS_DIR=1;LED_STATUS=1;}
voidPLL_Init(void){CLKSEL&=0x7f;PLLCTL&=0x8F;
#if(BUS_CLOCK==120000000)
SYNR=0xcd;
#elif(BUS_CLOCK==104000000)
SYNR=0xcc;
#elif(BUS_CLOCK==96000000)
SYNR=0xcb;
#elif(BUS_CLOCK==88000000)
SYNR=0xca;
#elif(BUS_CLOCK==80000000)
SYNR=0xc9;
#elif(BUS_CLOCK==72000000)
SYNR=0xc8;
#elif(BUS_CLOCK==64000000)
SYNR=0xc7;
#elif(BUS_CLOCK==56000000)
SYNR=0xc6;
#elif(BUS_CLOCK==48000000)
SYNR=0xc5;
#elif(BUS_CLOCK==40000000)
SYNR=0x44;
#elif(BUS_CLOCK==32000000)
SYNR=0x43;
#elif(BUS_CLOCK==24000000)
SYNR=0x42;
#elif(BUS_CLOCK==16000000)
SYNR=0x01;
#endif
REFDV=0x81;PLLCTL|=0x70;asmNOP;asmNOP;while(!(CRGFLG&0x08));CLKSEL|=0x80;}
voidPWM_Init(void){PWME=0x00;PWMCTL=0xF0;PWMPOL=0xff;PWMCAE=0x00;
PWMPRCLK=0x44;PWMCLK=0x00;PWMPER01=PWMPeriod[0];PWMDTY01=0;PWME_PWME1=1;
PWMPER23=PWMPeriod[1];PWMDTY23=0;PWME_PWME3=1;}
voidPWM_Set(u8ch,floatduty){*(&PWMDTY01+ch)=(u16)(s32)(duty*PWMPeriod[ch]);}
voidSCIInit(u8SCINo,u8sysclk,u32baud){u8t;u16ubgs=0;if(SCINo>1)SCINo=1;ubgs=
(u16)(sysclk*(10000/(baud/100))/16);switch(SCINo){case0:SCI0BDH=(u8)((ubgs&0xFF00)>>8);
SCI0BDL=(u8)(ubgs&0x00FF);SCI0CR1=0x00;t=SCI0DRL;t=SCI0SR1;SCI0CR2=0x0C;break;
case1:SCI1BDH=(u8)((ubgs&0xFF00)>>8);SCI1BDL=(u8)(ubgs&0x00FF);SCI1CR1=0x00;
t=SCI1DRL;t=SCI1SR1;SCI1CR2=0x0C;break;}}
voidSCISendByte(u8SCINo,u8dat){u16k;if(SCINo>1){SCINo=1;}switch(SCINo){case0:for(k=0;k<0xfbbb;k++){if((ReSendStatusR0&(1<<SendTestBit))!=0){ReSendDataR0=dat;break;}}break;case1:
for(k=0;k<0xfbbb;k++){if((ReSendStatusR1&(1<<SendTestBit))!=0){ReSendDataR1=dat;break;}}break;}}
voidSCISendNByte(u8SCINo,u8n,u8dat[]){u8i;for(i=0;i<n;i++)SCISendByte(SCINo,dat[i]);}
u8SCIRcvByte(u8SCINo,u8*p){u16k;u8i;if(SCINo>1){SCINo=1;}switch(SCINo){case0:for(k=0;k<0xfbbb;k++)if((ReSendStatusR0&(1<<ReTestBit))!=0){i=ReSendDataR0;*p=0x00;break;}if(k>=0xfbbb){i=0xff;*p=0x01;}
returni;break;case1:for(k=0;k<0xfbbb;k++)if((ReSendStatusR1&(1<<ReTestBit))!=0){i=ReSendDataR1;*p=0x00;break;}if(k>=0xfbbb){i=0xff;*p=0x01;}returni;break;}}
u8SCIRcvNByte(u8SCINo,u8n,u8dat[]){u8m;u8fp;m=0;while(m<n){
dat[m]=SCIRcvByte(SCINo,&fp);if(fp==1)return1;m++;}return0;}
voidSCISendString(u8SCINo,s8*p){u32k;if(SCINo>1){SCINo=1;}if(p==0)return;for(k=0;p[k]!='\0';++k){SCISendByte(SCINo,p[k]);}}
voidPIT_Init(void){PITCFLMT_PITE=0;PITMTLD0=100-1;PITMTLD1=250-1;PITMUX_PMUX0=1;
PITLD0=1024-1;PITINTE_PINTE0=1;PITCE_PCE0=1;PITCFLMT_PITE=1;T_DECI1MS_Counter=0;}
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterruptVectorNumber_Vpit0PIT0_ISR(void){PITTF=0x01;T_DECI1MS_Counter++;
if(MeasureStep==1){DA_OutData+=STEP_VALUE;if(REED_NOT_BREAKOVER_STATUS==0){
ActuationDAData=DA_OutData;ActuationFlag=1;}}elseif(MeasureStep==2){
DA_OutData-=STEP_VALUE*2;if(REED_NOT_BREAKOVER_STATUS==1){
ReleaseDAData=DA_OutData;ReleaseFlag=1;}}DA_SetData(DA_OutData);}
#pragmaCODE_SEGDEFAULT
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterruptVectorNumber_Vpit1PIT1_ISR(void){PITTF=0x02;}
#pragmaCODE_SEGDEFAULT
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterruptVectorNumber_Vpit2PIT2_ISR(void){PITTF=0x04;}
#pragmaCODE_SEGDEFAULT
#pragmaCODE_SEG__NEAR_SEGNON_BANKED
voidinterruptVectorNumber_Vpit3PIT3_ISR(void){PITTF=0x08;}
#pragmaCODE_SEGDEFAULT
Include.h
#ifndef__INCLUDE_H__
#define__INCLUDE_H__
#include<MC9S12XS128.h>
#defineREED_NOT_INSERT_STATUSPORTE_PE6
#defineREED_NOT_INSERT_STATUS_DIRDDRE_DDRE6
#defineREED_NOT_BREAKOVER_STATUSPORTE_PE5
#defineREED_NOT_BREAKOVER_STATUS_DIRDDRE_DDRE5
#defineREFERENCE_VOLTAGE_P5V(4.99)
#defineREFERENCE_VOLTAGE_P15V(15.07)
#defineREFERENCE_VOLTAGE_N15V(-15.10)
#defineR_CURRENT_LIMITING_1(511)
#defineR_CURRENT_LIMITING_2(999)
#defineR_COIL(444)
#defineCOIL_TURNS(5000)
#defineAT_LIMITING_MAX(30)
#defineAT_LIMITING_MIN(10)
#defineDA_DATA_LIMITING_MAX(3228)
#defineDA_DATA_LIMITING_MIN(1076)
#defineSAMPLE_TIMES(3)
#defineSTEP_VALUE(10)
#defineSMOOTH_NUM(10)
#defineRom_INPTM_PTM0/*字库IC接口定义:ROM_IN就是字库IC的SI*/
#defineRom_IN_DIRDDRM_DDRM0/*字库IC接口方向定义*/
#defineRom_OUTPTM_PTM1/*字库IC接口定义:ROM_OUT就是字库IC的SO*/
#defineRom_OUT_DIRDDRM_DDRM1/*字库IC接口方向定义*/
#defineRom_SCKPTM_PTM2/*字库IC接口定义:ROM_SCK就是字库IC的SCK*/
#defineRom_SCK_DIRDDRM_DDRM2/*字库IC接口方向定义*/
#defineRom_CSPTM_PTM3/*字库IC接口定义ROM_CS就是字库IC的CS#*/
#defineRom_CS_DIRDDRM_DDRM3/*字库IC接口方向定义*/
#defineLCD_SCLKPTP_PTP0/*接口定义:LCD_SCLK就是LCD的sclk*/
#defineLCD_SCLK_DIRDDRP_DDRP0/*字库IC接口方向定义*/
#defineLCD_SDAPTP_PTP1/*接口定义:LCD_SDA就是LCD的sid*/
#defineLCD_SDA_DIRDDRP_DDRP1/*字库IC接口方向定义*/
#defineLCD_RSPTP_PTP2/*接口定义:LCD_RS就是LCD的rs*/
#defineLCD_RS_DIRDDRP_DDRP2/*字库IC接口方向定义*/
#defineLCD_RESPTP_PTP3/*接口定义:LCD_RES就是LCD的reset*/
#defineLCD_RES_DIRDDRP_DDRP3/*字库IC接口方向定义*/
#defineLCD_CSPTP_PTP4/*接口定义:LCD_CS就是LCD的cs1*/
#defineLCD_CS_DIRDDRP_DDRP4/*字库IC接口方向定义*/
#defineBIT_SET(bit,Register)((Register)|=(1<<(bit)))
#defineBIT_CLR(bit,Register)((Register)&=~(1<<(bit)))
#defineBIT_GET(bit,Register)(((Register)>>(bit))&1)
#defineEnableSCIReInt0SCI0CR2|=0x20//开放SCI0接收中断
#defineDisableSCIReInt0SCI0CR2&=0xDF//禁止SCI0接收中断
#defineEnableSCIReInt1SCI1CR2|=0x20//开放SCI1接收中断
#defineDisableSCIReInt1SCI1CR2&=0xDF//禁止SCI1接收中断
#defineReSendStatusR0SCI0SR1//SCI0状态寄存器
#defineReSendDataR0SCI0DRL//SCI0数据寄存器
#defineReSendStatusR1SCI1SR1//SCI0状态寄存器
#defineReSendDataR1SCI1DRL//数据寄存器
#defineReTestBit5//接收缓冲区满标志位
#defineSendTestBit7//发送缓冲区空标志位
#defineBUS_CLOCK(80000000)//总线频率,改变总线频率直接在此处修改
#defineLED_STATUSPTT_PTT2
#defineLED_STATUS_DIRDDRT_DDRT2
#defineREADword(address)((unsignedint)(*(volatileunsignedint*__near)(address)))
#defineDFLASH_LOWEST_START_PAGE0x00//定义dataflash的起始页
#defineDFLASH_START0x00100000//定义dataflash的起始地址
#defineDFLASH_PAGE_SIZE0x0400//定义dataflash的大小为1K.
#defineDFLASH_PAGE_WINDOW_START0x0800
typedefunsignedcharu8;typedefunsignedshortintu16;typedefunsignedlongintu32;typedefsignedchars8;
typedefsignedshortints16;typedefsignedints32;typedefvolatileu8vu8;typedefvolatileu16vu16;
typedefvolatileu32vu32;typedefvolatiles8vs8;typedefvolatiles16vs16;typedefvolatiles32vs32;
voidControlInit(void);voidDA_SetData(u16dat);floatAverage(u8num,float*dat);
unsignedintGetSmoothADValue0(unsignedintoriginal_ad_value);floatCalculatePressure(unsignedintad_value);floatCalculateCurrent(unsignedintad_value);floatCalculateVacuumDegree(unsignedintad_value);
u16CalculateDAOutData(floatat);floatCalculateSensitivity(u8mod,unsignedintDA_Data);
voidSystem_Init(void);floatCalculateDAOutVoltage(u16dat);floatMedianFilter(u8num,float*value_buf);
voidSampleInit(void);unsignedintCRC16_Calculate(unsignedchar*ptr,unsignedcharlen,unsignedintweight);
voidSerialProtocolSend(unsignedchar*SendData,unsignedcharLength,unsignedcharMode);
voidtransfer_command_lcd(intdata1);voidlcd_address(unsignedintpage,unsignedintcolumn);
voidtransfer_data_lcd(intdata1);voiddisplay_128x64(unsignedchar*dp);voidLCD_Init(void);
voidLCDPort_Init(void);voidsend_command_to_ROM(unsignedchardatu);voidclear_screen(void);
staticunsignedcharget_data_from_ROM();voidSCISendString(u8SCINo,s8*p);voidPLL_Init(void);
voiddisplay_graphic_16x16(unsignedintpage,unsignedintcolumn,unsignedchar*dp);voidPWM_Init(void);
voiddisplay_graphic_8x16(unsignedintpage,unsignedcharcolumn,unsignedchar*dp);voidPIT_Init(void);
voiddisplay_graphic_5x7(unsignedintpage,unsignedcharcolumn,unsignedchar*dp);voidGPIO_Init(void);
voidget_n_bytes_data_from_ROM(unsignedcharaddrHigh,unsignedcharaddrMid,unsignedcharaddrLow,unsignedchar*pBuff,unsignedcharDataLen);externfloatSensitivityNow;voidLED_Init(void);
voiddisplay_GB2312_string(unsignedchary,unsignedcharx,unsignedchar*text);voidDFlash_Init(void);
voiddisplay_string_5x7(unsignedchary,unsignedcharx,unsignedchar*text);
voidDisplayFloatVariable5x7(u8row,u8col,consts8*format,floatdat);u8SCIRcvNByte(u8SCINo,u8n,u8dat[]);
voidDisplayFloatVariable2312(u8row,u8col,consts8*format,floatdat);voidPWM_Set(u8ch,floatduty);
externunsignedcharbmp1[];externunsignedcharjiong1[];externunsignedcharlei1[];
externu8MeasureStep;externu16DA_OutData;externu8ErrorCode;externu8ActuationFlag;
externu8ActuationRecordFlag;externu16ActuationDAData;externu8ReleaseFlag;
externfloatActuationSensitivity[SAMPLE_TIMES];externfloatActuationSensFinal;
externu8ReleaseRecordFlag;externu16ReleaseDAData;externfloatReleaseSensFinal;
externfloatReleaseSensitivity[SAMPLE_TIMES];externu8MeasureCounter;
voidSCIInit(u8SCINo,u8sysclk,u32baud);voidSCISendByte(u8SCINo,u8dat);
voidSCISendNByte(u8SCINo,u8n,u8dat[]);u8SCIRcvByte(u8SCINo,u8*p);
externunsignedlongT_1MS_Counter;voidDFlash_EraseSector(unsignedshortintADDR16);
voidDFlash_Write4Word(unsignedshortintADDR16,unsignedshortintdat[]);
unsignedshortintDFlash_ReadWord(unsignedshortintADDR16);voidDelayUs(unsignedinti);
voidDelayMs(unsignedinti);unsignedintAD_Sample(unsignedcharchannel);
typedefstructCanFrame
{u32m_ID;u8m_IDE;u8m_RTR;u8m_data[8];u8m_dataLen;u8m_priority;}CANFrame;
externu8CANDataBuffer[8];externu8sendDataLength;externCANFramesendFrame,rcvFrame;
externu8CANSendErrorFlag;externu32CANSendErrorCounter;externu8CANRcvErrorFlag;
externu32CANRcvErrorCounter;externu8CANRcvDataUpdateFlag;voidCANInit(void);
externu32CANSendError1Counter;externu32CANSendError2Counter;voidCANDataInit(void);
externu32CANSendError3Counter;externu32CANSendError4Counter;voidAD_Init(void);
externu32CANRcvDataCounter;externu32CANSendDataCounter;
u8CANSendFrame(CANFrame*sendFrame);u8CANRcvFrame(CANFrame*receiveFrame);
u8CANFillFrame(CANFrame*frame,u32id,u8ide,u8rtr,u8*data,u8len,u8priority);
#endif。