嵌入式软件设计及编程思想2-1_第1页
嵌入式软件设计及编程思想2-1_第2页
嵌入式软件设计及编程思想2-1_第3页
嵌入式软件设计及编程思想2-1_第4页
嵌入式软件设计及编程思想2-1_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单片机软件设计及编程思想李海全一个嵌入式设计系统一般包含对外 显示、指示灯、按键 模拟量输入(凹凸压、交直流、多回路) 开关量输入 开关量输出 变送输出 通信(RS485\DLT645\Profibus)一个嵌入式设计系统一般包含对内 显示驱动 LED595/IO/TM1629 LCD1621/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(width<height)dosomething();综合考虑全部条件推断if考虑else,switch考虑default程序版式(易读性)假如出现嵌套的{},则运用缩进对齐,如: { … { … } …}叮嘱规则留意大小写intHowManyPeople; //全局变量intHowMuchMoney;运用下划线intdraw_mode;不要运用不明含义的缩写设计理念空间换时间频繁计算的时间为主 例:中断中采样、扫描、读取DI限制DO等 应尽可能提高速度,削减调函数、循环次数时间换空间很少须要计算的例:校准、按键操作等应优化代码削减存储空间设计头文件设计头文件设计头文件typedef union{ floatFT; unsignedlongULG; signedlongSLG; unsignedcharUBY[4]; shortintIWD[2]; unsignedshortintUWD[2];}UNION_FT_4BY;typedef union{ 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可能各不一样显示设计数码液晶混合设计思路段式显示段式显示设计显示驱动typedef union{ 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_BY DSBUF[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(keyDownDLy>15) { keyDownDLy=0;KEY_DATA=KEY_OLD;SAM++;} } else { if(keyDownDLy>99) { 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(); } else if(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); } //PASS elseif(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)

中断中和主程序中不能均限制外设,尤其留意定时器和通信的处理存储设计按存储介质

我司常用的

EEPROM

铁电(存储电能)

不举荐设计时运用芯片内部FLASH做存储存储设计IIC外部有上拉电阻,需考虑CPU的IO口属性

开漏输入输出

一般IO做一般IO时,在时序不对时易产生大电流锁死CPU,程序应和常规不一样存储设计一存储设计二存储设计三留意事项:

1.上电后,CPU起先运行后,不能立刻读写外设

2.一般延时3秒后操作,此时电源稳定

3.一般上电操作灭->显示版本->全亮->(读数据)->正常运行

4.上电后举荐不进行写操作

5.举荐存储数据分区间校验,可以做累加和,如设置数据一组、校准数据一组、电能数据一组等

6.EEPROM上电默认一般为FFFF,铁电上电一般默认为0

7.有条件做双备份DI读取 留意,设计时最好IO默认上拉(可以外部),考虑未安装时设计为断开状态,不能为不确定状态

1.常开常闭点

IO状态要么断开、要么闭合

中断中读取,延时消抖

2.有源湿节点

无信号时才完全断开,

有信号时时断时续DI读取1.常开常闭点

if(READ2_DI1())

{

if(DIDLY_On[0]<DI_Read_TotalCnt)

{ DIDLY_On[0]++; }

else

{ DI_DO_Status.DIDO.DI1=0; }

DIDLY_Of[0]=0;

}

else

{ if(DIDLY_Of[0]<DI_Read_TotalCnt)

{ DIDLY_Of[0]++; }

else

{ DI_DO_Status.DIDO.DI1=1; }

DIDLY_On[0]=0;

}

DI读取2.有源湿节点

看硬件怎么接

不同解法不一样

正常50HZ,一般通,一般断

留意点:施加谐波后不同DI读取2.有源湿节点

考虑布线干扰,防误动,施加谐波防不动,具体状况具体分析,取合适的推断值

if(READ_DI1())DI_OFF_DLY[0]++;elseDI_ON_DLY[0]++;

if(DI_OFF_DLY[0]+DI_ON_DLY[0]>800)

{

if(DI_ON_DLY[0]>400)

{Meas.T.DIStatus.Bits.Bit0=1; }

else {Meas.T.DIStatus.Bits.Bit0=0; }

DI_OFF_DLY[0]=0; DI_ON_DLY[0]=0;

}

DI读取3.留意事项

通信和DI和DO排在一起时

操作DO时,DI不应被更改

MODBUS协议须要做02叮嘱DO设置1.总线限制

电平方式

脉冲方式

2.报警限制

取各信号输入

延时

死区,不动作带

高报警、低报警

为零时是否报警DO设置 1.电平方式

中断中操作IO

if(DI_DO_Status.DIDO.DO1)

RELAY_SET_TDO1();

else

RELAY_CLR_TDO1();

2.脉冲方式

毫秒级须要要中断中做,秒级主程序中做即可

DO动作后,推断延时到了修改相应变量皆可 DI_DO_Status.DIDO.DO1 通信通信编程需接受收数据帧方式处理,不同波特率延时不同,收帧最短帧间隔时间应大于1.5个字符时间以9600波特率为例,假如接收的2个字符间隔时间超过1.5毫秒则认为是2帧。发送数据帧时应有延时,从收到帧结束到发送帧起先最短间隔应大于3.5个字符时间。波特率超过9600可以以9600的时间为准。通信通信设计时应按帧接收例:可用1毫秒定时器做,检测是否有数据接收struct{ unsignedshortintINNUM,START; unsignedcharR_ALL,S_Dly,S_Flag,R_Dly,R_Flag; unsignedcharinbuff[100]; unsignedcharoutbuff[270]; unsignedshortintOUTNUM; unsignedchar*sbuff;}UartUD1;通信设计时应按帧接收例:可用1毫秒定时器做,检测是否有数据接收voidUSART1_SendRec_Dly(void) { if(UartUD1.S_Flag) { if(UartUD1.S_Dly==0) { UartUD1.S_Flag=0; USART_ITConfig(USART1,USART_IT_TXE,ENABLE); USART_ITConfig(USART1,USART_IT_RXNE,DISABLE); if(UartUD1.OUTNUM!=0) { UartUD1.OUTNUM--; USART_SendData(USART1,*UartUD1.sbuff); UartUD1.sbuff++; } } else UartUD1.S_Dly--; } elseif(UartUD1.OUTNUM==0)USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); 。。。。。。}通信设计时应按帧接收例:可用1毫秒定时器做,检测是否有数据接收voidUSART1_SendRec_Dly(void) { 。。。。 switch(Comm_Baud) { case3: if(UartUD1.R_Dly>=4){UartUD1.R_Flag=1;if(UartUD1.START>2)UartUD1.R_ALL=1;} else{UartUD1.R_Dly++;UartUD1.R_Flag=0;} break; case4: if(UartUD1.R_Dly>=7){UartUD1.R_Flag=1;if(UartUD1.START>2)UartUD1.R_ALL=1;}else{UartUD1.R_Dly++;UartUD1.R_Flag=0;}break; case5: if(UartUD1.R_Dly>=14){UartUD1.R_Flag=1;if(UartUD1.START>2)UartUD1.R_ALL=1;}else{UartUD1.R_Dly++;UartUD1.R_Flag=0;}break; default: if(UartUD1.R_Dly>=2){UartUD1.R_Flag=1;if(UartUD1.START>2)UartUD1.R_ALL=1;}else{UartUD1.R_Dly++;UartUD1.R_Flag=0;}break; }}通信发送时设置延时例:voidUSART1_Send_Ready(void){ switch(Comm_Baud) { case5: UartUD1.S_Dly=19; break; case4: UartUD1.S_Dly=8; break; case3: UartUD1.S_Dly=4; break; default:UartUD1.S_Dly=1; break; } UartUD1.S_Flag=1; UartUD1.INNUM=0;UartUD1.START=0; UartUD1.R_ALL=0; UartUD1.sbuff=UartUD1.outbuff;}通信MODBUS通信按GBZ19582.1-2004标准执行,以下需特殊留意地址范围1-247,波特率举荐1200-38400,奇偶校验位03H叮嘱读功能 默认最少允许用户从地址0起先读125个数据,如只用到20个地址,其他地址宜默认填0。地址125以上超过设定的地址假如未默认为

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论