本文来自我的163博客搬移
春节放假前到现在,设计了一款采集器,采集器的设计按照标准的MBUS协议设计,设计容量为最大可同时对100只水表的水量数据进行采集。
硬件设计:
原理图设计上采用自顶向下的分层电路图设计方法,分为5个电路子图,分别为单片机小系统部分、电源部分、MBUS协议部分、短路保护部分、通信部分。
1、单片机小系统部分的设计上将编程引脚的时钟和数据通过3X2的插头分隔开,因为时钟和数据是跟UART2的RXD和TXD是复用的,准备通过跳线来使用UART2,在程序正常运行的时候通过设置引脚来使用UART2,这就存在一个问题就是如果一上电程序就运行,然后设置了UART2引脚后,如果需要烧入程序,这个时候还能不能烧入程序,需要在软件调试的时候来验证,按理说默认是编程的时钟和数据脚,在没有重新设置的时候是可以用的。
2、电源设计上通过稳压器经外部输入的15V电压分隔出5V、12V、和3.3V,其中12V是MBUS协议要求的调制电压,3.3V通过磁珠分离出数字电源和模拟电源用于单片机电源,5V为备用。
3、MBUS协议部分的设计上使用了UART1的TXD和RXD引脚来控制MBUS数据的收发,这样设计的意图是在软件设计上可以直接使用串口来进行收发,简化软件的设计。另外还有三个控制功能,分别是控制下行数据的时候加载12V的调制电压,数据上行的时候用于控制调制电流的41欧姆电阻以及控制电容的充放电来重新建立接收数据电压参考点的控制脚。
关于动态平衡点的建立及数据的接收详解:在没有加载Mbus总线电压的时候,C401上存在冲击电压,与C401并联的大电阻阻碍了电容的放电,而二极管D401的单向导电性又阻止了电容与Mbus总线的导通,这样经过比较器比较后在1脚上输出低电压(注意这个时候会产生串口接收中断,但这个时候系统的状态不对,中断程序里面应该做相应的处理否则会出现死机的情况,见后续软件调试部分分析),再经过第二个比较器在7脚上输出低电压,可以发现LED灯D17发光。当加载了Mbus总线电压后,电容C401与总线电压间始终存在一个二极管D401的导通电压差0.6v,通过第一个比较器在1脚上输出高电压,即RxD引脚上为高电压,经过第二个比较器后7脚输出高电压,LED灯D17不发光。如果Mbus总线上串联有表具,这个时候总线上就有静态电流的消耗,消耗的静态电流跟表具的数量相关,这个时候总线上的电压跟电容C401上的电压差可肯就不是0.6V,作为参考的电容电压就不能真实的反应总线电压,因此当下行数据发送完成,切换到总线接收数据状态的时候,首先要对电容C401进行放电,然后再充电,重新建立0.6v的动态电压平衡比较点;当表具通过电流调制上传数据的时候,如果是1,则消耗的是静态电流,比较器1脚输出高电平,如果是0,则消耗的是静态电流+调制电流,通过设置tss721调制电流参数为15毫安,这个15毫安的电流通过一个设计好的41欧姆电阻,在总线上就会在静态电影基础上额外产生一个0.6v的压降,这时总线电压低于电容C401上的电压,从而比较器1脚输出低电压,RxD脚上识别出比特0,重复这个过程这样上传的数据就被单片机接收到了。如下图所示:
4、短路保护部分也有两个控制脚,一个是用于发现是否发生短路,另一个是如果短路故障解除了后用于控制电源,重新加载MBUS基础电压。
图中的P6KE43 TVS管用于保护MBUS接口,TVS管和被保护的接口并联,当接口上有瞬时干扰脉冲电压出现的时候,P6KE43 将MBUS接口电压钳位在43V,同时提供一个快速到地的放电通道,这就保护了MBUS接口上连接的社保。在实际的电路中,如图所示,在DC input的时候,有时由于供电环境的变化会带来一些瞬时脉冲。而要消除瞬时脉冲对器件损害的最好办法,就是将瞬时电流从敏感器件引到地,一般具体做法是将TVS在线路板上与被保护线路并联。这样,当瞬时电压超过电路正常工作电压后,TVS将发生雪崩击穿,从而提供给瞬时电流一个超低阻抗的通路,其结果是瞬时电流通过TVS被短路到GND,从而避开被保护器件,并且在电压恢复正常值之前使被保护回路一直保持截止电压。而当瞬时脉冲结束以后,TVS二极管再自动恢复至高阻状态,整个回路又回到正常电压状态。
短路保护原理解释:1、MBUS两端27v基础电压的控制:首先IRF530N为N沟道增强型MOS管,Vgs间电压>4V就可以使MOS管导通。通过MbusPowerCtrl引脚来控制PNP型三极管P502就可以控制Vgs间电压,从而控制MBus总线电压的加载。当MbusPowerCtrl输出高电平=>R511两端电压差为零=>P502截止=>R507无电流通过=>G、S端拉低到相同的电压MBUS-=>Vgs间电压为零=>MOS管截止=>BUS总线两端电压为零。当MbusPowerCtrl输出低电平=>R511两端电压差大于0.6V=>P502导通=>P502的集电极有大约DP3V3-0.6V的电压=>通过R507、R506分压在MOS管G、S两端产生大于10V的电压=>MOS管导通=>MBUS总线两端出现27v基础电压。2、短路保护的实现:正常MBUS通信下N502控制P503导通,MbusShort引脚在R514上采集到高电平,将MbusShort引脚配置为外部边沿触发中断。当MBUS总线上发生短路的时候,大的短路电流通过MOS管d、s端引起R501两端电压上升,通过R502、R503、R504的分压=>N501导通=>P501导通=>N501的基极电流增大=>N501和P501形成正反馈=>N501饱和导通,由于R505上最多有一个PN结的电压差=>N501将MOS管G、S两端电压拉低到MBUS-=>Vgs两端电压为零=>MOS管截止=>MBUS总线两端电压为零,起到短路保护。同时在短路发生时N502截止=>P503截止=>MbusShort引脚在R514上采集到低电平=>出现由高到低的电压边沿=>触发中断=>MCU进行短路处理,关闭MBUS总线电压,禁止通信,设置短路指示灯。
5、通信部分除了保留RS485通信口外,另外增加了一块max3232电压转换芯片,可以直接跟电脑串口连接,这样就可以通过电脑来控制采集器,方便通信和调试。
6、PCB的设计上采用双层板设计,使用玻璃纤维基材,板厚1.5mm(含正反面覆铜),表面采用铅锡的处理工艺,表面涂绿色油墨,按照一般加工工艺生成的PCB板。
目前电路调试通过,可以正常检测到单片机,能烧写程序,说明单片机小系统正确。在PCB板的焊接过程中发现一个PCB设计问题,就是有些圆孔焊盘的焊盘面小了点,在焊接的时候不好上焊锡,,类似于这样的过孔焊盘,由于内圈和外圈的差比较小,导致可以焊接的圆面积比较小,在后续设计中遇到类似的问题时要加大内圈和外圈的差值。
软件设计部分:
1、首先通过一个点灯程序能否运行正常,来验证单片机系统设置是否正确,系统设置包括:关闭看门狗功能、单片机各个模块的初始化、系统时钟配置等。
2、调试串口的通信功能,由于还不能直接跟PC串口连接,所以首先初始化单片机UART1,采用中断方式收发数据,波特率为9600,通过UART1不断向外发送数据,用示波器观察TXD引脚是否有数据发出。
看到示波器上的漂亮波形以及9600的波特率就表明UART1的发送功能调试成功。在调试串口的通信过程中遇到一个问题,就是设置串口通过轮询的方式收发数据的时候都比较正常,但是通过中断的方式通信的时候始终不能进入中断。最初怀疑是寄存器配置出错,通过单步调试和查询datasheet都没有发现问题,最后通过分析启动代码MKM33Z5.s发现对于串口UART0~UART1的中断程序是外部引用“ EXPORT SCI0_SCI1_IRQHandler [WEAK]”,而串口驱动中UART0~1的中断处理函数是UART0_UART1_isr,将驱动中的函数名修改为跟启动代码中函数名一致就可以了。
3、嵌入式系统的一个特点就是稳定可靠,为了在系统出现故障的情况下仍然能够从故障中恢复,采用了看门狗功能,这样当系统出现故障(比如软件跑飞、系统时钟故障等)时能够通过自动重启来恢复功能。
4、在软件功能设计上采用面向对象的设计思想,将数据和处理分开,因此设计了两个文件ComDataBase.c和DataDealWith.c分别用于存储数据和对数据的处理。
5、在调试的过程中发现每次打开MBus电源不久,MBus电源就会自动关闭,经过分析发现时看门狗的时间设置太短,导致没有及时喂狗而系统复位,调整了看门狗的时间就没有问题了。发现一个PCB上的问题,短路保护部分的R506和R507电阻没有连接在一起,估计是在从原理图生成网表的时候出的错。
6、通信部分的设计采用了状态机+定时器的设计方法,而状态机和定时器是通信类软件设计的基础。状态机制应用于数据收发和处理间状态的有序变化,定时器用于超时重发机制,以及各种异常处理。
通信部分的调试经历了几个大的问题:首先是采集器数据发送出去后没有收到返回数据,通过示波器观察到发送的波形,粗哟一看好像数据都正确发送出去,仿佛一下子找不到解决问题的方向了,经过几天的调试没有进展,后来仔细分析了发送的波形数据,发现数据的最后两个字节始终发送有错误,估计是软件的数据发送部分出了问题,修改了数据的发送部分,再分析发送的数据波形,发现波形正确,表具有返回数据。发送数据没有应答的问题解决了, 紧接着接收数据的问题又来了,接收的数据始终不对,而且接收数据的时候会莫名其妙的死机,用单步跟踪调试发现时死在Uart1的中断程序里面,即不停的收到接收数据的中断,CPU一直再处理中断,根本没有时间响应其他的事件,通过进行一次读数据寄存器操作清除中断标识后这个问题解决了,但需要分析引起这种错误中断的根本原因。经过仔细分析Mbus数据接收部分的电路设计,前面第3点所述,是在没有加载12v调制电压的情况下,比较器1脚输出低电平,这个低电平就会引起串口中断,但这个时候的数据是错误的,应为在中断处理程序里面采用了状态机,所以在状态不对的时候就没有去读数据寄存器,中断标志就没有清除,因此导致不停的进入中断处理,通过一次读寄存器操作清除了中断,解决了这个问题。 再一个调试了很久的问题就是,接收的数据第一次是对的,再次重复这个操作的时候就不对了,通过单步调试发现第二次接收到的数据多了一个0x68头,怀疑是不是有残存的接收数据影响,通过查阅芯片数据手册串口部分的资料,发现通过设置寄存器可以清空接收fifo中的数据,然后再程序中每次发送完命令,切换到接收数据状态的时候就清空接收fifo,接收到的数据就在也没有出错了。
通过这次调试再一次深刻体会到了嵌入式产品综合分析能力的重要性,想起以前出去面试,别人问自己最擅长那一部分,现在想起来那些人问的很有问题,如果仅仅是找一个做莫一部分的人,编写一些局部代码,那他擅长什么并不重要了,而如果你先找一个在嵌入式方面有能力的人,应该是看他的系统分析能力,持续的学习能力,对嵌入式开发的认识程度,以及嵌入式产品开发经历等。
7、RS485的调试,有了前面的基础,RS485的调试就比较顺利,没有遇到什么大的问题。需要注意的是uart1和uart3的时钟用的是系统时钟,因此在用48M,2:1:1的时钟模式时候计算波特率时参数应该是48M。
8、在采集器中添加兼容广安水表的功能,由于我们水表存在两种协议,因此在调试的时候经常要切换采集器,比较麻烦,因此在新的采集器中对广安水表做了一个透传的功能,这个时候uart0、uart1串口使用的是2400波特率、偶校验、9bit数据的配置模式。在调试这个功能的时候主要是在串口的配置上出错,花费了一点时间来调试,通过抓取一个正确的偶校验数据和错误的数据波形相比较,就发现了问题的原因。最初将串口的偶校验功能打开,但数据位选择的是8bit,也就是开始位+8bit数据+1bit停止位=10bit,但由于选择了偶校验就应该是开始位+8bit数据+1bit偶校验位+1bit停止位=11bit,通过示波器观察可以发现串口配置错误选择8比特的时候始终差一位停止位,因此数据格式不对。
只比较第一个数据就发现问题:数据的开头为0x68,可以看到添加了偶数个1,但没有停止位
这个是正确的0x68,一共11比特数据,增加了偶校验。9、关于采集器最大容量的定义:由于数据的接收是采样电流调制,通过在41欧电阻上产生压降,触发比较器输出来进行数据的接收,最大容量由能使比较值正常工作的最小输入电压决定,根据设计比较器两个输入端有0.6v的电压差,总的静态电流在41欧电阻上的消耗电压应小于12v-0.6v=11.4v,这是比较器能正确识别出电流调制数据的临界点,当静态电流消耗大于这个临界点的时候,在电流调制的时候比较器的同相端得到的是一个负的电压,而反相端由于二极管的限制始终是一个正的电压,比较器输出总是0,这个时候就不能正确的识别出数据了。
这是一个工作在临界点附近的波形,可以看到在41欧电阻上消耗了将近12v的电压,这个时候比较器就很有可能不能正确识别出数据。提供采集器的容量可以从提高调制电压如12v提高到15v和降低载波电压如27v降低到20v等方面考虑,但载波电压的降低应不低于表具边使表具上tss721能正常工作的最低电压,要考虑到mbus总线上的电压降。10、在看门狗的功能上遇到一个问题,就是喂狗不成功,总是在一段设定的时间里面导致芯片复位,最后解决的办法是在喂狗函数后面加了一点延时,就好了,不知道是什么原因,在芯片手册上也没有相关的说明,这个得跟原厂技术支持交流一下了。
11、关于总功率的计算:假设一个采集器上可以接200只水表,每个表的静态电流为2mA,则抄表的时候总的静态电流为400mA=0.4A,在等待表具电流调制期间的静态总线电压为27V+12V,静态总功率为39*0.4=15.6W;在抄表的时候只有一只表能上传数据,抄表时候的电流增加15mA,总功率为在静态总功率的基础上增加0.015*39=0.585w,即抄表时候的总功率为:15.6+0.585=16.185W。当然可以通过在表具上进行一些低功耗的设计,可以使表具静态电流小于1.5mA,可以节约功耗。
12、用这个板子做了一个用定时器控制步进电机,可以选择步进电机速率的实验,在用AK100仿真器烧写程序的时候遇到提示要解锁的情况,或者提示复位状态不对,咨询技术支持人员,得到的答复是给单片机供电不稳定导致的;根据这一线索检查板子,发现3.3v跟地导通了,3.3v上连接了许多的电阻、电容、IC器件,到底是哪个器件出了问题,花了好几个小时才将问题找到。首先是在PCB图上将3.3v相关的器件点亮,然后分析可能出现问题的元件,一个一个取下来,用万用表测试看是否任然导通,取了许多电阻电容、IC芯片,问题依旧,最后将一个max3232串口电压转换芯片取掉后3.3v跟地就不导通了,后面仔细分析了一下,一般容易损坏的大多是接口芯片,说要遇到电源和地短路的情况要先检查接口之类的芯片。还有就是用外部电池给芯片供电的时候,在电池电压不足的时候,也容易引起不能烧写程序,并提示芯片锁定。