1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,基本,8,位单片机的软件平台设计方案,(3),太阳能热水器软件平台设计,平台目的,建立一个通用的、规范的、高效的、易读的、流程清晰的软件平台,通用性:针对太阳能热水器具有一定的通用性,太阳能热水器在此架构上修改即可,规范性:文件定义、变量定义、函数定义规范化,高效性:程序流程清晰,方便修改,易读性:大量注释保证程序的可读性好,模块化:大量程序模块化,方便其它程序调用,内容,一个标准程序,可以完成规格书所规定的热水器的基本功能。包含所有注释和说明。,编程规范:一套完整的编程规范,包括文件定义、变量定义、函数
2、定义的规范化,文件调用关系:各文件间的调用关系图与全局变量的数据流图,程序流程图:包括程序总流程图及各关键子函数流程图,与程序一一对应。,基本软件架构,外部中断,主循环,时间中断,*三者是并行的关系*本质上单片机是顺序执行,只有在中断发生的时候才会进入中断执行,中断内容执行完毕后返回到主循环中,*由主循环程序处理大部分的流程,中断内的内容要尽量少,时间中断的处理,要求,代码少,效率高,除了必须使用的扫描等功能,其他和时间有关的只是设置变量标志位,并不做任何处理,所有的处理均放在主程序中处理,必要时嵌入汇编实现,实现时注意优化代码,编译后使用反汇编程序来查看对应的汇编代码,注意有些芯片计时是不准
3、确的,所以要有定时检测方法(可通过定时控制,IO,口输出之后通过示波器检测),举例:,SolarWaterHeatermain.c,外部中断的处理,外部中断要考虑到干扰的影响,一般会有滤波措施,必要时嵌入汇编实现,软件工程中的分层设计,硬件平台,硬件抽象层,驱动程序,应用程序,操作系统,基本软件平台,分层设计思想,硬件平台,硬件抽象层,驱动程序,主程序,负责主要结构体和变量的定义,主要功能函数的流程,随硬件更改而更改,不随硬件更改而更改,函数及变量定义,改变思路,一个源文件解决所有:可以,但可移植性和可读性不好。可以说把,c,程序做成一个文件的还停留在汇编程序设计的思路上,他只是换了种语言工具
4、而已,而非改变了设计思路。,以后的系统会越来越复杂,使用成熟的代码等于站在巨人的肩膀上,从系统角度考虑问题:没有最好的,只有最适合的,(,不要迷信规格书,),,事实上很多系统工程师也不知道怎么做才是最好的,软件只是系统的一部分,但是如同人的大脑,是系统的灵魂所在,尤其在涉及到控制算法的时候,模块,(,文件,),划分,头文件:被其他文件包含的文件,包括结构体定义和常量定义文件,主文件:,main.c,,,负责所有文件间的调度,全局变量文件:,所有的全局变量及其初始化函数,尽量少的使用全局变量,硬件文件:,hardware.c,与硬件有关的文件,驱动文件,:,与硬件有关同时含有滤波或时序等功能的文
5、件,流程文件:与硬件无关与流程有关的文件,其他文件:算法文件或通用函数文件,模块,(,文件,),划分:头文件,.h,文件只包含宏定义和函数声明,不包含变量的定义,可以被任何,.c,文件包含,Io_define.h,:,IO,口定义头文件,,文件内全部使用宏定义定义,IO,口及与,IO,相关的操作等内容。会被驱动文件和主文件调用。这些定义也是和硬件息息相关的,更改,MCU,的时候需要全部改写此文件,MainConst.h,:,常数定义文件,,包括程序中用到的常量和枚举类型定义,MainStruct.h,:,结构定义文件,,包含可能用到的所有结构定义,不包含变量,模块,(,文件,),划分:主文件,
6、Main.c,main.h,:,主文件,,程序的入口(注意并不一定是芯片复位后的入口),负责所有文件间的调度,Hardware.c,hardware.h,:,硬件文件,,负责与硬件相关的函数定义,如,MCU,的特殊寄存器定义模块,(,f_InitSFR,),,,AD,检测函数,f_CheckADVaule,(),,,PWM,输出函数等。这些函数都是和硬件息息相关的,更改,MCU,的时候需要全部改写此文件,GlobalVar.c,GlobalVar.h,:,全局变量文件,,,GlobalVar.c,中定义所有的全局变量及其初始化函数,,GlobalVar.h,包括对全局变量的声明,使用全局变量的
7、文件中包含,GlobalVar.h,即可,通用函数,CommFunc.c,CommFunc.h,:与硬件无关的,通用函数文件,,如,BCD,码转,16,进制码等函数,使用任何芯片此文件中的内容均不用修改,模块,(,文件,),划分:驱动文件,与硬件有关或含有滤波功能或含有时序等功能的文件,称为,驱动文件。,不负责与流程有关的内容。与硬件的接口通过,hardware.c,或,io_define.h,来实现。如:,RTC_PCF8563.c,,,RTC_PCF8563.h,:时钟芯片,8563,驱动,和时序有关,主程序只要调用此驱动文件的各个函数即可实现对时钟芯片的读写操作,CheckWaterPo
8、s.c,CheckWaterPos.h,:脉冲宽度或个数检测模块,如水流量脉冲检测,水位检测,一般会涉及到滤波算法,ChkADKey.C,ChkScanKey.c,ChkKey.h,:按键检测模块,与算法相关,需要滤波,由于可以使用多种方式检测按键,故需要通过文件名将其分开。但文件里的函数名称是一样的,头文件也是一样的,这样在更改按键检测方式的时候只要更换编译的文件即可。,ChkAverageTmp.c,,,ChkMiddleTmp.c,,,ChkTmp.h,:温度检测模块,一般涉及到滤波算法,同检测按键一样,可以使用多种滤波算法检测温度,故需要通过文件名将其分开。,UART_Drv.c,UA
9、RT_Drv.h,:,UART,通讯模块,负责,UART,通信的故障检测,冲突检测等功能,模块,(,文件,),划分:流程文件,与功能要求有关的文件,称为,流程文件。,主要负责流程和逻辑相关的操作,做到与硬件无关。所有与硬件有关的输入输出都是通过驱动文件中的函数或对全局变量的操作来实现的,流程文件与驱动文件的接口也主要由,Display.c,DealKey.c,main.c,等固定的接口文件来完成,其他流程文件尽量做到与驱动文件无关。,Display.c,Display.h,:显示文件,负责获取显示缓冲和显示输出,DealKey.c,DealKey.h,:按键处理文件,负责处理按键功能,其他和流
10、程有关的模块,如,UpWater.c,UpWater.h,Elec_Heat.c,Elec_Heat.h,模块,(,文件,),划分:,其他,通用函数,CommFunc.c,CommFunc.h,:与硬件无关的通用函数文件,如,BCD,码转,16,进制码等函数,使用任何芯片此文件中的内容均不用修改,复杂的控制算法,一般会涉及到算法效率及控制性能,单独使用一个文件,称为,算法文件。,要做到与硬件无关。,主芯片,硬件包含文件,(,io_define.h,文件,),设备驱动文件,LCD,驱动,流程相关文件,设备驱动文件,按键检测,设备驱动文件,蜂鸣器驱动,主程序,(,main.c,),(,对下面的函数
11、进行调用,),与硬件相关,内容,hardware.c,驱动文件通过,io_define.h,与,MCU,交互,显示相关文件,Display.c,按键处理相关文件,DealKey.c,其他与输入,/,输出,无关的文件,通用函数文件,算法文件,包括滤波、控制算法,包含文件,MainStruct.h,MainConst.h,GlobalVar.h,io_define.h,全局变量,GlobalVar.c,与输入输出有关的内容通过驱动文件控制,MCU,与输入输出均无关的文件,硬件抽象层的实现,Hardware.c,文件:负责整个,MCU,的初始化,,PWM,输出,检测,AD,等函数的实现,举例:,So
12、larWaterHeaterHardware.c,io_define.h,文件:负责驱动文件与硬件的接口,举例:与,ST_MCU_EEPRom,的接口,ST_MCU_EEPRom.c,目的:当更换芯片时,驱动程序的内容完全不动,只需更改,io_define.h,里的内容即可,驱动文件组成,RTC_PCF8563.c,,记忆芯片驱动程序为例,两个头文件,一个实现文件,RTC_PCF8563.c,RTC_PCF8563.h,Io_define.h,驱动文件基本功能,RTC_PCF8563.c,,时钟驱动程序为例,包含所有对,RTC,写和读操作的时序,外部调用时只需将其当作黑匣子,读写后均有读写是否
13、正确返回值,Io_define,(,硬件接口文件,包含,IO,口的实际硬件定义,更改,MCU,时修改此文件,),包括,RTC_PCF8563,.h(,头文件,外部调用时的函数声明,),,主文件中包含此文件,与,RTC_PCF8563.c,相对应,RTC_PCF8563.c,(,驱动实现文件,所有函数的实现,),,确定后不需修改,其它硬件驱动文件与之类似,主程序流程,见,main.c,main.c,中只保留简单的几个函数,main(),timer_interrupt,();,在,main.c,中调用各个模块的函数,主程序流程图,包括上电初始化部分和主循环部分,初始化部分上电后只执行一次,之后一直
14、在主循环部分循环,流程图,主程序流程图,1.jpg,流程图,主程序流程图,2.jpg,太阳能热水器基本概念,一、系统组成及工作方式:,由集热器,承压水箱、集热循环管路,控制系统组成。利用,温控仪,根据集热器管中温度和水位控制上水阀和电加热是否开启,从而满足用户的用水需求。,二、重要元器件,1,、超导热真空集热管。,2,、蓝金刚全承压搪瓷内胆水箱。,3,、,采用智能控制技术,全自动运行。,4,、结垢与防冻设计,太阳能热水器基本概念,三、控制器主要功能,1,、功能齐全:满足尽可能多的太阳能热水器(多种系统模式选择),2,、智能控制技术:可选择全自动模式运行,既节能又舒适,3,、安全性高:各种报警功
15、能齐全,能检测到各个元器件是否工作正常,4,、保护功能齐全:用户误操作或检测错误均不会造成系统的损坏,5,、界面友好,方便操作:显示和保护一目了然,参数设置简单易学,编写软件工作进程,、熟悉规格书(三天):这段时间请不要开始编写程序(事倍功半),、根据规格书提出疑问:几乎所有的规格书都有互相矛盾或逻辑不清晰的地方,有疑问则要与系统工程师问清楚,可能会扩展的地方也要问清楚,、根据规格书列出输入和输出负载情况,电加热、上水阀、伴热带、增压泵、循环泵、显示、蜂鸣器,时钟芯片、按键、水温、水位、记忆芯片、,编写软件工作进程(续),、根据规格书判断哪些是保护功能,即优先执行的功能(安全第一),哪些是正常
16、运行时的功能,防炸管、防干烧、加热管保护、水箱防冻、管道防冻,定时上水、定时加热、手动上水、手动加热、全天候上水、全天候电热、温控补水、恒定水位、恒定水温,、可选项确定:是否有时钟芯片,是否有记忆芯片,是否有管道防冻,定义结构,tOption,,程序要根据此结构来判断是否存在此功能,编写软件工作进程(续),6,、排查有关联的功能模块和无关联的功能模块,无关联:自动增压、管道防冻、断电记忆、开机自检等,有关联:温控补水、手动加热、加热管保护、低水压保护等,无关联的可以单独控制,好比控制理论中的单输入单输出系统,有关联的需考虑各种可能性,好比控制理论中的多输入多输出系统,复杂性上升,编程总体原则,
17、尽量少使用全局变量,多定义结构体表示某一事件的组合,模块划分要清晰,各模块耦合尽量少,检测输入(温度,水位)需要滤波,增强程序的鲁棒性,需要报故障前一定要多检测几次,防止误报,增强程序的鲁棒性,中断程序内容尽量少,尽量用宏代替数字,增强程序的可读性,太阳能热水器功能模块划分,基本模块:主程序,main.c,,硬件相关程序,hardware.c,,全局变量,GlobalVar.c,基本功能:温度检测,ChkTmp.c,、显示模块,display.c,、按键检测模块,CheckKey.c,、按键处理模块,DealKey.c,带电加热功能:漏电检测模块,CheckElecLeak.c,带时钟芯片:时
18、钟检测模块,RTC_,RTC_PCF8563.c,带自动上水功能:水位检测模块,CheckWaterPos.c,带蜂鸣器:蜂鸣器驱动模块,BuzBeep.c,带记忆功能:记忆芯片模块,ST_MCU_EEPRom.c,带液晶驱动:液晶驱动模块,HL6024_Drv.c,流程文件:防冻模块,Defreeze.c,保存设定参数模块,SetSavePara.c,,上水模块,UpWater.c,,电加热模块,ElecHeat.c,主要流程控制模块(难点),上水控制:根据用户设置和检测到的温度、水位判断是否需要上水,同时要考虑到各种保护,电加热控制:根据用户设置和检测到的温度、水位判断是否需要启动电加热,
19、同时要考虑到各种保护,防冻控制:与电加热和上水有关联动作,状态保存:保存用户设置的数据,保存的数据多,且与按键、显示、,EEPROM,,,RTC,均有关联,全局变量 定义,与大部分流程有关的才定义全局变量,否则尽量使用局部变量或函数调用的方式。在定义前首先问问自己这个变量是不是一定要定义为全局变量,以下为根据,G04,规格书定义的太阳能热水器的全局变量(不同规格书定义的全局变量可能会略有不同),option_def,tOption,;/*,可选功能*,/,relay_def,tRelay,;/*,继电器输出*,/,fault_def,tFault,;/*,故障变量*,/,upwater_def
20、tUpWater,;/*,上水变量*,/,elecheat_def,tElecHeat,;/*,电加热变量*,/,defreeze_def,tDefreeze,;/*,防冻变量*,/,hour_def,tCurTime,;/*,当前时间*,/,enum,enumSetState,nSetState,;/*,当前设置状态*,/,unsigned char,nSetValue,;/*,正在设定的参数值*,/,savepara_def,tSetPara,;/*,设定参数*,/,全局变量,tOption,typedef,union,/*,可选功能的结构定义,*/,unsigned,int,byte;
21、struct,unsigned char,bEnergySaving,:1;/*,节能,*/,unsigned char,bAddPressurePump,:1;,/*,增压泵,*/,unsigned char,bSilence,:1;,/*,静音,*/,unsigned char,bDefreeze,:1;,/*,防冻,*/,unsigned char bLoopPumpDefreeze:1;/*,循环泵防冻,*/,bit;,option_def,;,值为,1,的时候表示此选项有效,如,tOption.bit.,bSilence,=1,表示有静音功能,全局变量,tRelay,typedef
22、 union,/*继电器输出的结构定义*/,unsigned char byte;,struct,unsigned char bUpWaterValve:1;/*上水阀*/,unsigned char bPump:1;,/*增压泵*/,unsigned char bElecHeat:1;,/*电加热*/,unsigned char bLoopPump:1;/*循环泵(电热带)*/,bit;,relay_def,;,由流程文件,(,UpWater.c,),来更改,tRelay,的值,主程序,(,main.c,),将根据,tRelay,的值来判断打开或关闭继电器输出。关闭全部继电器可使用,tRel
23、ay.byte,=0;,全局变量,tFault,typedef,union,/*,故障的结构定义,*/,unsigned char byte;,struct,unsigned char,bWaterSSR,:1;/*,水温传感器故障,*/,unsigned char,bWaterPosSSR,:1;/*,水位传感器故障,*/,unsigned char,bSystemErr,:1;/*,系统故障,*/,unsigned char,bElecLeak,:1;/*,系统漏电,*/,unsigned char,bElecLeakCircuit,:1;/*,漏电电路,*/,unsigned char,
24、bEEPErr,:1;/*,记忆芯片故障,*/,unsigned char,bRTCError,:1;/*,时钟芯片故障,*/,bit;,fault_def,;,定义可能出现的全部故障,从上到下故障代码依次为,E1,E2,清除全部故障可通过,tFault.byte,=0;,实现,全局变量,:,参数设定变量(,tSetPara,),需要保存到记忆芯片中的参数,具体见,mainStruct.h,定义,共包含,20,个,byte,包括两个引导码和一个校验码,当从,EEPROM,读出的时候要同时判断引导码和校验和是否正确,只有全部正确才认为是正确,与之对应的是,SetSavePara.c,中的,TBL
25、PARA_DEFAULT,:缺省参数,TBL_PARA_RANGE,:各参数的设定范围,注意,tSetUpWaterTimer1,是,hourmin_def,格式的,即包含两个,byte,全局变量,(,上水变量,tUpWater,),上水,控制变量,,程序主要修改此,变量,的值,并根据此变量的各个参数来,判断当前上水状态及是否打开上水阀,bNeedUpWater:,需要上水,当需要上水时将此值置,1,nTargetWaterPos:,目标水位,nCurWaterPos:,当前水位,(,通过检测水位传感器得到,),nStartWaterPos,;:,上水时的起始水位,nUpWaterReaso
26、n:,上水原因,取值见下页,bAntiBombProtect,:,防炸管保护,有保护时不能上水,bLowPessureProtect,:,低水压保护,有保护时间断上水,bRunning,:,正在上水,tRunTime:,上水运行,(,停止,),时间,nArriveTargetTime,;,到达设定水位时间,(,单位,:,秒,),,到达设定水位后,10,秒停止上水使用,nNoWaterTm,:无水时间,(,单位,:,秒,),,判断缺水上水时使用,上水原因取值,enum,enumUpWaterReason,/*,上水原因,*/,ALL_DAY_TIMER,/*,全天候定时,*/,TIMER_UPW
27、ATER,/*,定时上水,*/,TEMPERATURE_CONTROL,/*,温控补水,*/,MANNUAL_UPWATER,/*,手动,*/,WATER_LOSE,/*,缺水上水,*/,ELEC_HEAT/*,电加热,上,水*/,;,全部使用大写字母,使用有用的名称代替,0,1,2,3,4,5,全局变量,(,电加热变量,tElecHeat,),电加热,控制变量,程序将根据此变量的值来判断是否开启电加热继电器,bNeedElecHeat:,需要电加热,当需要电加热时将此值置,1,nTargetTmp:,目标温度,nCurTmp:,当前水温,(,通过检测温度传感器得到,ChkTmp.c,),in
28、t,nStartTmp,:,起始温度,nElecHeatReason:,电加热原因,取值见下页,bHeaterProtect,:,加热管,保护,有保护时需要间断开启电加热,bNoWaterProtect,:,防干烧保护,有保护时不能运行,bRunning,:,电加热正在运行,tRunTime:,电加热运行时间,电加热原因取值,/*,电加热原因,*/,enum,enumElecHeatReason,ALL_DAY_TIMER,/*,全天候定时,*/,DEFREEZE,/*,防冻控制,*/,MANNUAL,/*,手动,*/,;,全局变量,(,防冻变量,tDefreeze,),防冻控制变量,程序将根
29、据此变量的值来判断是否开启防冻继电器,bNeedDefreeze,:,需要防冻,当开启防冻时时将此值置,1,bRunning,:,防冻正在运行,tRunTime,:,防冻运行,(,停止,),时间,防冻与电加热和上水有关联,全局变量,(,当前时间,tCurTime,),每,500ms,读一次时钟芯片,取得,tCurTime,的值,typedef,struct,/*,小时,分钟,秒结构*,/,unsigned charhour;,unsigned charminute;,unsigned charsecond;,hour_def,;,全局变量,(,当前设置状态nSetState,),NO_SET,
30、未设置,SET_WATER_TEMP,:,设置水温,SET_WATER_POS,:,设置水位,SET_RTC_HOUR,:,设置实时时钟小时,SET_RTC_MIN,:,设置实时时钟分钟,SET_CYCLE_PUMP_TIME,:,设置循环泵时间,SET_ELEC_STRIP_TIME,:,设置电热带时间,SET_TIMER_UP_WATER_1_HOUR,:,设置定时上水时间,1,小时,SET_TIMER_UP_WATER_1_MIN,:,设置定时上水时间,1,分钟,SET_TIMER_UP_WATER_2_HOUR,:,设置定时上水时间,2,小时,SET_TIMER_UP_WATER_
31、2_MIN,:,设置定时上水时间,2,分钟,SET_TIMER_ELEC_HEAT_1_HOUR:,设置定时加热时间,1,小时,SET_TIMER_ELEC_HEAT_1_MIN,:,设置定时加热时间,1,分钟,SET_TIMER_ELEC_HEAT_1_TEMP:,设置定时加热温度,1,SET_TIMER_ELEC_HEAT_2_HOUR:,设置定时加热时间,2,小时,SET_TIMER_ELEC_HEAT_2_MIN,:,设置定时加热时间,2,分钟,SET_TIMER_ELEC_HEAT_2_TEMP:,设置定时加热温度,2,全局变量,(,正在设定的参数值 nSetValue,),nSet
32、State,的取值为枚举型,,NO_SET,表示当前不是设置状态,其他表示当前为设置状态,根据,tSetPara,的值和,nSetState,的值得到,保存时将,nSetValue,的值保存到,tSetPara,中去,显示时也会用到此值,平台主要文件(头文件),常量文件:,MainConst.h,,包括各种常量定义,结构体定义文件:,MainStruct.h,,定义太阳能热水器中定义的各个结构体,Io_define.h,:,IO,口定义头文件,Table_temperature.h,温度阻值表:,AD,值与温度对应关系表,其他与各驱动文件和流程文件对应的,.h,,如,hardware.h,Bu
33、zBeep.h,等,平台主要文件(主文件),Main.c,main.h,:,主文件,,程序的入口(注意并不一定是芯片复位后的入口),负责所有文件间的调度,Hardware.c,hardware.h,:,硬件文件,,负责与硬件相关的函数定义,如使用,NOP,的延时函数,,f_NOPDelay,(),,,MCU,的特殊寄存器定义模块,(,f_InitSFR,),,,AD,检测函数,f_CheckADVaule,(),等。这些函数都是和硬件息息相关的,GlobalVar.c,GlobalVar.h,:,全局变量文件,,负责整个系统的全局变量,,GlobalVar.c,中定义所有的全局变量及其初始化函
34、数,,GlobalVar.h,包括对全局变量的声明,使用全局变量的文件中包含,GlobalVar.h,即可,平台主要文件(流程文件),特点:包含全局变量,与硬件无关,Display.c,Display.h,:显示文件,负责获取显示缓冲和显示输出,DealKey.c,DealKey.h,:按键处理文件,负责处理按键功能,UpWater.c,UpWater.h,:负责和上水有关的功能函数定义,Defreeze.c,Defreeze.h,:防冻模块,负责和防冻有关的功能函数定义,ElecHeat.c,ElecHeat.h,:加热模块,负责和电加热有关的功能函数定义,SetSavePara.c,Set
35、SavePara.h,:设置参数程序,负责与保存设置参数有关的函数定义,平台文件划分(输入驱动文件),特点:与输入,IO,口有关,包含,io_define.h,(,也可以与硬件无关,),,不包含全局变量,温度检测文件:,Table_temperature.h,和,ChkTmp.c,.h,,负责根据,AD,值检测温度及完成滤波功能,返回温度值及传感器是否故障,水位检测模块:,CheckWaterPos_Int.c,负责检测水位,返回当前水位及传感器是否故障,按键检测文件:,ChkKey.c,,负责检测按键,漏电检测模块:,CheckElecLeak.c,,负责检测是否漏电,平台文件划分(输出驱动
36、文件),特点:与输入,IO,口有关,包含,io_define.h,,不包含全局变量,蜂鸣器驱动文件:,BuzBeep.c,.h,,负责驱动蜂鸣器鸣叫,包括,n,短声、,n,长声等,时钟芯片驱动:,RTC_PCF8563.c,.h,负责驱动,8563,时钟芯片,EEPROM,驱动:,ST_MCU_EEPRom.c,.h,,负责驱动,ST,的内部,EEPRom,Io_define.h,各文件间的包含关系,Main.c,Hardware.c,RTC_,PCF8563.c,BuzBeep.c,ST_MCU_,EEPRom.c,MainConst.h,STM8S105K.h,ChkKey.c,ChkTm
37、p.c,Table_,Temperature.h,Check,WaterPos.c,Check,ElecLeak.c,Display.c,DealKey.c,UpWater.c,Defreeze.c,ElecHeat.c,GlobalVar.c,SetSave,Para.c,Io_define.h,hardware.h,GlobalVar.h,hardware.h,GlobalVar.h,MainStruct.h,MainConst.h,GlobalVar.h,hardware.h,hardware.h,mainstruct.h,包含关系说明,所有的驱动程序只包含一个与硬件有关的,io_def
38、ine.h,文件,更改硬件时只更改此,.h,文件即可,MainStruct.h,和,MainConst.h,文件可以由任何文件包含,不过为提高可移植性,驱动文件一般不包含,MainConst.h,文件,GlobalVar.h,被流程文件包含,被流程文件包含,不被驱动文件包含,Io_define.h,负责普通,IO,口的定义,被驱动文件包含,尽量不被流程文件包含,Display.c,DealKey.c,SetSavePara.c,为流程文件与驱动文件的接口,可能会包含,Io_define.h,各文件间的调用关系,Main.c,Hardware.c,RTC_,PCF8563.c,BuzBeep.c
39、ST_MCU_,EEPRom.c,ChkKey.c,ChkTmp.c,Check,WaterPos.c,Check,ElecLeak.c,Display.c,DealKey.c,UpWater.c,Defreeze.c,ElecHeat.c,GlobalVar.c,SetSave,Para.c,595_Drv.c,调用关系说明,主文件可以调用所有模块的函数,Hardware.c,负责与硬件相关的操作,不调用其他文件的函数,显示模块不调用任何流程中的文件,流程文件不调用,hardware.c,中的函数,尽量不调用驱动程序中的函数,Display.c,DealKey.c,SetSavePara.
40、c,为流程文件与驱动文件的接口,既可能调用流程文件的函数,也可能调用驱动文件的函数,其他流程文件不调用驱动程序中的函数,流程文件各文件间可以互相调用,驱动文件不调用,GlobalVar.c,的函数,也不使用全局变量,所有驱动程序间没有任何的联系,但驱动程序可能会调用,Hardware.c,中的函数,主要是调用两个函数:,f_MCU_FeedDog,(),和,f_NOPDelay,(),延时函数,各文件间的数据流图,Main.c,tCurTime,RTC_,PCF8563.c,ChkTmp.c,Check,WaterPos.c,Check,ElecLeak.c,Display.c,(,使用全部全
41、局变量,但不对全局变量更改,),DealKey.c,UpWater.c,Defreeze.c,ElecHeat.c,tOption,SetSave,Para.c,tSetPara,nSetState,nSetValue,tFault,tRelay,tUpWater,tElecHeat,tDefreeze,数据流说明,Hardware.c,BuzBeep.c,CheckKey.c,等驱动文件不对任何全局变量有影响,其他驱动文件,(,ChkTmp.c,ChkWaterPos.c,),对全局变量的影响都是通过函数的返回值实现的,驱动文件本身不直接改写全局变量值,Display.c,只读取全局变量,不
42、改变全局变量的值,流程文件改写大部分全局变量,DealKey.c,调用流程文件的函数来设置全局变量,其本身只读取全局变量,SetSavePara.c,文件只改写,tSetPara,变量,UpWater.c,改写,tUpWater,变量和,tRelay,变量,ElecHeat.c,改写,tElecHeat,变量和,tRelay,变量,Defreeze.c,改写,tDefreeze,变量和,tRelay,变量,划分流程模块原则之一:每个模块只负责一种功能,且每个模块基本只改写一组全局变量,模块说明:硬,件模块,(,hardware.c,.h),功能:硬件实现文件,实现和硬件有关的一些功能,主要包括
43、延时函数,喂狗程序,,初始化MCU基本设置,,AD,检测函数,,PWM,输出等,注意事项:,AD,检测注意延时,确保每次检测正确。,ST,芯片每个循环都对,IO,口的输入输出进行设置,注意中断优先级,断电检测中断最优先,外部中断注意设置下降沿中断还是低电平中断,以,f_MCU,_,做为函数的名称开头,硬件模块函数,(,Hardware.c,),主要函数:,f_NOPDelay,(),延时函数,使用NOP循环,f_MCU_FeedDog,(),清空看门狗,f_MCU_InitSfr,()初始化MCU基本设置,包括时钟、外部中断设置等,f_MCU_ChkJumper,(),检测拨码开关(跳线)值,
44、f_MCU_ChkADValue,()检测,AD,值,蜂鸣器驱动,(,BuzBeep,.c,;.h),功能:负责控制蜂鸣器是否鸣叫以及鸣叫时间,在需要鸣叫的时候只需调用此模块中的,f_Beep,函数即可,(,外部无需知道是如何实现鸣叫功能的,),。,包括鸣叫,1,2,3,短声,,1,2,3,长声等。,注意事项:,与硬件的接口通过,io_define.h,完成,尽量不要使用中断来驱动蜂鸣器,BuzBeep.h,中,使用宏定义短声和长声的时间,需要其他鸣叫功能则更新此驱动程序,蜂鸣器主要,函数,(,BuzBeep.c,),主要函数:,f_InitBuzPara,(),初始化蜂鸣器参数,(,可省略,
45、),f_IncBuzTm,(),增加蜂鸣器运行时间,每,10ms,调用,1,次,f_Beep,(),蜂鸣器开始鸣叫,输 入,:i_BuzState(1,为,1,短声,2,为,1,长声,3,为两短声,4,为两长声,5,为三短声,6,为三长声,7,为四短声,8,为四长声,其它为不鸣叫,注意,129,和,130,131,132,133,134,为内部变量不能使用,f_StopBeep,(),停止蜂鸣器鸣叫,f_OutBuz,(),输出蜂鸣器信号到芯片口,在主循环或毫秒级时间中断中调用,EEPRom,驱动,(,ST_MCU_EEPRom.c,),功能:用来驱动,ST MCU,自带的,EEPRom,,通
46、过此驱动程序可以从,EEPROM,中读出数据或向,EEPROM,中写入数据,同时可以检测,EEPROM,是否故障。,注意事项:,与硬件的接口通过,io_define.h,完成,MAX_READ_WRITE_EEPROM_NUM,为,故障判断次数,当连续写入(读出)错误超过此值时认为,EEPROM,故障,因,ST,自身问题,连续写入数据可能会导致程序不进中断,因此建议尽可能少向,EEPROM,写入数据,EEPRom,驱动,主要,函数,需要读取数据的时候调用,f_EEPRom_Read,(),函数,,nFault,=,f_EEPRom_Read(unsigned,char*)(,i_pData,)
47、22);,输入参数为,:,数据缓冲起始地址,读出的数据数量,输出参数为,:0-,写入正常,1-,读出故障,需要写入数据的时候调用,f_EEPRom_Write,(),函数,举例,:,nFault,=,f_EEPRom_Write(pData,22);,输入参数为,:,数据缓冲起始地址,要写入的数据数量,输出参数为,:0-,写入正常,1-,写入故障,写入单个数据的时候调用,f_EEPRom_WriteOneByte,(),举例,:,nFault,=f_EEPRom_WriteOneByte(0 x55,3);,输入参数为,:,要写入的数据,要写入的地址,输出参数为,:0-,写入正常,1-,写入
48、故障,RTC,驱动,(RTC_PCF8563.c),功能:用来驱动,Philips,的,时钟芯片,8563,,,使用,I2C,总线方式,通过此驱动程序可以从,RTC,中读出时间数据或向,RTC,中写入数据,同时可以检测,RTC,是否故障。,注意事项:,与硬件的接口通过,io_define.h,完成,MAX_READ_WRITE_,RTC,_NUM,为,故障判断次数,当连续写入(读出)错误超过此值时认为,EEPROM,故障,因为时间一般需要几个,BYTE,来表示,因此需要使用结构体,包含,MainStruct.h,文件,RTC,驱动,主要,函数,如果要读出小时分秒格式的数据,则调,f_RTCGe
49、tHMSTime,(),输入变量,:,hour_def,格式的时间变量地址,输出变量,:,正确返回,0,错误返回,-1,例,:,nRTCFault,=,f_RTCGetHMSTime(&tCurTime,);,如果要写入小时分秒格式的数据,则调,f_RTCSetHMSTime,(),输入变量,:,hour_def,格式的时间变量地址,输出变量,:,正确返回,0,错误返回,-1,例,:,nRTCFault,=,f_RTCSetHMSTime(&tSetTime,);,如果初始化时钟,(,启动时钟运行,向特定地址写入固定码等,),调用,f_RTCInit,(),函数,输出变量,:-1,为故障,0,
50、正常写入,例,:,nFault,=,f_RTCInit,();,漏电检测模块,(,ChkElecLeac.c,),电加热或防冻带开则检测是否漏电,不开的时候检测漏电检测电路是否正常,注意事项:,保证,100ms,内正确判断出故障,保证不会因为其他原因引起误报,(,射频干扰,群脉冲干扰等,),温度检测模块,(,ChkTmp.c,),使用平均值滤波:,ChkAverageTmp.c,使用中值滤波:,ChkMiddleTmp.c,Table_Temperature.h,文件中定义,AD,值与温度值的对应表,包含对所有传感器的温度检测,并检测传感器是否故障,根据实际情况判断多长时间检测一次温度,传感器






