您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 嵌入式软件设计及编程思想2_1
单片机软件设计及编程思想李海全一个嵌入式设计系统一般包含对外显示、指示灯、按键模拟量输入(高低压、交直流、多回路)开关量输入开关量输出变送输出通信(RS485\DLT645\Profibus)一个嵌入式设计系统一般包含对内显示驱动LED595/IO/TM1629LCD1621/1622等点阵、段式存储驱动EEPROM/铁电/FLASH采样CPU内部AD、AD芯片、测量SOC控制+算法设计原则1.可靠性2.维护性(可读性)3.移植性功能模块分类编程时分文件处理,一般一个驱动、一个功能模块一个文件原则:1.一个驱动芯片相应的操作封装到一个文件中2.一个算法,详细描述计算公式,涉及优化后的公式,标明原始和推导公式,做一个文件3.文件不适合过多,文件名应一目了然,根据文件名知其内容设计分类文件结构遵循一模块一文件格式注释特别是设计更改需注明更改日期、更改人、更改记录(头、行)文件头加注释说明功能文件结构程序版式(易读性)以布局清晰为原则不同函数体不同功能(同一函数中、定义变量)缩进(不要使用空格、使用TAB(4格))程序版式(易读性)推荐写法if(condition){…//programcode}else{…//programcode}不推荐写法if(condition){…//programcode}else{…//programcode}少用if(widthheight)dosomething();综合考虑所有条件判断if考虑else,switch考虑default程序版式(易读性)如果出现嵌套的{},则使用缩进对齐,如:{…{…}…}命令规则注意大小写intHowManyPeople;//全局变量intHowMuchMoney;使用下划线intdraw_mode;不要使用不明含义的缩写设计理念空间换时间频繁计算的时间为主例:中断中采样、扫描、读取DI控制DO等应尽可能提高速度,减少调函数、循环次数时间换空间很少需要计算的例:校准、按键操作等应优化代码减少存储空间设计头文件设计头文件设计头文件typedefunion{floatFT;unsignedlongULG;signedlongSLG;unsignedcharUBY[4];shortintIWD[2];unsignedshortintUWD[2];}UNION_FT_4BY;typedefunion{shortintIWD;unsignedshortintUWD;unsignedcharUBY[2];struct{unsignedcharBit0:1;unsignedcharBit1:1;unsignedcharBit2:1;unsignedcharBit3:1;unsignedcharBit4:1;unsignedcharBit5:1;unsignedcharBit6:1;unsignedcharBit7:1;unsignedcharBit8:1;unsignedcharBit9:1;unsignedcharBit10:1;unsignedcharBit11:1;unsignedcharBit12:1;unsignedcharBit13:1;unsignedcharBit14:1;unsignedcharBit15:1;}Bits;}UNION_WD_2BY;高低位需要在编译环境中试验定义好,不同的编译环境和CPU可能各不一样显示设计数码液晶混合设计思路段式显示段式显示设计显示驱动typedefunion{unsignedcharUBY;struct{unsignedcharA:1;unsignedcharB:1;unsignedcharC:1;unsignedcharD:1;unsignedcharE:1;unsignedcharF:1;unsignedcharG:1;unsignedcharP:1;}LED;struct{unsignedcharBit0:1;unsignedcharBit1:1;unsignedcharBit2:1;unsignedcharBit3:1;unsignedcharBit4:1;unsignedcharBit5:1;unsignedcharBit6:1;unsignedcharBit7:1;}Bits;}UNION_SEG_BY;UNION_SEG_BYDSBUF[17];缓冲、显存设计显示驱动在不影响显示的情况下,可重复预制一些寄存器抗干扰动态扫描设计扫描频率计算扫描频率范围一般在50Hz~100Hz过快浪费资源,过慢肉眼可视抖动可软件实现调整变暗例:借用1毫秒中断定时器,5个数码管,1000/5最大可设计200Hz的刷新频率,动态扫描驱动动态扫描+消影1.先关闭所有显示,显示选通不变,输出为灭2.等一段时间,先进行其他操作(比如说读按键、开关量、控制时间等)?3.切换到要显示的数码管(选通)4.送显示数据按键检测1.一个按键一个IO(编程方面)2.矩阵扫描(目前公司很少用)3.借用其他选通(如显示),一个IO读取按键设计消抖1.硬件2.软件按键设计1.短按(2种,一种检测按下,一种检测按下和释放)2.长按(不影响短按,应确认1-2秒后开始长按)3.组合按(含长按)按键设计staticunsignedcharkeyDownDLy,keypress;staticsignedcharKEY_OLD,SAM;if(keypress!=0)keypress--;else{if(!READ_KEY1())keypress|=0x01;if(!READ_KEY2())keypress|=0x02;if(!READ_KEY3())keypress|=0x04;if(!READ_KEY4())keypress|=0x08;if((KEY_OLD==keypress)&&(keypress!=0)){keyDownDLy++;if(SAM!=1){if(keyDownDLy15){keyDownDLy=0;KEY_DATA=KEY_OLD;SAM++;}}else{if(keyDownDLy99){keyDownDLy=0;KEY_DATA=KEY_OLD;SAM++;}}}else{KEY_OLD=keypress;SAM=0;}keypress=9;}菜单设计菜单层数菜单设计菜单层数不得超过4层(原则上采用4层结构需要有4行显示),宜采用3层结构,不可采用一层(一层但多排显示)翻到底结构。第一层为系统(SYS)、输入(In)、通信(bUS)、报警(do)、变送(tr)、版本(Ver)等设置;第二层为第1层下的子类细分,以报警为例,第2层可以是报警阈值、死区、延时、报警功能选择等;第三层为第2层显示的具体数据。注:选择太多时可选择数字加字母组合到方式,例:报警信号选择0.UA1.UB等菜单设计方法:1。函数指针,网上例程很多2。状态机菜单设计switch(Setup_Data){case0:if(KEY_DATA==KEY_Menu){Setup_Data=1;DS_SETUP(0);break;}elseif(KEY_DATA==KEY_Left){Display_Page=Get_Display_Page(Display_Page,0);}elseif(KEY_DATA==KEY_Right){Display_Page=Get_Display_Page(Display_Page,1);}elseif(KEY_DATA==KEY_Enter){Display_Page=Get_Display_Page(Display_Page,2);}else{break;}Display_All_Page();return;菜单设计switch(Setup_Data){case1:if(KEY_DATA==KEY_Menu){Setup_Data=0;Display_All_Page();}elseif(KEY_DATA==KEY_Enter){Setup_Data=2;tmp_PASSWORD=9999;DS_INT_DATA(2,0,tmp_PASSWORD);}break;菜单设计switch(Setup_Data){case2:if(KEY_DATA==KEY_Menu){Setup_Data=1;DS_SETUP(0);}//PASSelseif(KEY_DATA==KEY_Enter){if(tmp_PASSWORD==PASSWORD.UWD||tmp_PASSWORD==8){Setup_Data=9;DS_SETUP(2);m1Keytmp=0;tmp_PASSWORD=PASSWORD.UWD;tmp_PT=PT.UWD;tmp_CT=CT.UWD;}}else{tmp_PASSWORD=Data_4IWD_Key_Do(tmp_PASSWORD,1,9999);DS_INT_DATA(2,0,tmp_PASSWORD);}break;菜单设计switch(Setup_Data){caseSetup_DO1:caseSetup_DO2:caseSetup_DO3:caseSetup_DO4:if(KEY_DATA==KEY_Menu){Setup_Data=9;DS_SETUP(2+m1Keytmp);}elseif(KEY_DATA==KEY_Enter){cnt=Setup_Data-Setup_DO1;Setup_Data=cnt*SetupD_NN;Setup_Data+=SetupD_DO1+m2Keytmp;if(m2Keytmp==0){DS_SET_DAT(60+tmp_DOSel[cnt]);}elseif(m2Keytmp==1){DS_INT_DATA(2,0,tmp_DODly[cnt]);}elseif(m2Keytmp==2){DS_INT_DATA(2,0,tmp_DOBand[cnt]);DsKeyDOSetPoint(tmp_DOSel[cnt]);}}elseif(m2Keytmp==3){DS_INT_DATA(2,0,tmp_DOHDat[cnt]);DsKeyDOSetPoint(tmp_DOSel[cnt]);}elseif(m2Keytmp==4){DS_INT_DATA(2,0,tmp_DOLDat[cnt]);DsKeyDOSetPoint(tmp_DOSel[cnt]);}else{DS_SET_DAT(50+tmp_DOZero[cnt]);}}else{m2Keytmp=Data_4IWD_Key_Do(m2Keytmp,0,5);DS_LINE(40+m2Keytmp);}break;显示小数点菜单设计switch(Setup_Data){caseSetupD_DO1:caseSetupD_DO2:caseSetupD_DO3:caseSetupD_DO4:cnt=Setup_Data-SetupD_DO1;cnt/=SetupD_NN;tmp_DOSel[cnt]=Data_4IWD_Key_Do(tmp_DOSel[cnt],0,31);DS_SET_DAT(60+tmp_DOSel[cnt]);break;caseSetupD_DO1+1:caseSetupD_DO2+1:caseSetupD_DO3+1:caseSetupD_DO4+1:cnt=Setup_Data-SetupD_DO1;cnt/=SetupD_NN;tmp_DODly[cnt]=Data_4IWD_Key_Do(tmp_DODly[cnt],0,9999);DS_INT_DATA(2,0,tmp_DODly[cnt]);break;存储设计按操作方式IIC(FM24C04)SPI(X5045)地址数据总线总线(FLASH)中断中和主程序中不能均控制外设,尤其注意定时器和通信的处理存储设计按存
本文标题:嵌入式软件设计及编程思想2_1
链接地址:https://www.777doc.com/doc-4012784 .html