第一篇:Excel之VBA编程常用语句300句之二
ThisWorkbook.ActiveSheet.Rows(1).RowHeight = 10 ‘改变工作表的行1的高度值设置为10(121)ThisWorkbook.Worksheets(1).Activate ‘当前工作簿中的第一个工作表被激活
(122)ThisWorkbook.Worksheets(“Sheet1”).Rows(1).Font.Bold = True ‘设置工作表Sheet1中的行1数据为粗体
(123)ThisWorkbook.Worksheets(“Sheet1”).Rows(1).Hidden = True ‘将工作表Sheet1中的行1隐藏
ActiveCell.EntireRow.Hidden = True ‘将当前工作表中活动单元格所在的行隐藏
注:同样可用于列。
(124)ActiveSheet.Range(“A:A”).EntireColumn.AutoFit ‘自动调整当前工作表A列列宽
(125)ActiveSheet.Cells.SpecialCells(xlCellTypeConstants,xlTextValues)‘选中当前工作表中常量和文本单元格
ActiveSheet.Cells.SpecialCells(xlCellTypeConstants,xlErrors+xlTextValues)‘选中当前工作表中常量和文本及错误值单元格
*******************************************************
公式与函数
(126)Application.MacroOptions Macro:=”SumPro”,Category:=4 ‘将自定义的SumPro函数指定给Excel中的“统计函数”类别
(127)Application.MacroOptions Macro:=”SumPro”, _
Description:=”First Sum,then Product” ‘为自定义函数SumPro进行了功能说明
(128)Application.WorksheetFunction.CountA(Range(“A:A”))+1 ‘获取A列的下一个空单元格(129)WorksheetFunction.CountA(Cell.EntireColumn)‘返回该单元格所在列非空单元格的数量 WorksheetFunction.CountA(Cell.EntireRow)‘返回该单元格所在行非空单元格的数量(130)WorksheetFunction.CountA(Cells)‘返回工作表中非空单元格数量
(131)ActiveSheet.Range(“A20:D20”).Formula=“=Sum(R*-19]C:R[-1+C”’对A列至D列前19个数值求和
*******************************************************
图表
(132)ActiveWindow.Visible=False
或 ActiveChart.Deselect ‘使图表处于非活动状态
(133)TypeName(Selection)=”Chart” ‘若选中的为图表,则该语句为真,否则为假
(134)ActiveSheet.ChartObjects.Delete ‘删除工作表上所有的ChartObject对象
ActiveWorkbook.Charts.Delete ‘删除当前工作簿中所有的图表工作表
*******************************************************
窗体和控件
(135)UserForms.Add(MyForm).Show ‘添加用户窗体MyForm并显示
(136)TextName.SetFocus ‘设置文本框获取输入焦点
(137)SpinButton1.Value=0 ‘将数值调节钮控件的值改为0
(138)TextBox1.Text=SpinButton1.Value ‘将数值调节钮控件的值赋值给文本框控件
SpinButton1.value=“/Val(TextBox1.Text)” ‘将文本框控件值赋给数值调节钮控件
CStr(SpinButton1.Value)=TextBox1.Text ‘数值调节钮控件和文本框控件相比较
(139)UserForm1.Controls.Count ‘显示窗体UserForm1上的控件数目
(140)ListBox1.AddItem “Command1” ‘在列表框中添加Command1
(141)ListBox1.ListIndex ‘返回列表框中条目的值,若为-1,则表明未选中任何列表框中的条目(142)RefEdit1.Text ‘返回代表单元格区域地址的文本字符串
RefEdit1.Text=ActiveWindow.RangeSelection.Address ‘初始化RefEdit控件显示当前所选单元格区域
Set FirstCell=Range(RefEdit1.Text).Range(“A1”)‘设置某单元格区域左上角单元格
(143)Application.OnTime Now + TimeValue(“00:00:15”), “myProcedure” ‘等待15秒后运行myProcedure过程
(144)ActiveWindow.ScrollColumn=ScrollBarColumns.Value ‘将滚动条控件的值赋值给ActiveWindow对象的ScrollColumn属性
ActiveWindow.ScrollRow=ScrollBarRows.Value ‘将滚动条控件的值赋值给ActiveWindow对象的ScrollRow属性
(145)UserForm1.ListBox1.AddItem Sheets(“Sheet1”).Cells(1,1)‘将单元格A1中的数据添加到列表框中
ListBox1.List=Product ‘将一个名为Product数组的值添加到ListBox1中
ListBox1.RowSource=”Sheet2!SumP” ‘使用工作表Sheet2中的SumP区域的值填充列表框(146)ListBox1.Selected(0)‘选中列表框中的第一个条目(注:当列表框允许一次选中多个条目时,必须使用Selected属性)
(147)ListBox1.RemoveItem ListBox1.ListIndex ‘移除列表框中选中的条目
*******************************************************
对象
Application对象
(148)Application.UserName ‘返回应用程序的用户名
(149)Application.Caller ‘返回代表调用函数的单元格
(150)Application.Caller.Parent.Parent ‘返回调用函数的工作簿名称
(151)Application.StatusBar=”请等待……” ‘将文本写到状态栏
Application.StatusBar=”请等待……” & Percent & “% Completed” ‘更新状态栏文本,以变量Percent代表完成的百分比
Application.StatusBar=False ‘将状态栏重新设置成正常状态
(152)Application.Goto Reference:=Range(“A1:D4”)‘指定单元格区域A1至D4,等同于选择“编辑——定位”,指定单元格区域为A1至D4,不会出现“定位”对话框
(153)Application.Dialogs(xlDialogFormulaGoto).Show ‘显示“定位”对话框,但定位条件按钮无效
(154)Application.Dialogs(xlDialogSelectSpecial).Show ‘显示“定位条件”对话框
(155)Application.Dialogs(xlDialogFormatNumber).show ‘显示“单元格格式”中的“数字”选项卡 Application.Dialogs(xlDialogAlignment).show ‘显示“单元格格式”中的“对齐”选项卡
Application.Dialogs(xlDialogFontProperties).show ‘显示“单元格格式”中的“字体”选项卡 Application.Dialogs(xlDialogBorder).show ‘显示“单元格格式”中的“边框”选项卡
Application.Dialogs(xlDialogPatterns).show ‘显示“单元格格式”中的“图案”选项卡
Application.Dialogs(xlDialogCellProtection).show ‘显示“单元格格式”中的“保护”选项卡 注:无法一次显示带选项卡的“单元格格式”对话框,只能一次显示一个选项卡。
(156)Application.Dialogs(xlDialogFormulaGoto).show Range(“b2”), True ‘显示“引用位置”的默认单元格区域并显示引用使其出现在窗口左上角(注:内置对话框参数的使用)
(157)Application.CommandBars(1).Controls(2).Controls(16).Execute ‘执行“定位”话框,相当于选择菜单“编辑——定位”命令
(158)Application.Transpose(Array(“Sun”,”Mon”,”Tur”,”Wed”,”Thu”,”Fri”,”Sat”))‘返回一个垂直的数组
(159)Application.Version ‘返回使用的Excel版本号
(160)Application.Cursor = xlNorthwestArrow ‘设置光标形状为北西向箭头
Application.Cursor = xlIBeam ‘设置光标形状为Ⅰ字形
Application.Cursor = xlWait ‘设置光标形状为沙漏(等待)形
Application.Cursor = xlDefault ‘恢复光标的默认设置
(161)Application.WindowState ‘返回窗口当前的状态
Application.WindowState = xlMinimized ‘窗口最小化
Application.WindowState = xlMaximized ‘窗口最大化
Application.WindowState = xlNormal ‘窗口正常状态
(162)Application.UsableHeight ‘获取当前窗口的高度
Application.UsableWidth ‘获取当前窗口的宽度
(163)Application.ActiveCell.Address ‘返回活动单元格的地址(注:返回的是绝对地址)(164)Application.ActivePrinter ‘返回当前打印机的名称
(165)Application.ActiveSheet.Name ‘返回活动工作表的名称
(166)Application.ActiveWindow.Caption ‘返回活动窗口的标题
(167)Application.ActiveWorkbook.Name ‘返回活动工作簿的名称
(168)Application.Selection.Address ‘返回所选区域的地址
(169)Application.ThisWorkbook.Name ‘返回当前工作簿的名称
(170)Application.CalculationVersion ‘返回Excel计算引擎版本(右边四位数字)及Excel版本(左边两位数字)
(171)Application.MemoryFree ‘以字节为单位返回Excel允许使用的内存数(不包括已经使用的内存)
(172)Application.MemoryUsed ‘以字节为单位返回Excel当前使用的内存数
(173)Application.MemoryTotal ‘以字节为单位返回Excel可以使用的内存数(包括已使用的内存,是MemoryFree和MemoryUsed的总和)
(174)Application.OperatingSystem ‘返回所使用的操作系统的名称和版本
(175)Application.OrganizationName ‘返回Excel产品登记使用的组织机构的名称
(176)Application.FindFormat ‘查找的格式种类
Application.ReplaceFormat ‘替换查找到的内容的格式种类
ActiveSheet.Cells.Replace What:=” “, _
Replacement:=” “,SearchFormat:=True,ReplaceFormat:=True ‘替换查找到的格式
(177)Application.Interactive=False ‘忽略键盘或鼠标的输入
(178)Application.Evaluate(“Rate”)‘若在工作表中定义了常量0.06的名称为”Rate”,则本语句将返回值0.06
(179)Application.OnUndo “Undo Option”,“Undo Procedure” ‘选择UndoOption后,将执行Undo Procedure过程
*******************************************************
Range对象
(180)Range(A1:A10).value=“/Application.WorksheetFunction.Transpose(MyArray)” ‘将一个含有10个元素的数组转置成垂直方向的工作表单元格区域(A1至A10)
注:因为当把一维数组的内容传递给某个单元格区域时,该单元格区域中的单元格必须是水平方向的,即含有多列的一行。若必须使用垂直方向的单元格区域,则必须先将数组进行转置,成为垂直的。
(181)Range(“A65536”).End(xlUp).Row+1 ‘返回A列最后一行的下一行
(182)rng.Range(“A1”)‘返回区域左上角的单元格
(183)cell.Parent.Parent.Worksheets ‘访问当前单元格所在的工作簿
(184)Selection.Font.Bold=Not Selection.Font.Bold ‘切换所选单元格是否加粗
(185)ActiveSheet.Range(“A:B”).Sort Key1:=Columns(“B”), Key2:=Columns(“A”), _
Header:=xlYes ‘两个关键字排序,相邻两列,B列为主关键字,A列为次关键字,升序排列(186)cell.Range(“A1”).NumberFormat ‘显示单元格或单元格区域中的第一个单元格的数字格式
(187)cell.Range(“A1”).HasFormula ‘检查单元格或单元格区域中的第一个单元格是否含有公式 或cell.HasFormula ‘工作表中单元格是否含有公式
(188)Cell.EntireColumn ‘单元格所在的整列
Cell.EntireRow ‘单元格所在的整行
(189)rng.Name.Name ‘显示rng区域的名称
(190)rng.Address ‘返回rng区域的地址
(191)cell.Range(“A1”).Formula ‘返回包含在rng区域中左上角单元格中的公式。
注:若在一个由多个单元格组成的范围内使用Formula属性,会得到错误;若单元格中没有公式,会得到一个字符串,在公式栏中显示该单元格的值。
(192)Range(“D5:D10”).Cells(1,1)‘返回单元格区域D5:D10中左上角单元格
(193)ActiveCell.Row ‘活动单元格所在的行数
ActiveCell.Column ‘活动单元格所在的列数
(194)Range(“A1:B1”).HorizontalAlignment = xlLeft ‘当前工作表中的单元格区域数据设置为左对齐
(195)ActiveSheet.Range(“A2:A10”).NumberFormat=”#,##0” ‘设置单元格区域A2至A10中数值格式
(196)rng.Replace “ “,”0” ‘用0替换单元格区域中的空单元格
*******************************************************
Collection与object
(197)Dim colMySheets As New Collection
Public colMySheets As New Collection ‘声明新的集合变量
(198)Set MyRange=Range(“A1:A5”)‘创建一个名为MyRange的对象变量
(199)
第二篇:实用的EXCEL VBA编程总结
实用的EXCEL VBA编程小结:
最近单位内部的项目里要用到些报表EXCEL的生成,虽说JAVA 的POI可以有这能力,但觉得还是可能比较麻烦,因此还是转用.net来搞,用Visual Studio2003配合office 2003,用到了一些VBA,因此小结并归纳之,选了些资料归纳在这里,以备今后查考
首先创建 Excel 对象,使用ComObj:
Dim ExcelID as Excel.Application
Set ExcelID as new Excel.Application
1)显示当前窗口:
ExcelID.Visible := True;
2)更改 Excel 标题栏:
ExcelID.Caption := '应用程序调用 Microsoft Excel';
3)添加新工作簿:
ExcelID.WorkBooks.Add;
4)打开已存在的工作簿:
ExcelID.WorkBooks.Open('C:¥Excel¥Demo.xls');
5)设置第2个工作表为活动工作表:
ExcelID.WorkSheets[2].Activate;
或 ExcelID.WorkSheets[ 'Sheet2' ].Activate;
6)给单元格赋值:
ExcelID.Cells[1,4].Value := '第一行第四列';
7)设置指定列的宽度(单位:字符个数),以第一列为例:
ExcelID.ActiveSheet.Columns[1].ColumnsWidth := 5;
8)设置指定行的高度(单位:磅)(1磅=0.035厘米),以第二行为例:
ExcelID.ActiveSheet.Rows[2].RowHeight := 1/0.035;// 1厘米
9)在第8行之前插入分页符:
ExcelID.WorkSheets[1].Rows[8].PageBreak := 1;
10)在第8列之前删除分页符:
ExcelID.ActiveSheet.Columns[4].PageBreak := 0;
11)指定边框线宽度:
ExcelID.ActiveSheet.Range[ 'B3:D4' ].Borders[2].Weight := 3;
1-左 2-右 3-顶 4-底 5-斜(¥)6-斜(/)
12)清除第一行第四列单元格公式:
ExcelID.ActiveSheet.Cells[1,4].ClearContents;
13)设置第一行字体属性:
ExcelID.ActiveSheet.Rows[1].Font.Name := '隶书';
ExcelID.ActiveSheet.Rows[1].Font.Color := clBlue;
ExcelID.ActiveSheet.Rows[1].Font.Bold := True;
ExcelID.ActiveSheet.Rows[1].Font.UnderLine := True;
14)进行页面设置:
a.页眉:
ExcelID.ActiveSheet.PageSetup.CenterHeader := '报表演示';b.页脚:
ExcelID.ActiveSheet.PageSetup.CenterFooter := '第&P页';
c.页眉到顶端边距2cm:
ExcelID.ActiveSheet.PageSetup.HeaderMargin := 2/0.035;
d.页脚到底端边距3cm:
ExcelID.ActiveSheet.PageSetup.HeaderMargin := 3/0.035;
e.顶边距2cm:
ExcelID.ActiveSheet.PageSetup.TopMargin := 2/0.035;
f.底边距2cm:
ExcelID.ActiveSheet.PageSetup.BottomMargin := 2/0.035;
g.左边距2cm:
ExcelID.ActiveSheet.PageSetup.LeftMargin := 2/0.035;
h.右边距2cm:
ExcelID.ActiveSheet.PageSetup.RightMargin := 2/0.035;
i.页面水平居中:
ExcelID.ActiveSheet.PageSetup.CenterHorizontally := 2/0.035;
j.页面垂直居中:
ExcelID.ActiveSheet.PageSetup.CenterVertically := 2/0.035;
k.打印单元格网线:
ExcelID.ActiveSheet.PageSetup.PrintGridLines := True;
15)拷贝操作:
a.拷贝整个工作表:
ExcelID.ActiveSheet.Used.Range.Copy;
b.拷贝指定区域:
ExcelID.ActiveSheet.Range[ 'A1:E2' ].Copy;
c.从A1位置开始粘贴:
ExcelID.ActiveSheet.Range.[ 'A1' ].PasteSpecial;
d.从文件尾部开始粘贴:
ExcelID.ActiveSheet.Range.PasteSpecial;
16)插入一行或一列:
a.ExcelID.ActiveSheet.Rows[2].Insert;
b.ExcelID.ActiveSheet.Columns[1].Insert;
17)删除一行或一列:
a.ExcelID.ActiveSheet.Rows[2].Delete;
b.ExcelID.ActiveSheet.Columns[1].Delete;
18)打印预览工作表:
ExcelID.ActiveSheet.PrintPreview;
19)打印输出工作表:
ExcelID.ActiveSheet.PrintOut;
20)工作表保存:
If not ExcelID.ActiveWorkBook.Saved then
ExcelID.ActiveSheet.PrintPreview End if
21)工作表另存为:
ExcelID.SaveAs('C:¥Excel¥Demo1.xls');
22)放弃存盘:
ExcelID.ActiveWorkBook.Saved := True;
23)关闭工作簿:
ExcelID.WorkBooks.Close;
24)退出 Excel:
ExcelID.Quit;
25)设置工作表密码:
ExcelID.ActiveSheet.Protect “123”, DrawingObjects:=True, Contents:=True, Scenarios:=True
26)EXCEL的显示方式为最大化
ExcelID.Application.WindowState = xlMaximized
27)工作薄显示方式为最大化
ExcelID.ActiveWindow.WindowState = xlMaximized
28)设置打开默认工作薄数量
ExcelID.SheetsInNewWorkbook = 3
29)'关闭时是否提示保存(true 保存;false 不保存)
ExcelID.DisplayAlerts = False
30)设置拆分窗口,及固定行位置
ExcelID.ActiveWindow.SplitRow = 1
ExcelID.ActiveWindow.FreezePanes = True
31)设置打印时固定打印内容
ExcelID.ActiveSheet.PageSetup.PrintTitleRows = “$1:$1”
32)设置打印标题
ExcelID.ActiveSheet.PageSetup.PrintTitleColumns = “"
33)设置显示方式(分页方式显示)
ExcelID.ActiveWindow.View = xlPageBreakPreview
34)设置显示比例
ExcelID.ActiveWindow.Zoom = 100
35)让Excel 响应 DDE 请求
Ex.Application.IgnoreRemoteRequests = False
用VB操作EXCEL
Private Sub Command3_Click()
On Error GoTo err1
Dim i As Long
Dim j As Long
Dim objExl As Excel.Application '声明对象变量
Me.MousePointer = 11 '改变鼠标样式
Set objExl = New Excel.Application '初始化对象变量
objExl.SheetsInNewWorkbook = 1 '将新建的工作薄数量设为1
objExl.Workbooks.Add '增加一个工作薄
objExl.Sheets(objExl.Sheets.Count).Name = ”book1“ '修改工作薄名称
objExl.Sheets.Add , objExl.Sheets(”book1“)‘增加第二个工作薄在第一个之后
objExl.Sheets(objExl.Sheets.Count).Name = ”book2“
objExl.Sheets.Add , objExl.Sheets(”book2“)‘增加第三个工作薄在第二个之后
objExl.Sheets(objExl.Sheets.Count).Name = ”book3“
objExl.Sheets(”book1“).Select '选中工作薄
For i = 1 To 50 '循环写入数据
For j = 1 To 5
If i = 1 Then
objExl.Selection.NumberFormatLocal = ”@“ '设置格式为文本
objExl.Cells(i, j)= ” E “ & i & j Else
objExl.Cells(i, j)= i & j End If Next Next
objExl.Rows(”1:1“).Select '选中第一行
objExl.Selection.Font.Bold = True '设为粗体
objExl.Selection.Font.Size = 24 '设置字体大小
objExl.Cells.EntireColumn.AutoFit '自动调整列宽
objExl.ActiveWindow.SplitRow = 1 '拆分第一行
objExl.ActiveWindow.SplitColumn = 0 '拆分列
objExl.ActiveWindow.FreezePanes = True '固定拆分 objExl.ActiveSheet.PageSetup.PrintTitleRows = ”$1:$1“ '设置打印固定行
objExl.ActiveSheet.PageSetup.PrintTitleColumns
=
”“
'objExl.ActiveSheet.PageSetup.RightFooter = ”打印时间: “ & _
Format(Now, ”yyyy年mm月dd日 hh:MM:ss“)
objExl.ActiveWindow.View = xlPageBreakPreview '设置显示方式
objExl.ActiveWindow.Zoom = 100 '设置显示大小
'给工作表加密码
objExl.ActiveSheet.Protect ”123", DrawingObjects:=True, _
Contents:=True, Scenarios:=True
objExl.Application.IgnoreRemoteRequests = False
objExl.Visible = True '使EXCEL可见
objExl.Application.WindowState = xlMaximized 'EXCEL的显示方式为最大化
objExl.ActiveWindow.WindowState = xlMaximized '工作薄显示方式为最大化
objExl.SheetsInNewWorkbook = 3 '将默认新工作薄数量改回3个
Set objExl = Nothing '清除对象
Me.MousePointer = 0 '修改鼠标
打
印
标
题 Exit Sub err1:
objExl.SheetsInNewWorkbook = 3
objExl.DisplayAlerts = False '关闭时不提示保存
objExl.Quit '关闭EXCEL
objExl.DisplayAlerts = True '关闭时提示保存
Set objExl = Nothing
Me.MousePointer = 0 End Sub
第三篇:智慧之语
智慧之语
清平乐 /李煜 别来春半,触目柔肠断。砌下落梅如雪乱,拂了一身还满。雁来音信无凭,路遥归梦难成。离恨恰如春草,更行更远还生。
]1.一个人最大的缺点不是自私、多情、野蛮、任性,而是偏执地爱一个不爱自己的人。2.一个承诺在最重要的时候没有兑现,那就是出卖。3.记忆像是倒在掌心的水不论你摊开还是紧握终究还是会从指缝中一滴一滴流淌干净。4.什么叫快乐?就是掩饰自己的悲伤对每个人微笑。
爱人是路,朋友是树。人生只有一条路,一条路上却有多棵树。有钱的时候别迷路,没钱的时候靠靠树。幸福的时候莫忘路,休息的时候浇浇树。
玉楼春 /欧阳修 别后不知君远近,触目凄凉多少闷。渐行渐远渐无书,水阔鱼沉何处问。夜深风竹敲秋韵,万叶千声皆是恨。故欹单枕梦中寻,梦又不成灯又烬。
不断的努力,才会提升自己。
完美女朋友标准:1.懂事2.融入你的生活圈3.她永远会把你与其他男生区别对待4.她也许会有很多异性朋友5.她不抽烟不酗酒6.天天嚷着喜欢帅哥7.路痴8.你发给她的短消息,她一条也舍不得删.9.她需要你的肩膀10.她不会总要求你先让步11.她发给你的短信几乎不会有错别字12.她很想陪着你。
有些人会一直刻在记忆里的——即使忘记了他(她)的声音,忘记了他(她)的笑容,忘记了他(她)的脸,但是每当想起他(她)时的那种感受,是永远都不会改变的…我们微笑着说:我们停留在时光的原处,其实,那早已被时间洪流无声地卷走。
安忍不动如大地,深思静虑似密藏。今日复诵少时的座铭,别是一番滋味。人生的修行,困顿时寸进也难,开悟的机缘成熟时,遍地莲花、刹那笙歌中齐齐开放。
猗兰声歇。抱孤琴思远,几番弹彻。洗耳无人,寂寂行歌古时月。一笑东风又急。黯消凝、恨听啼鴂。想少陵、还叹飘零,遣兴在吟箧。# 愁绝更离别。待款语迟留,赋归心切。故园梦接。花影闲门掩春蝶。重访山中旧隐,有羁怀、未须轻说。莫相忘,堤上柳、此时共折。梧桐树,三更雨,不道离情正苦。一叶叶,一声声,空阶滴到明。
人生就象一口大锅,当你走到了锅底时,无论再朝哪个方向走,都是向上的。最困难的时刻也许就是拐点的开始,改变一下思维方式可能就迎来转机。乐观豁达的人,能把平凡的生活变得富有情趣,能把苦难的日子变得甜美珍贵,能把繁琐的事情变得简单可行。以平常心去看世界,花开花谢都是风景。
如果有一天,让你心动的再也感动不了你,让你愤怒的再也激怒不了你,让你悲伤的再也不能让你流泪,你便知道这时光,这生活给了你什么,你为了成长,付出了什么。
当下中国,某类散文只擦拭观点,而无视身旁人群,自己所居住的场,喧嚣变革的时代,作品凌空蹈虚,遭读者蔑视讥讽全然不觉。应该有一种和时代水乳交融、血肉相连的散文出现,应该将散文不排斥主体,将主体摆进去,并同时保持主体的独立性和自由性的特点,充分发挥出来,让散文中的“我”变得更大起来。爱一个人,要问自己:对于他那些最恶劣的行为和性情,是否能够容忍?如果你不能够,你就离开。
第四篇:单片机编程经验之总结
单片机编程经验之总结!【转】
贴子发表于:2008/11/3 21:38:05 经验之一:用“软件陷阱+程序口令”对付PC指针的弹飞
当CPU受到外界干扰,有时PC指针会飞到另一段程序中,或跳到空白段去。其实,如果PC指针飞到空白段去,倒也好处理。只要在空白段设立软件陷阱(拦截指令),将程序拦截到初始化段或程序错误处理段。但是,如果PC指针飞到另一段程序中去了,系统如何办?小匠在这里推荐一种方法——程序口令。思路如下:
1、首先,程序必须模块化。每个模块(子程序)执行一个功能。每个模块只有一个出口(RET)。
2、设立一个模块(子程序)ID寄存器。
3、为每个子程序配置一个唯一的ID号码。
4、每当子程序执行完毕,要返回(RET)之前,先将本子程序的ID号送入 ID寄存器。
5、返回到上级程序后,先判断ID寄存器中的ID号。
如果正确,则继续执行;如果不正确,则表示PC指针有可能已经跳错了,子程序没有按预计的出口返回,这时将程序拦截到初始化段或程序错误处理段。
这种方法,如同在程序中设立了若干个岗哨,每次调用子程序返回后,都要对口令(ID号),验明正身后再放行。再配合软件陷阱,基本上可以将大多数PC指针弹飞的现象检测到。到了程序错误处理段,要杀要剐(冷启动还是热启动)就由您了。
仅以一条代码来揭示程序飞跑的本质!750102H ;MOV 01H,#02H,如当前PC不是指向75H,而是指向01H或02H,那么51内的指令译码器将把她们忠实地翻译成AJMP X01H 或 LJMP XXXXH 而XX01H XXXXH又是什么呢?天知道!这样恶性飞跑下去那还不死定!改革一下:
CLR A ;0C4H INC A ;04H MOV R1,A ;0F9H INC A ;04H MOV @R1,A ;86H
每一字节代码都不能在生成跳转和循环,且都是单字节指令!往那跑去?跑出去了都要自己回来!“在家”千日好!“跳出”事事难嘛!这样只要平时习惯了用累加器和寄存器把数倒一倒,把那些危险代码都给倒掉,这样虽说给PC的“足”上多加了两字节的“包”可它不好“跑”啊!“足包”====跑!有朋友会问:要是PC抓做02H--LJMP 又有抓做了老鼻子远的XXH,再抓做隔壁的YYH不就没用了吗?提这样的问题只有ZENYIN这种钻牛角得才会提!PC那一位最活跃啊?PC0啊!要“扯拐”显然发生在她身上,至于那PC15同志啊,睡得更死猪一样,雷爆(强干扰)来了都打不醒?此外如果干扰都强到了PC高位都出错的地步!关电!关电!不干了!“不是我们不行而是敌人太强大”!反过来要是敌人在你的专政下,只是偶尔出来捣捣乱,但一出来就冲到屁西(PC)高层,就要问问是不是你的王国根基(硬件)有问题了?而非出在意识形态(软件)上!硬件为本!软件为标!标本兼治铸就坚强体魄,方能百毒不侵!
经验之
二、不要轻信软件狗
关于软件狗的讨论,论坛上多矣。匠人也曾经查阅过许多关于软件狗的文章。有些大师确实提出了一些比较有技巧性的方法。但是,匠人的忠告是:不要轻信软件狗!其实,软件狗相当于软件的一种自律行为。一般的思路都是通过设立一个计数器,在计时中断中对其+1,在主程序的适当地方对其清零。如果程序失控了,清零指令未被执行,但中断造常发生,则计数器溢出(狗狗叫了)。但是这里有个问题:万一干扰导致中断被屏蔽了,那软件狗就永远不会叫了!——针对这种可能,有人提出在主程序中反复刷新中断使能标志,保证不让中断被屏蔽。——但万一程序飞到某个死循环中去了,不再执行“刷新中断使能标志”这一功能了,还是有可能把狗狗活活饿死。。
所以,匠人的观点是:看门狗必须拥有独立的计数器。(即硬件看门狗)好在现在好多芯片都提供了内部WDT。这种狗都是自带计数器的。即使干扰导致程序失控,WDT还是会造常计数直到溢出。当然,匠人也没有要将软件狗一棍子全部打死的意思。毕竟不管是软狗还是硬狗,逮到耗子就是好狗嘛(狗拿耗子——多管闲事?)。如果哪位训狗专家确实养过一条能看门的好软件狗,请牵出来让大伙瞧瞧。
经验之
三、话说RAM冗余技术
所谓的RAM冗余,就是:
1、将重要的数据信息备份2份(或以上)并存放在RAM中不同的区域(指地址不相连)。
2、当平时对这些数据进行修改时,同时也更新备份。
3、当干扰发生并被拦截到“程序错误处理段”中时,将数据与备份做比较,采用表决方式(少数服从多数)选出正确(或可能正确?)的那个。
4、备份越多,效果越好。(当然,你得有足够的存储空间)。
5、只备份最最原始的数据。中间变量(指那些可以从原始数据重新推导出来的数据)不必备份,注:
1、这种思路的理论依据,据说是源于一种“概率论”,即一个人被老婆打肿脸的概率是很大的,但如果他捂着脸去上班却发现全公司每个已婚男人的脸都青了,这种概率是很小的。同理,一个RAM寄存器数据被冲毁的概率是很大的,但地址不相连的多个RAM同时被冲毁的概率是很小的。
2、前两年,小匠学徒时,用过一次这种方法,但效果不太理想。当时感觉可能是概率论在我这失效了?现在回想起来,可能是备份的时机选的不好。结果将已经冲毁的数据又备份进去了。这样以来,恢复出来的数据自然也就不对了。
经验之
四、话说指令冗余技术
前面有个朋友问到指令冗余,按匠人的理解,指令冗余,就是动作冗余。举个例子,你要在某个输出口上输出一个高电平去驱动一个外部器件,你如果只送一次“1”,那么,当干扰来临时,这个“1”就有可能变成“0”了。正确的处理方式是,你定期刷新这个“1”。那么,即使偶然受了干扰,它也能恢复回来。除了I/O口动作的冗余,匠人强烈建议大家在下面各方面也采用这种方法:
1、LCD的显示。有时,也许你会用一些LCD的专用驱动芯片(如HT1621),这种芯片有个好处,即你只要将显示数据传送给它,它就会不断的自动扫描LCD。但是,你千万不要以为这样就没你啥事了。正确的处理方式是,要记得定期刷新送显数据(即使显示内容没有改变)。对于CPU中自带LCD DRIVER 的,也要定期刷新LCD RAM。
2、中断使能标志的设置。不要以为你在程序初始化段将中断设置好就OK了。应该在主程序中适当的地方定期刷新一下,以免你的中断被挂起来。
3、其它一些标志字和参数寄存器(包括你自己定义的),也要记得常常刷新。
4、其它一些你认为有必要反复刷新的地方。
经验之
五、10种软件滤波方法
下面奉献——匠人呕心沥血搜肠刮肚冥思苦想东拼西凑整理出来的10种软件滤波方法:
1、限幅滤波法(又称程序判断滤波法)
A、方法:根据经验判断,确定两次采样允许的最大偏差值(设为A),每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效。如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值
B、优点:能有效克服因偶然因素引起的脉冲干扰。
C、缺点:无法抑制那种周期性的干扰,平滑度差。
2、中位值滤波法
A、方法:连续采样N次(N取奇数),把N次采样值按大小排列,取中间值为本次有效值。
B、优点:能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果。
C、缺点:对流量、速度等快速变化的参数不宜。
3、算术平均滤波法
A、方法:连续取N个采样值进行算术平均运算。N值较大时:信号平滑度较高,但灵敏度较低;N值较小时:信号平滑度较低,但灵敏度较高。N值的选取:一般流量,N=12;压力:N=4
B、优点:适用于对一般具有随机干扰的信号进行滤波,这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
C、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用,比较浪费RAM。
4、递推平均滤波法(又称滑动平均滤波法)
A、方法:把连续取N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则),把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4
B、优点:对周期性干扰有良好的抑制作用,平滑度高,适用于高频振荡的系统。
C、缺点:灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差,不易消除由于脉冲干扰所引起的采样值偏差,不适用于脉冲干扰比较严重的场合,比较浪费RAM
5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
A、方法:相当于“中位值滤波法”+“算术平均滤波法”。连续采样N个数据,去掉一个最大值和一个最小值,然后计算N-2个数据的算术平均值。N值的选取:3~14
B、优点:融合了两种滤波法的优点,对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。
C、缺点:测量速度较慢,和算术平均滤波法一样,比较浪费RAM。
6、限幅平均滤波法
A、方法:相当于“限幅滤波法”+“递推平均滤波法”,每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理。
B、优点:融合了两种滤波法的优点,对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。
C、缺点:比较浪费RAM。
7、一阶滞后滤波法
A、方法:取a=0~1,本次滤波结果=(1-a)*本次采样值+a*上次滤波结果。
B、优点:对周期性干扰具有良好的抑制作用,适用于波动频率较高的场合。
C、缺点: 相位滞后,灵敏度低,滞后程度取决于a值大小,不能消除滤波频率高于采样频率的1/2的干扰信号。
8、加权递推平均滤波法
A、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权。通常是,越接近现时刻的数据,权取得越大。给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低。
B、优点:适用于有较大纯滞后时间常数的对象和采样周期较短的系统。
C、缺点:对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号不能迅速反应系统当前所受干扰的严重程度,滤波效果差。
9、消抖滤波法
A、方法:设置一个滤波计数器将每次采样值与当前有效值比较:如果采样值=当前有效值,则计数器清零如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出),如果计数器溢出,则将本次值替换当前有效值,并清计数器。
B、优点:对于变化缓慢的被测参数有较好的滤波效果,可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动。
C、缺点:对于快速变化的参数不宜,如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统。
10、限幅消抖滤波法
A、方法:相当于“限幅滤波法”+“消抖滤波法” 先限幅,后消抖。
B、优点: 继承了“限幅”和“消抖”的优点改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统。
C、缺点:对于快速变化的参数不宜。
IIR 数字滤波器
A.方法:确定信号带宽,滤之。Y(n)= a1*Y(n-1)+ a2*Y(n-2)+.+ ak*Y(n-k)+ b0*X(n)+ b1*X(n-1)+ b2*X(n-2)+.+ bk*X(n-k)。
B.优点:高通,低通,带通,带阻任意。设计简单(用matlab)
C.缺点:运算量大。
第五篇:C语言对单片机编程的学习心得
很多朋友都在学习单片机或是想学单片机,但在看了一些资料后,要么感到不知道学的什么,要么找不到下一步的学习方法,这都很正常,因为单片机的学习是一项综全性知识的结果。那么怎样学习单片机,怎么样学好单片机是我们关心的,通过我本人的学习过程,我总结了几条,是单片机学习都要具备的几个条件:
1.首先要明确一点,你是爱好单片机编程的,通过写出各种各样的程序,你可以从中得到快乐和成就感,这一点非常重要,如果你是因为学好单片机可以走上更好的工作岗位得到更好的报酬,那也可以,必竞有个动力所以可以驱使你好好的学。
2.要具备能吃苦的精神,学习单片机初期是十分枯燥无味的(在你能写出自已的程序前这一段时间),你会被状态控制字、中断地址、中断优先级等等问题所困惑,可能有些问题要好多天,查了很多资料,想的头疼后你才能彻底想明白。没有吃苦的精神是不行的。所以这一点也很重要。
3.要具备一些数字电路和模拟电路知识,这些虽然看起来和单片机关系不大,实际上哪个单片机没有外围电路,没有这些知识你学会单片机编程后,能力也会被大大的限制。
4.虽然现在工作中用单片机编程都用的C语言编程,因为C语言有代码编写程序速度快,逻辑比较清晰,可维护性强。但是汇编语言对初学者来说也十分重要,这有助于你了解单片机内部运行机制,对单片机的执行过程更加了解。听朋友这么说过,当一个工程师做单片机程序从汇编转到C时,他的水平就提高了,但当他从C又转回汇编时那么他就成精了。
5.要边学边练习,光看书还是不行的,要把你在学习过程中的编程思路在单片机上跑起来,你才会更能找到编写单片机程序的感觉。如果不把自已的编程思路在单片机上运行起来,那么后面你就不知道自已的想法是对是错,感觉无法继续下去。如果经济条件允许一块开发板还是必须的,理论和动手相经结合,你的单片机水平会提高的很快。
6.多想多练,做一些实际的项目,你可以根据你现有的开发板硬件条件,做出一些你感觉比较有意思的项目,实际动手做过项目和看过别人的项目还是有差别的。自已做过项目以后在工作或求职中就没有那么被动,也会有信心一点。
祝个位学习单片机的朋友早日提高!以上是个人见解有不同意见请提出来供广大单片机爱好参考。
创易电子搜集,全部资料来源于互联网开源资料,如有侵权,请及时与楼主联系立刻纠正。