2011年12月22日星期四

The problem of AVR USART using USRE interrupt

"The Data Register Empty (UDREn) Flag indicates whether the transmit buffer is ready to receive
new data. This bit is set when the transmit buffer is empty, and cleared when the transmit buffer
contains data to be transmitted that has not yet been moved into the Shift Register. For compatibility with future devices, always write this bit to zero when writing the
UCSRnA Register.
When the Data Register Empty Interrupt Enable (UDRIEn) bit in UCSRnB is written to one, the USART Data Register Empty Interrupt will be executed as long as UDREn is set (provided thatn global interrupts are enabled). UDREn is cleared by writing UDRn. When interrupt-driven data transmission is used, the Data Register Empty interrupt routine must either write new data to UDRn in order to clear UDREn or disable the Data Register Empty interrupt, otherwise a new interrupt will occur once the interrupt routine terminates."

此中断与TXC中断不同,如果在发送一套数据后,发送寄存器会一直空的,这样UDRE中断会一直存在,解决方法就是,在发完后关上UDRE中断。

如果一直产生中断的话,会影响后面的中断的进入。

PS:2011年底,重写飞机上的AVR程序,把以前的usart接收用的TXC中断改为UDRE中断,导致这个问题的发生,被困扰了4天啊。。。基本上都是通宵的。。。。

2011年12月12日星期一

const指针的一些总结

前两天在网上看到华为的一些笔试题,对基础的掌握仍然是这种大公司所重视的。其间对指针掌握的要求比较多,有一道是关于const指针的。看到那道题,回来整理了一些有关const指针的内容,分享一下。

  const说明指针变量,组合的情况可能会显得很复杂。使用指针时要涉及两个目标,即指针本身和指针所指的对象。关于const指针变量,可归结为以下三种:
  1.指向常量的指针变量;
  2.常指针变量;
  3.指向常量的常指针变量。
  下面来分别谈谈这三种情况。

一、指向常量的指针变量:
声明格式: const type * var_name;
或 type const * var_name;
特点: 可改值。
  将指针声明冠以const,使指向的对象为常量,而不是指针为常量。注意:指向常量的指针不一定指向真正的常量,它也可以指向常量,只是从该指针的角度来看,它所指向的对象是常量,通过该指针不能修改它指向的对象。它还可以指向其它的对象,可以不初始化。
-----eg:
int a = 0,b = 1;
const int c = 3;
const int* pi; //等同于 (const int*) pi;
pi = &a;
*pi = 10; //错误:不能修改它指向的对象。
a = 10;
pi = &b;
*pi = &b;
*pi = 20; //错误:不能修改它指向的对象。
b = 20;
pi = &c;
*pi = &c;
*pi = 30; //错误:不能修改它指向的对象。
-----eg2:
const char* pc = "asdf";
pc[3] = 'a'; //错误:不能修改它指向的对象。
pc = "ghik";
-----eg3:
const char* step[3] =
{"left","right","hop"};
step[2] = "skip";
step[2][1] = 'i'; //错误:不能修改它指向的对象。

二、常指针常量:
声明格式: type* const var_name;
特点: 可改对象。
  要把指针本身,而不是它指向的对象声明为常量,采用运算符 *const,必须初始化,通过该指针可以修改它指向的对象,但它不可以指向其他的对象。
-----eg:
int a = 0,b = 1;
int* const pi = &a; //等于 int* (const pi) = &a;
*pi = 10;
pi = &b; //错误:pi本身为常量,不能指向其他对象。

三、指向常量的常指针变量:
声明格式: const type * const var_name;
特点: 值与对象均不能改。
  要使两个目标都是常量,两者都要声明为 const 。
eg:
int a = 0,b = 1;
const int c = 3;
const int* const pi = &a; //相当于: (const int*)(const pi) = &a;
*pi = 10; //错误:不能修改它的对象。
a = 10;
pi = &b; //错误:不能指向其它对象。
eg2:
const char* const pc = "asdf";
pc[3] = 'a'; //错误:不能修改它的对象。
pc = "ghik"; //错误:不能指向其它对象。
eg3:
const char* const step[3] =
{"left","right","hop"};
step[2] = "skip"; //错误:不能指向其它对象。
step[2][1] = 'i'; //错误:不能修改它的对象。

  一般的,当声明中出现 const 描述符时,它修饰的是紧跟其后的声明元素或者在 const 成员函数声明中函数的 this 指针。
  注意:可以将变量的地址赋给指向常量的指针变量,不会因此有什么害处,但是,常量的地址不能赋给无约束的指针。
eg:
int a = 1;
const int c = 2;
const int* p1 = &c;
const int* p2 = &a;
int* p3 = &c; //非法!
int* const p4 = &c; //非法! 指针常量 p4 能够改值。
const int* const p5 = &c;

2011年11月29日星期二

如何利用NTFS加密文件及文件夹

NTFS是WinNT以上版本支持的一种提供安全性、可靠性的高级文件系统。在Win2000和WinXP中,NTFS还可以提供诸如文件和文件夹权限、加密、磁盘配额和压缩这样的高级功能。
  一、加密文件或文件夹
  步骤一:打开Windows资源管理器。
  步骤二:右键单击要加密的文件或文件夹,然后单击“属性”。
  步骤三:在“常规”选项卡上,单击“高级”。选中“加密内容以便保护数据”复选框
 在加密过程中还要注意以下五点:
  1.要打开“Windows 资源管理器”,请单击“开始→程序→附件”,然后单击“Windows 资源管理器”。
  2.只可以加密NTFS分区卷上的文件和文件夹,FAT分区卷上的文件和文件夹无效。
  3.被压缩的文件或文件夹也可以加密。如果要加密一个压缩文件或文件夹,则该文件或文件夹将会被解压。
  4.无法加密标记为“系统”属性的文件,并且位于systemroot目录结构中的文件也无法加密。
  5.在加密文件夹时,系统将询问是否要同时加密它的子文件夹。如果选择是,那它的子文件夹也会被加密,以后所有添加进文件夹中的文件和子文件夹都将在添加时自动加密。
  二、解密文件或文件夹
  步骤一:打开Windows资源管理器。
  步骤二:右键单击加密文件或文件夹,然后单击“属性”。
  步骤三:在“常规”选项卡上,单击“高级”。
  步骤四:清除“加密内容以便保护数据”复选框。
  同样,我们在使用解密过程中要注意以下问题:
  1.要打开“Windows资源管理器”,请单击“开始→程序→附件”,然后单击“Windows资源管理器”。
  2.在对文件夹解密时,系统将询问是否要同时将文件夹内的所有文件和子文件夹解密。如果选择仅解密文件夹,则在要解密文件夹中的加密文件和子文件夹仍保持加密。但是,在已解密文件夹内创立的新文件和文件夹将不会被自动加密。
  以上就是使用文件加、解密的方法!而在使用过程中我们也许会遇到以下一些问题,在此作以下说明:
  1.高级按钮不能用
  原因:加密文件系统(EFS)只能处理NTFS文件系统卷上的文件和文件夹。如果试图加密的文件或文件夹在FAT或FAT32卷上,则高级按钮不会出现在该文件或文件夹的属性中。
  解决方案:
  将卷转换成带转换实用程序的NTFS卷。
  打开命令提示符。
  键入:Convert [drive]/fs:ntfs
  (drive 是目标驱动器的驱动器号)
  2.当打开加密文件时,显示“拒绝访问”消息
  原因:加密文件系统(EFS)使用公钥证书对文件加密,与该证书相关的私钥在本计算机上不可用。
  解决方案:
  查找合适的证书的私钥,并使用证书管理单元将私钥导入计算机并在本机上使用。
  3.用户基于NTFS对文件加密,重装系统后加密文件无法被访问的问题的解决方案(注意:重装Win2000/XP前一定要备份加密用户的证书):
  步骤一:以加密用户登录计算机。
  步骤二:单击“开始→运行”,键入“mmc”,然后单击“确定”。
  步骤三:在“控制台”菜单上,单击“添加/删除管理单元”,然后单击“添加”。
  步骤四:在“单独管理单元”下,单击“证书”,然后单击“添加”。
  步骤五:单击“我的用户账户”,然后单击“完成”(如图2,如果你加密用户不是管理员就不会出现这个窗口,直接到下一步) 。
  步骤六:单击“关闭”,然后单击“确定”。
  步骤七:双击“证书──当前用户”,双击“个人”,然后双击“证书”。
  步骤八:单击“预期目的”栏中显示“加密文件”字样的证书。
  步骤九:右键单击该证书,指向“所有任务”,然后单击“导出”。
  步骤十:按照证书导出向导的指示将证书及相关的私钥以PFX文件格式导出(注意:推荐使用“导出私钥”方式导出,这样可以保证证书受密码保护,以防别人盗用。另外,证书只能保存到你有读写权限的目录下)。
  4.保存好证书
  注意将PFX文件保存好。以后重装系统之后无论在哪个用户下只要双击这个证书文件,导入这个私人证书就可以访问NTFS系统下由该证书的原用户加密的文件夹(注意:使用备份恢复功能备份的NTFS分区上的加密文件夹是不能恢复到非NTFS分区的)。
  最后要提一下,这个证书还可以实现下述用途:
  (1)给予不同用户访问加密文件夹的权限
  将我的证书按“导出私钥”方式导出,将该证书发给需要访问这个文件夹的本机其他用户。然后由他登录,导入该证书,实现对这个文件夹的访问。
  (2)在其也WinXP机器上对用“备份恢复”程序备份的以前的加密文件夹的恢复访问权限
  将加密文件夹用“备份恢复”程序备份,然后把生成的Backup.bkf连同这个证书拷贝到另外一台WinXP机器上,用“备份恢复”程序将它恢复出来(注意:只能恢复到NTFS分区)。然后导入证书,即可访问恢复出来的文件了。

2011年11月26日星期六

VS2008 FLTK Setting

refer to the vedio tutorial: http://www.seriss.com/people/erco/fltk-videos

1.download the stable version FLTK-1.3

2.open the fltk.sln from the IDE folder, choose "Debug Cario" to Debug or Release configuration, otherwise , there will be error showing missing "cario-win32.h", because there is no third-party Cario. However, there will be some problems when choosing Debug configuration, so i chose the Release.

->build all

3. create the folder:D:\Program Files\FLTK-1.3
copy foler FL, lib and fluid.exe to the above folder.

4.add D:\Program Files\FLTK-1.3 and D:\Program Files\FLTK-1.3\lib to the Visual Studio option

5.add fltk.lib wsock32.lib comctl32.lib in the linker option, this is very important.

2011年11月22日星期二

Using Relays (Tips & Tricks)

From: http://jumperone.com/2011/10/using-relays/
In this article I will tell you how to get shorter relay switching times and how to minimize relay current consumption. The same exact things apply to solenoids and solenoid valves.
Usually if you want to control relay from microcontroller you would do something like this:



You need to use a transistor because either relay you want to control needs a higher voltage than your microcontroller can provide, or relay’s current demand is too high. Although some microcontrollers can give enough current to switch a relay, but most of them is incapable of doing that.
And the diode in parallel with relay coil (or solenoid coil) is needed to suppress the flyback voltage that occurs when transistor is switching-off and magnetic field stored in coil collapses. That flyback voltage can reach hundreds of volts, which can completely destroy the driving transistor.
Switch-off (release) speed
When you cutting power to relay, the energy stored in the coil will slowly dissipate through the diode. The problem with this is slow relay release time. This time could be crucial to some high-speed relays or to fast acting valves, like, for example, car fuel injectors, which should open and close really fast to inject specific amount of fuel into combustion chamber (maybe I will write about this someday).
To conquer this problem you can put a zener diode in series with flyback protection diode like so:


This will allow for flyback voltage to go higher, therefore helping to dissipate stored energy in coil much faster and dramatically decreasing relay release time. Zener diode voltage should be lower than transistor breakdown voltage, which you can find in that transistor’s datasheet.
The little test that I’ve made with this relay



shows much smaller release time when using zener diode, than with single clamping diode.
Relay with clamping diode takes about 11.5 milliseconds to turn-off (release):


Channel 1 (yellow) shows state of relay control signal, and channel 2 (blue) goes low when relay is ON.
With additional 12V zener diode it’s only 3.5 milliseconds, which is 8ms less than with just a clamping diode alone.


And without clamping diode at all it’s roughly 2.5 milliseconds. Which is not that different from 3.5 ms with 12V zener diode.


So as you can see, zener diode in series with ordinary clamping diode significantly speeds up relay release. All relays and solenoids behave the same, but release time will vary.
PICK/HOLD Power Consumption
Once relay is picked it doesn’t need that much current to hold it’s contacts. Usually relay needs only about 50% of pick voltage to hold it’s position. So relay needs higher current only at the beginning to pull contacts from one end to another. For example relay that I was testing earlier has 12VDC coil, but it can be easily pulled-in at 9V and reliably hold it’s contacts at about 4V.
I’m gonna tell you about two solutions to this problem. This solutions can save you battery life in battery-operated devices, or can save you money by selecting power supply with less output current, especially when you need to switch more than one relay simultaneously or some big single relay. In addition to that it will decrease release time, because coil will store less energy.
The first solution is this:



Capacitor in discharged state has very low impedance, it’s almost like a short and it will pass full current needed by relay to pick. Then, as capacitor will fully charge, it will completely stop passing any current, and all the current will flow through the resistor connected in parallel with the capacitor, therefore lowering the relay current consumption.
So, basically, the capacitor provides initial “kick” needed by relay to pull-in, and then current will flow through the resistor.
I made a little experiment with the above relay, powering it from 9VDC with 200Ω resistor in series. That relay has 12VDC 155Ω coil, and it draws about 58mA working from 9V.
When connected in series with 200Ω resistor and still working from 9V this circuit draws only about 25mA instead of 58mA. So the coil works from about 4V, whilst 5V dropping on the resistor. And under 4V the relay holds close pretty reliable (at least for the experiment).
But 4V is not nearly enough to initially pull-in. So I found out that it needs at least 330uF capacitor in parallel with the resistor to work reliably.
As you can see, the results is pretty nice. 58mA @ 9V versus 25mA @ 9V.
But this solution has it’s own downsides – part of energy will dissipate through the resistor in form of heat, so when you have a really big relay, you would need a power resistor; and second one is that you would need a comparatively big capacitor for each relay.
And the second solution allows you to make the same thing, but without any extra parts, by using PWM once relay is picked:



When using microcontroller to switch relay on and off, you often have enough processor time or even hardware capability to generate PWM on one or on multiple MCU outputs.
This will allow you to “chop” relay current consumption without adding any additional parts to the circuit.
So, basically, if PWM would be 50% on and 50% off – then relay will consume only half of the current needed to pull-in. But for switching relay with this method you need to implement simple software algorithm, for example like this one:
1. RELAY_OUTPUT_PWM = 100%
2. DELAY 20ms
3. RELAY_OUTPUT_PWM = 50% (or whatever ratio you want to set)
There is another methods to lower relay power consumption exists, like using two transistors and two different power supply voltages, or using discrete logic and some external clock to make PWM, or even using additional set of contacts(if your relay has any) to implement pick and hold function without capacitor.
That’s it! Here you can download datasheet for BS-901, the relay I was playing with

2011年11月21日星期一

关于线宽与过孔铺铜的一点经验

我先讲讲一点点布线常识(都是我的辛苦积累下来的呀,不是转发的),后面会讲一下实际中遇到的情况,请各位看客耐心看完。
        我们在画PCB时一般都有一个常识,即走大电流的地方用粗线(比如50mil,甚至以上),小电流的信号可以用细线(比如10mil)。对于某些机电控制系统来说,有时候走线里流过的瞬间电流能够达到100A以上,这样的话比较细的线就肯定会出问题。一个基本的经验值是:10A/平方mm,即横截面积为1 平方毫米的走线能安全通过的电流值为10A。如果线宽太细的话,在大电流通过时走线就会烧毁。当然电流烧毁走线也要遵循能量公式:Q=I*I*t,比如对于一个有10A电流的走线来说,突然出现一个100A的电流毛刺,持续时间为us级,那么30mil的导线是肯定能够承受住的。(这时又会出现另外一个问题??导线的杂散电感,这个毛刺将会在这个电感的作用下产生很强的反向电动势,从而有可能损坏其他器件。越细越长的导线杂散电感越大,所以实际中还要综合导线的长度进行考虑)
       一般的PCB绘制软件对器件引脚的过孔焊盘铺铜时往往有几种选项:直角辐条,45度角辐条,直铺。他们有何区别呢?新手往往不太在意,随便选一种,美观就行了。其实不然。主要有两点考虑:一是要考虑不能散热太快,二是要考虑过电流能力。 专业软件下载
        使用直铺的方式特点是焊盘的过电流能力很强,对于大功率回路上的器件引脚一定要使用这种方式。同时它的导热性能也很强,虽然工作起来对器件散热有好处,但是这对于电路板焊接人员却是个难题,因为焊盘散热太快不容易挂锡,常常需要使用更大瓦数的烙铁和更高的焊接温度,降低了生产效率。使用直角辐条和45角辐条会减少引脚与铜箔的接触面积,散热慢,焊起来也就容易多了。所以选择过孔焊盘铺铜的连接方式要根据应用场合,综合过电流能力和散热能力一起考虑,小功率的信号线就不要使用直铺了,而对于通过大电流的焊盘则一定要直铺。至于直角还是45度角就看美观了。
        为什么提起这个来了呢?因为前一阵一直在研究一款电机驱动器,这个驱动器中H桥的器件老是烧毁,四五年了都找不到原因。在我的一番辛苦之后终于发现:原来是功率回路中一处器件的焊盘在铺铜时使用了直角辐条的铺铜方式(而且由于铺铜画的不好,实际只出现了两个辐条)。这使得整个功率回路的过电流能力大打折扣。虽然产品在正常使用过程没有任何问题,工作在10A电流的情况下完全正常。但是,当H桥出现短路时,该回路上会出现100A左右的电流,这两根辐条瞬时就烧断了(uS级)。然后呢,功率回路变成了断路,储藏在电机上的能量没有泻放通道就通过一切可能的途径散发出去,这股能量会烧毁测流电阻及相关的运放器件,击毁桥路控制芯片,并窜入数字电路部分的信号与电源中,造成整个设备的严重损毁。整个过程就像用一根头发丝引爆了一个大地雷一样惊心动魄。那么你可能要问了,为什么在功率回路中的焊盘上只使用了两个辐条呢?为什么不让铜箔直铺过去呢?因为,呵呵,生产部门的人员说那样的话这个引脚太难焊了!设计者正是听了生产人员的话,所以才...唉唉,发现这个问题可着实费了我一番脑筋啊,哪像说起来这么简单!苦乐自知,苦乐自知...

2011年11月20日星期日

Altium Designer PCB 常用功能键

12.PCB设计提高a

方格与格点的切换:View-Grids-Toggle Visible Grid Kind
源点:Edit-Origin-Set
边界的定义:Keep Out Layer-Utility Tools-Place Line 按TAB可定义线宽
选取元件:PCB-PCB Filter-IS Component
逐个放置元件:TOOLS-Component Placement-Reposition Selected Components
自动布局:ToolS-Component Placement--Arrange Within Room
自动布局器:ToolS-Component Placement--Auto Placer
元件排列(居中 居左居右等):选中元件右键Align-
或Alignment Tools--
元件在层之间的快速切换:拖动元件的过程按L键
让焊盘放在格点上:选中元件,右键-Component Actions-Move Component Origin To Grid
移动元件的远近:"G"键 选择mil
刷新屏幕: 键盘"END"
改走线模式(5种):shift+空格键
“45°线性” “45°+圆角” “90°”“ 任意角”“90°+圆弧 ”“圆弧”
遇障碍物:右键-Options-Preferences-...
"Shift+R"3种模式:推挤 等
布线快捷菜单“~ ”键
线宽设置:“Shift+W”

12.PCB设计提高b
交互式布线:

13.PCB设计深入a
板的(螺丝)固定孔,铜柱内孔3.3mm,外孔5.0mm,Layer:Multi-layer;
孔发绿修改规则:Design-Rules-HoleSize;
板边5mm圆弧:Place-KeepOut-Arc

Ctrl+Q 切换英美单位制度;
保护元器件位置:锁定 双击-Lock打钩
保护已锁定物体:Tools-Preference-PCB Editer-General-Protect Locked Objects 打钩;
双层板过孔放置...;

键盘左上角快捷键波浪号“~ ”显示布线快捷菜单;
"+""-"可切换层;
字体(条形码)放置:"A"-Place String;
对板的定义:Designers-Board Shape-R/D;
尺度标注:Place Dimension-Place Linear Dimension

13.PCB设计深入b
工具栏恢复原始状态:在工具栏处右键Customizing PCB Editor-Toolbar-Restore;
圆形板 尺度标注;
填充Place Fill;
复制粘贴:选中-Edit-Rubber Stamp-单击
粘贴特殊形状:选中-Edit-Paste Special(圆形或阵列粘贴)
第一次确定圆心,第二次确定半径;
选择一组Select:“S键”-Touching Liner线/Rectangle矩形
或Shift 一个个选
移动Move:"M"
整体移动:选中-右键-Unions-Create Union from selected object/break
解脱从联合体
弱小信号线包地:选中-“s”select net,Tool-Outline -Selected Objects
查找相似物体:右键-Find Similar Object

PCB

测距离:Report-Measure Distance
自动布线:Auto Route:Net/Net Class/Connection/Area/Room
重要的一点是要先设定好布线规则。
查看布线层:Shift+F或“*”切换层
切断线:Edit-Slice Tracks
布完线进行规则检查:Tools-Design Rule Check-Run D_R_C_
3D视图:数字键“3”或View-Switch to 3D,Shift+右键旋转;
右下角PCB-3D Visualization

13.PCB设计深入c
铺铜Place-Polyon Pour
去死铜:双击铜区,Remove Deader Copper 打钩
注意软件兼容问题 实铜Solid与Hatched在PROERL99SE与DXP 的显示区别
原理图和PCB的双向同步更新:
检测PCB与原理图的不同处:Project-Show Differences
在原理图里更改后更新到PCB:Design-Update PCB Document in
在PCB里更改后更新到原理图:Design-Update Schematics in
标号Designator显示:PCB Filter ISDesignator 然后PCB Inspector Hide
重新标注:Tool- Re Annotate
元器件标号自动排列:选中器件-右键-Align-Position Component Text
补泪滴:Tool-Teardrops,焊盘与导线连接更牢固
生成生产制造文件:File-Fabrication Outputs
生成PDF文件:File-Smart PDF
翻板:View-Flip Board

L打开层
S打开选择
J 跳转
Q 英寸和毫米选择
空格 翻转
选择某物体(导线,过孔等),同时按下Tab键可改变其属性(导线长度,过孔大小等)
选择目标,按住shift拖动

在PCB电气层之间切换(小键盘上的*)。在交互布线的过程中,按此键则换层并自动添加过孔。这很常用。
DXP->preferences 系统设置

其中General--Use localized resources 中文

其中Backup --设置备份时间
树形图标--home
快捷键--右下角help-shortcuts
默认布局--View-Desktop layouts--Default
窗口缩回的速度--DXP->preferences->system->view--Hide delay
打开不同面板--右下角System等等
切换不同窗口--ctrl+tab
放大和缩小---ctrl+鼠标中键滚轴
选取工具栏上的图标,下面状态栏有它对应的一些快捷方式用途
DeSign-Template-Set Template File Name...A4 修改右下方的边框(title,日期)格式

拖动移动时连线跟着自动延长 Drag---ctrl+鼠标拖动
复制目标---选择目标,按住shift拖动
自动添加元件编号---Tools->Annotate Schematics
Preferences-->Schematic-->Graphical Editing Convert Special Strings 转换特殊字符串
原理图出现红色波浪形表示有违法规则的地方(例如两个同名R1)
编译完原理图,查看Message窗口(注意元件库导出隐藏的VCC,GND引脚)
原理图连接处,或添加NEt,会有四个白色方形小点
总线连接
总net 例如:RB[0..7] 每一导线net分别为:RB0,RB1....
如何全局修改
例如:单击电容C1选中,鼠标右键选择Find Similar Objects (Select Matching 选中,二步骤可以跳过
(1) Part Comment ---same Current Footprint ---same ,点击OK按钮
(2) Select ALL
(3) SCH Inspector 窗口 修改 Footprint

Tools-->FootPrint Manager
分层设计
(1)一种水平设置,N个分图 ,net设置全局(project-->project options-->Options...Net Identifier Scope..Gloal) 不推荐
(2)一种垂直设置,一个总图(Sheet Entry),N个分图(PORT) 连接只能Sheet Entry到PORT
第二种方法:
(1)Place sheet Symbol(方框) 和 sheet Entry(放在方框边界内侧)
(2)选择sheet Symbol,右键选择"Sheet symbol actions"--creat sheet from symbol
原理图库
(1) File-->New-->Library-->sch..
(2) 右边下方SCH打开SCH Library 窗口
(3) Place->RecTangle,注意放在原点
(4) Library Components Properties
Designator U?
Comment max232
Symbol Refernece max234
(5) 可将一个元件库分为两个Part,例如parta,partb(通过Tools-->new part)
特殊用途:选择该元件,按F1打开该元件的pdf文档
Library Components Properties-->Parameters for Component -->Add..
Name: HelpURL Value: C:\zy\abc.pdf#page=5
PCB库
(1) File-->New-->Library-->pcb..
(2) 右边下方PCB打开pcb Library 窗口
IPC FootPrint wizard..(比较有用)
画图要焊盘要比datasheet中长1mm
集成库
(1) File-->New-->Project-->Interger Library
(2) 新建sch.lib和pcb.lib, 在sch.lib中选择Tools-->Model Manage....
(3) Project-->Compile Integrated Library
盲孔(BIINDVIA):从印制板内仅延展到一个表层的导通孔。
埋孔(BURIEDVIA):未延伸到印制板表面的一种导通孔。
PCB绘制
(1) 在PCB中 Design-->Import Changes From.....
(2) S+N 选择相同net的线
(3) Design-->Board layers & color-->show/hide polygons hide (将覆铜隐藏) (L快捷键)
(4) 查看PCB元件,通过打开PCB窗口,选择Components
(5) shift+S 单层打开或关闭
(6) 对弱小信号可选择包地处理(Tools-->Outline Selected Object)
(7) Tools-->Design Rule Check...
(8) File-->Fabrication Outputs-->Gerber Files (可直接给这个文件到工厂)
覆铜:
place-->polygon Pour...
1. Pour Over Same Net Polygons Only 相同net铜箔覆盖
2. Pour Over All Same Net Objects 铜箔覆盖相同net部分(将相同net的导线等等融合了)
注意 :如果要保存为PCB4.0 Binary File(*.pcb), 覆铜要选择网格式,(可将网格Track With和Grid Size设置一样,就如同Solid格式了)
如何隐藏所有Designator(即u1,r1,r2....)
(1) PCB filer-->IsDesignator 选择所有Designator
(2) PCB Inspector-->Hide
如何将Designator(即u1,r1,r2....)自动放置在元件附件
(1) PCB filer-->IsComponent
(2) Align-->Position Component Text....
将PCB翻转 查看反面方便 view-->Filp Board
PCB查看层数 Design-->Layer Stack Manager
"类" Design-->class
比如新建一个net class ,把Vc3.3 VC5等加入,然后在rule中选择Net class,这样规则适用范围就是自己定义的类了
按键2--2D 按键3--3D

原理图画线:P+W
PCB图画线: P+T
CTRL+F 在原理图里同快速查找元器件
J+C 在PCB里面快速查的元件

S+N 选择net (ctr+H)
E+E+A 去掉全部选中物体
T+U+C 删除两个焊点间的导线
shift+S 单层打开或关闭
shift+C 去掉过滤
Shift+空格键 在交互布线的过程中,切换布线形状
ctrl+鼠标左键拖动 == 拖动时连线跟着延长
ctrl+鼠标右键 ==PCB选择相同net,并高亮
ctrl+D hide/show层
ctrl+crosspobe ==原理图和PCB快速切换
ctrl+上下箭头 ==分图和总图的切换
ctrl+M ==测量距离
Backspace键 在交互布线(手动布线)的过程中,放弃上一步操作。很常用。

Altium Designer PCB设计常用快捷键

Altium Designer 6.6 PCB设计常用快捷键
1. PCB设计快捷键(单次按键)

单次按键是指按下该键并放开。

1-01 * 在PCB电气层之间切换(小键盘上的*)。在交互布线的

过程中,按此键则换层并自动添加过孔。这很常用。

1-02 Tab键 在交互布线或放置元件、过孔等对象的过程中修改对象属性。

例如改变走线的的宽度,这很常用。

1-03 空格键 在交互布线的过程中,切换布线方向。这很常用。

1-04 Backspace键 在交互布线(手动布线)的过程中,放弃上一步操作。很常用。

1-05 主键盘上的1 在交互布线的过程中,切换布线方法(设定每次单击鼠标布1

段线还是2段线)。

1-06 主键盘上的2 在交互布线的过程中,添加一个过孔,但不换层。

1-07 Q 在公制和英制之间切换。

1-08 Delete 删除已被选择的对象。

2. PCB设计快捷键(组合按键)

组合按键是指,先按住第一个键不放,然后按下第二个键,再放开这两个键。组合键用+号

表示。例如Shift+S表示,先按住Shift键不放,然后按下S键,再放开这两个键。

2-01 Shift+S 切换单层显示和多层显示。

2-02 Shift+空格键 在交互布线的过程中,切换布线形状。

2-03 Shift+C 清除当前过滤器。(当显示一片灰暗时,可恢复正常显示)

2-04 Ctrl+鼠标左键 高亮显示同网络名的对象(鼠标左键必须点到有网络名的对象)

2-05 Ctrl+R 一次复制,并可连续多次粘贴。

2-06 Ctrl+C 复制

2-07 Ctrl+V 粘贴

2-08 Ctrl+S 保存文档。

3. PCB设计快捷键(多次按键)

多次按键是指,先按下第一个键并放开,然后按下第二个键并放开,以此类推。多次按键

用逗号“,”表示。

多次按键有很多,但是完全可以自己找到。在PCB设计状态下,随便按下A~Z中的一个

字母(第一次按键),便弹出一个与该字母相关的快捷菜单,菜单提示中的带下划线的字

母便是第二次按键。

3-01 J,L 定位到指定的坐标的位置。这时要注意确认左下角的坐标值,

如果定位不准,可以放大视图并重新定位,如果还是不准,则

需要修改栅格吸附尺寸。(定位坐标应该为吸附尺寸的整数倍)

3-02 J,C 定位到指定的元件处。在弹出的对话框内输入该元件的编号。

Company Ltd. 第2页 共2页

3-03 R,M 测量任意两点间的距离。

3-04 R,P 测量两个元素之间的距离。

3-05 G,G 设定栅格吸附尺寸。

3-06 O,Y 设置PCB颜色。

3-07 O,B 设置PCB属性。

3-08 O,P 设置PCB相关参数

3-09 O,M 设置PCB层的显示与否。

3-10 D,K 打开PCB层管理器

3-11 E,O,S 设置PCB原点。

3-12 E,F,L 设置PCB元件(封装)的元件参考点。(仅用于PCB元件库)

元件参考点的作用:假设将某元件放置到PCB中,该元件在

PCB中的位置(X、Y坐标)就是该元件的参考点的位置,

当在PCB中放置或移动该元件时,鼠标指针将与元件参考点

对齐。如果在制作元件时元件参考点设置得离元件主体太远,

则在PCB中移动该元件时,鼠标指针也离该元件太远,不利

于操作。一般可以将元件的中心或某个焊盘的中心设置为元件

参考点。

3-13 E,F,C 将PCB元件的中心设置为元件参考点。(仅用于PCB元件库)

元件的中心是指:该元件的所有焊盘围成的几何区域的中心。

3-14 E,F,P 将PCB元件的1号焊盘的中心设置为元件参考点。(仅用于

PCB元件库)


CTRL+F 在原理图里同快速查找元器件

J ,C 在PCB里面快速查的元件

2011年11月18日星期五

Altium Designer快速制作元件原理图

Altium Designer 使用 —— 快速制作原理图封装

当制作引脚数比较多的器件的原理图封装时,可以使用AD提供的“smart grid insert”功能快速制作原理图封装库。

本文以制作K9F1G08为例,进行简单说明。

K9F1G08的引脚分布如图1所示:


1. 打开 excel ,按照图2的格式,将引脚编号和引脚名称全部输入。
注: 第一行的内容是标准格式,直接套用即可。
X1 和Y1 这两列 表示的是引脚在原理图封装库中对应的位置。
由于屏幕比较小,俺只拷贝了其中部分引脚。


选中所有的行和列,按下ctrl & C,拷贝。

2. 进入原理图封装库编辑界面,参考图3,点击下方的SCH工具栏,并选择SCHLIB List


3. SCHLIB List界面栏如图4所示。




注意左上角红框中的mode显示,可能是两种,1为view ,2 为edit;
如果是view, 进入第4步;
如果是edit,直接进入第5步。

4. 参考图4.右键点击下方空白处,选中 switch to edit mode

5. 参考图5,右键点击空白处,选中 smart grid insert

6. 第5步操作完毕,出现图6

7. 在图6中,鼠标左键直接单击 automatically determine paste,再点击OK,弹出画面如图7。

所有引脚都已经成功添加,再画上外框,或者可以根据需要调整引脚的位置,OK!

2011年11月14日星期一

如何在Altium Designer中定义PCB的边界……

软件环境:Altium Designer Summer 09



1)建立PCB文件,选择菜单命令【File】|【New】|【PCB】;

2)定义参考原点,选择菜单命令【Edit】|【Origin】|【Set】;

3)定义物理边界。在PCB中图中选择机械层Mechanical1,然后选择菜单命令【Place】|【Line】,在PCB图中定义一个500mil*500mil的物理边界;

4)定义电气边界。在PCB图中选择电气隔离层Keep-Out Layer,然后选择菜单命令【Place】|【Line】,在PCB图中定义一个500mil*500mil的电气边界;

注意:在执行以上两步时,建议定义边界时建议首先画四根独立的线,然后【双击】每一根线,通过坐标的方式设定每一根线的位置和长度,因为这样更精确;定义500mil*500mil的边界的四根线的的坐标分别是:【(0,0)和(0,500)】,【(0,500)和(500,500)】,【(500,500)和(500,0)】,【(500,0)和(0,0)】;

5)定义PCB板形状。选择【Design】|【Board shape】|【Redefine Board shape】命令,然后沿物理边界定义出PCB的形状。

注意:在这一步时,将PCB的分辨率放的很大很大绘制比较方便,可能初次操作有些不便,如果首次不成功,重新执行即可。

电气边界的作用是将所有的焊盘、过孔和线条限定在适当的范围之内。电气边界的范围不能大于物理边界,一般将电气边界的大小设置的和物理边界相同。

以上主要参考了三恒星科技编著的《Altium Designer 6.0易学通》,人民邮电出版社,第21页……

2011年11月11日星期五

Create an Online Survey/Questionnaire With Google Docs

From: http://www.amisampath.com/2009/11/how-to-create-online.html
I have been using Google Docs for quite a sometime now to solve a nasty problem most of us will have to face very often. The problem is how to access that last word document you saved from your home PC, when you are at office or working with a computer in some other place. On the other hand, when you are at a library referring some books, but not having access to your own computer to note down some of the important extracts into a word document, Google Docs might be a handy solution if you have access to a public computer in the library.

The aim of this post is not to talk much about the uses of Google Docs (which expands much beyond the few uses I’ve mentioned above), but to describe how to use Google Docs as a survey tool to collect responses for a research project or for a customer survey for a business organization.

For last few years, sites like Surveymonkey and SurveyGizmo used to serve this need for many researchers but a secret most of these people didn’t know is that, Google Docs comes with an inbuilt feature of creating professional looking online surveys just like Surveymonkey and SurveyGizmo. Most important thing is, it comes to you 100% free to collect unlimited responses, where as most of the traditional survey tools limit it to 100 or 500 responses for the free versions. You can easily create your questionnaire as a Google form and share a web link (URL) through email to get responses from your target respondents. If you have a website, you can easily embed the questionnaire into one of your web pages to give it a more professional look and feel.

2011年11月7日星期一

有三视的照片 照描立体图



如上图

ProE里叫 Trace Sketch(跟踪草绘)

YouTube教学视频:

2011年10月29日星期六

字符串数组怎么赋值

比如:
>> a(1)='bob';
a(2))='ryan';
a(3)='richard';
??? Subscripted assignment dimension mismatch.
需要怎么写?

Answer1:
a{1}='bob'
a{2}='ryan'
a{3}='richard'


Answer2:
a(1,:)='bob ';
a(2,:)='ryan ';
a(3,:)='richard';
%注意:后面或者前面加空格,使每个字符串的长度相等


Answer3:
a(1,1:length('bob'))='bob';
a(2,1:length('ryan'))='ryan ';
a(3,1:length('richard'))='richard';
最后数组a的列数以最长为准,自动补充空格。

2011年10月24日星期一

如何炒出嫩牛肉

【如何炒出嫩牛肉】首先切牛肉时依横断面切薄片。用白糖腌10分钟后,加少许水搅拌,再加入酱油、盐、味精、料酒、姜片、生粉抓匀,腌15分钟。再加一小勺生油拌匀。最后下油适量,趁油未热放入牛肉旺火翻炒。烧至六成熟时,把火关小,加盖焖至熟透。这样炒出的牛肉既鲜美又嫩滑。

早上5点

快一年没写东西了,妈的,近1个月了,晚上基本上睡不着,早上基本上起不来。
现在是5点。。。唉。。

2011年10月23日星期日

Altium Designer 批量修改属性

用Altium Designer 画PCB,想修改所有电源线宽。摸索了一下,可以用以下两种方法实现,都很简单。

1.选取一根电源线,右键,Find Similar Objects(快捷键Shift+F),弹出对话框是让你设置筛选条件,比如说我们要选择所有的标号为VDD的导线,就在Net选项中选择Same,其他为Any(默认),然后把线宽改为相同宽度,Apply下,ok。

2.利用PCB Filter和PCB Inspector。PCB Filter,可以利用表达式选取你所需条件的任何器件;打开PCB Inspector,在条件中输入:InNet('VDD3.3V') and IsTrack (Net标号是你要修改的),然后Apply,这时在PCB中就可以看到所有标号为VDD3.3V的导线都被选中,然后打开PCB Inspector修改线宽,Apply,ok。

两种方法原理是一样的,都是设法批量选取之后在修改属性;后者的功能更强大,前者是后者的一种快捷操作方式。

2011年10月13日星期四

polyfit 曲线拟合

polyfit函数是matlab中用于进行曲线拟合的一个函数。曲线拟合:已知离散点上的数据集,即已知在点集上的函数值,构造一个解析函数(其图形为一曲线)使在原离散点上尽可能接近给定的值。
  解释1
  用法 polyfit(x,y,n ) ;用多项式求过已知点的表达式,其中x为源数据点对应的横坐标,可为 行向量、矩阵,y为源数据点对应的纵坐标,可为 行向量、矩阵,n为你要拟合的阶数,一阶直线拟合,二阶抛物线拟合,并非阶次越高越好,看拟合情况
  matlab polyfit 做出来的值从左到右表示从高次到低次的多项式系数
  给个例子一看就知道了
  x = (0: 0.1: 2.5)';
  y = erf(x);
  p = polyfit(x,y,6)
  p =
  0.0084 -0.0983 0.4217 -0.7435 0.1471 1.1064 0.0004
  则y=0.0084x^6-0.0983x^5+0.4217x^4-0.7435x^3+0.1471x^2+1.1064x+0.0004
  解释2:
  MATLAB软件提供了基本的曲线拟合函数的命令.
  多项式函数拟合:a=polyfit(xdata,ydata,n)
  其中n表示多项式的最高阶数,xdata,ydata为将要拟合的数据,它是用数组的方式输入.输出参数a为拟合多项式 y=a1xn+...+anx+a n+1的系数
  多项式在x处的值y可用下面程序计算.
  y=polyval(a,x,m)
  线性:m=1, 二次:m=2, …
  polyfit的输出是一个多项式系数的行向量。为了计算在xi数据点的多项式值,调用MATLAB的函数polyval。
  例:
  x=0:0.1:1; y=[-0.447 1.978 3.28 6.16 7.08 7.34 7.66 9.56 9.48 9.30 11.2]; polyfit用法示例结果A=polyfit(x,y,2)
  z=polyval(A,x);
  plot(x,y,'r*',x,z,'b')
释疑:
  在不少书中和论坛上,polyfit被误写作“ployfit”,使得很多初学者误解,认为自己安装的MATLAB软件出错,无法找到这样的函数。只要注意拼写正确即可。同样地,polyval函数也易被误写为“ployval”。

2011年10月12日星期三

App2SD和App2SD+简介

From:http://my.oschina.net/lintur/blog/10165
下面介绍如何开启App2SD和App2SD+:
先介绍App2SD,然后再详细介绍App2SD+。

开启和关闭2.2系统自带的App2SD
在电脑上用输入下面的命令来开启或者关闭App2SD:

adb shell pm setInstallLocation 0
adb shell pm setInstallLocation 1
adb shell pm setInstallLocation 2
注释:

0 代表自动(这个是默认值,如果你曾经开启过App2SD,想关闭的话,通过adb shell pm setInstallLocation 0就可以关闭App2SD功能了)
1 代表手机存储
2 代表SD卡。
也可以通过adb shell pm getInstallLocation 来获取当前的设置。

2011年10月9日星期日

VS 2008 OpenGL 配置

最近准备学习OpenGL,结果发现敲入书中给的代码,居然提示头文件找不到,相当郁闷,查了一下才发现有些不是VC自带的,需要自己下载安装,以下为转帖,感觉说的还算详细,OpenGl大牛们,就略过此文好了,呵呵

OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性。
1、与C语言紧密结合。
OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的。如果你曾经接触过TC的graphics.h,你会发现,使用OpenGL作图甚至比TC更加简单。
2、强大的可移植性。
微软的Direct3D虽然也是十分优秀的图形API,但它只用于Windows系统(现在还要加上一个XBOX游戏机)。而OpenGL不仅用于 Windows,还可以用于Unix/Linux等其它系统,它甚至在大型计算机、各种专业计算机(如:医疗用显示设备)上都有应用。并且,OpenGL 的基本命令都做到了硬件无关,甚至是平台无关。
3、高性能的图形渲染。
OpenGL是一个工业标准,它的技术紧跟时代,现今各个显卡厂家无一不对OpenGL提供强力支持,激烈的竞争中使得OpenGL性能一直领先。
总之,OpenGL是一个很NB的图形软件接口。至于究竟有多NB,去看看DOOM3和QUAKE4等专业游戏就知道了。
OpenGL官方网站(英文)

http://www.opengl.org/

下面将对Windows下的OpenGL编程进行简单介绍。

学习OpenGL前的准备工作
第一步,选择一个编译环境
现在Windows系统的主流编译环境有Visual Studio,Broland C++ Builder,Dev-C++等,它们都是支持OpenGL的。
我选择Visual Studio 2008和VC6++作为学习OpenGL的环境。
第二步,安装GLUT工具包
GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。
Windows环境下的GLUT下载地址:(大小约为150k)
http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip

无法从以上地址下载的话请使用下面的连接:

http://upload.programfan.com/upfile/200607311626279.zip
Windows环境下安装GLUT的步骤:
1、将下载的压缩包解开,将得到5个文件
2、在“我的电脑”中搜索“gl.h”,并找到其所在文件夹

如果是VC++6,则应该将glut.h复制在“D:\Program Files\MicrosoftVisualStudio\VC98 \Include\GL文件夹”)。 如果是VisualStudio2008,把glut.h复制到x:\Program Files\Microsoft\Visual Studio 9.0\VC\include\GL文件夹中,如果没有GL这个文件夹则可以自己新建一个。(x是你安装VS的盘符号,如果装的是VC++的话,里面有个gl文件,Visual Studio 2008则需要自己去新建一个)
3、把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(即与include并排的lib文件夹下)。
4、把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)
第三步,建立一个OpenGL工程
无论VisualStudio2008还是VC++6:
选择File->New->Project,然后选择Win32 Console Application,(不是win32 application).选择一个名字,然后按OK。在谈出的对话框左边点Application Settings,找到Empty project并勾上,选择Finish。然后向该工程添加一个代码文件,取名为“OpenGL.c”,注意用.c来作为文件结尾。
搞定了,就跟平时的工程没什么两样的。

注意: 包含头文件:

#include
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glut32.lib")

第一个OpenGL程序

一个简单的OpenGL程序如下:(注意,如果需要编译并运行,需要正确安装GLUT,安装方法如上所述)

#include
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("第一个OpenGL程序");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}

该程序的作用是在一个黑色的窗口中央画一个白色的矩形。下面对各行语句进行说明。


首先,需要包含头文件#include ,这是GLUT的头文件。
本来OpenGL程序一般还要包含,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含。


然后看main函数。
int main(int argc, char *argv[]),这个是带命令行参数的main函数,各位应该见过吧?没见过的同志们请多翻翻书,等弄明白了再往下看。
注意main函数中的各语句,除了最后的return之外,其余全部以glut开头。这种以glut开头的函数都是GLUT工具包所提供的函数,下面对用到的几个函数进行介绍。
1、glutInit,对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
2、 glutInitDisplayMode,设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。更多信息,请自己Google。当然以后的教程也会有一些讲解。
3、glutInitWindowPosition,这个简单,设置窗口在屏幕中的位置。
4、glutInitWindowSize,这个也简单,设置窗口的大小。
5、glutCreateWindow,根据前面设置的信息创建窗口。参数将被作为窗口的标题。注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口。
6、glutDisplayFunc,设置一个函数,当需要进行画图时,这个函数就会被调用。(这个说法不够准确,但准确的说法可能初学者不太好理解,暂时这样说吧)。
7、glutMainLoop,进行一个消息循环。(这个可能初学者也不太明白,现在只需要知道这个函数可以显示窗口,并且等待窗口关闭后才会返回,这就足够了。)

在glutDisplayFunc函数中,我们设置了“当需要画图时,请调用myDisplay函数”。于是myDisplay函数就用来画图。观察myDisplay中的三个函数调用,发现它们都以gl开头。这种以gl开头的函数都是OpenGL的标准函数,下面对用到的函数进行介绍。
1、glClear,清除。GL_COLOR_BUFFER_BIT表示清除颜色,glClear函数还可以清除其它的东西,但这里不作介绍。
2、glRectf,画一个矩形。四个参数分别表示了位于对角线上的两个点的横、纵坐标。
3、glFlush,保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)。其作用跟fflush(stdout)类似

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Ididcan/archive/2009/08/27/4490797.aspx

2011年10月7日星期五

C语言关于取余数 %

C语言关于取余数



任何的整数取20的余数都是在0-19之间
不然还可以商啊
小于20的数字取20的余数就是它本身咯
商0 嘛
余自己啊
大于20的数字取20的余数就在0-19之间


20/9
商2
余2
这就是商的概念

12年前的小学学的

2011年10月5日星期三

公式编号:有些编有些不编

begin{eqaution*}
begin{split} 等

\notag

LaTeX技巧404:双栏文章中如何跨两栏写长公式(通栏公式)

第一种方法:这是从IEEE摘选出来的输入方式,但是这个方式会使得公式移动到下一页浮动置顶。
\newcounter{mytempeqncnt}
\begin{figure*}[!t]
% ensure that we have normalsize text
\normalsize
% Store the current equation number.
\setcounter{mytempeqncnt}{\value{equation}}
% Set the equation number to one less than the one
% desired for the first equation here.
% The value here will have to changed if equations
% are added or removed prior to the place these
% equations are referenced in the main text.
\setcounter{equation}{5}
\begin{equation}
\label{eqn_dbl_x}
x = 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21+ 23 + 25
+ 27 + 29 + 31
\end{equation}
\begin{equation}
\label{eqn_dbl_y}
y = 4 + 6 + 8 + 10 + 12 + 14 + 16 + 18 + 20+ 22 + 24
+ 26 + 28 + 30
\end{equation}
% Restore the current equation number.
\setcounter{equation}{\value{mytempeqncnt}}
% IEEE uses as a separator
\hrulefill
% The spacer can be tweaked to stop underfull vboxes.
\vspace*{4pt}
\end{figure*}
第二种方法:使用multicol来实现,这个方法较为贴近我们平时的习惯。
\begin{multicols}{2}
Bla bla...
\end{multicols}
%
\begin{equation}
very long equation
\end{equation}
%
\begin{multicols}{2}
Bla bla...
\end{multicols}
有时,我们看到一些论文有如下的显示方式,LaTeX里如何实现呢?



实现代码如下:
\newlength{\halfpagewidth}
\setlength{\halfpagewidth}{\linewidth}
\divide\halfpagewidth by 2
\newcommand{\leftsep}{%
\noindent\raisebox{4mm}[0ex][0ex]{%
\makebox[\halfpagewidth]{\hrulefill}\hbox{\vrule height 3pt}}%
\vspace*{-2mm}%
}
\newcommand{\rightsep}{%
\noindent\hspace*{\halfpagewidth}%
\rlap{\raisebox{-3pt}[0ex][0ex]{\hbox{\vrule height 3pt}}}%
\makebox[\halfpagewidth]{\hrulefill}%
}

使用方法:
\begin{multicols}{2}
Bla bla...
\end{multicols}
%
\leftsep
\begin{equation}
\label{eqn:planar:Hz02}
\left \{\begin{array}{l}
\delta A + \kappa B = 0 \\
(\kappa\sin\kappa d - \gamma\cos\kappa d)A + (\kappa\cos\kappa d + \gamma\sin\kappa d)B = 0
\end{array} \right.
\end{equation}
\rightsep
%
\begin{multicols}{2}
Bla bla...
\end{multicols}

以上几个方法,供大家参考使用。若是你有更好地办法,可以留言,或者发送至latestudio@hotmail.com

2011年10月4日星期二

Android 手机铃声

【Android小知识】很多人常问我安卓手机铃声放哪里?答:在SD卡上建一个名为ringtones的文件夹,铃声放进去,系统可自动识别!是不是很简单呢!

jpg转eps

用bmeps命令


bmeps 默认是黑白,加上 -c 选项就是彩色的了。

latex里如何在双列文章里加入平行的横跨两列的图

跨行的图需要用 \begin{figure*}\end{figure*}

latex里如何在双列文章里加入平行的横跨两列的图

跨行的图需要用 \begin{figure*}\end{figure*}

2011年10月1日星期六

关于AVR的ISP

注意手冊,一定要注意手冊!!!!

大部分AVR芯片的ISP端口是 SCK,MOSI,MISO,RESET
而Atmega64/Atmega128的ISP端口是 SCK, PDI, PDO,RESET

2011年9月16日星期五

Standard Macros

From:http://developer.gnome.org/glib/2.29/glib-Standard-Macros.html#G-STRUCT-MEMBER-P:CAPS

Standard Macros
Standard Macros — commonly-used macros.

Synopsis
#include

#define G_OS_WIN32
#define G_OS_BEOS
#define G_OS_UNIX

#define G_DIR_SEPARATOR
#define G_DIR_SEPARATOR_S
#define G_IS_DIR_SEPARATOR (c)
#define G_SEARCHPATH_SEPARATOR
#define G_SEARCHPATH_SEPARATOR_S

#define TRUE
#define FALSE

#define NULL

#define MIN (a,
b)
#define MAX (a,
b)

#define ABS (a)
#define CLAMP (x,
low,
high)

#define G_STRUCT_MEMBER (member_type,
struct_p,
struct_offset)
#define G_STRUCT_MEMBER_P (struct_p,
struct_offset)
#define G_STRUCT_OFFSET (struct_type,
member)

#define G_MEM_ALIGN

#define G_CONST_RETURN
Description
These macros provide a few commonly-used features.

Details
G_OS_WIN32
#define G_OS_WIN32
This macro is defined only on Windows. So you can bracket Windows-specific code in "#ifdef G_OS_WIN32".

G_OS_BEOS
#define G_OS_BEOS
This macro is defined only on BeOS. So you can bracket BeOS-specific code in "#ifdef G_OS_BEOS".

G_OS_UNIX
#define G_OS_UNIX
This macro is defined only on UNIX. So you can bracket UNIX-specific code in "#ifdef G_OS_UNIX".

G_DIR_SEPARATOR
#define G_DIR_SEPARATOR '\\'
The directory separator character. This is '/' on UNIX machines and '\' under Windows.

G_DIR_SEPARATOR_S
#define G_DIR_SEPARATOR_S "\\"
The directory separator as a string. This is "/" on UNIX machines and "\" under Windows.

G_IS_DIR_SEPARATOR()
#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/')
Checks whether a character is a directory separator. It returns TRUE for '/' on UNIX machines and for '\' or '/' under Windows.

c :
a character
Since 2.6

G_SEARCHPATH_SEPARATOR
#define G_SEARCHPATH_SEPARATOR ';'
The search path separator character. This is ':' on UNIX machines and ';' under Windows.

G_SEARCHPATH_SEPARATOR_S
#define G_SEARCHPATH_SEPARATOR_S ";"
The search path separator as a string. This is ":" on UNIX machines and ";" under Windows.

TRUE
#define TRUE (!FALSE)
Defines the TRUE value for the gboolean type.

FALSE
#define FALSE (0)
Defines the FALSE value for the gboolean type.

NULL
# define NULL (0L)
Defines the standard NULL pointer.

MIN()
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) Calculates the minimum of a and b. a : a numeric value. b : a numeric value. Returns : the minimum of a and b. MAX() #define MAX(a, b) (((a) > (b)) ? (a) : (b))
Calculates the maximum of a and b.

a :
a numeric value.
b :
a numeric value.
Returns :
the maximum of a and b.
ABS()
#define ABS(a) (((a) < 0) ? -(a) : (a)) Calculates the absolute value of a. The absolute value is simply the number with any negative sign taken away. For example, ABS(-10) is 10. ABS(10) is also 10. a : a numeric value. Returns : the absolute value of a. CLAMP() #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
Ensures that x is between the limits set by low and high. If low is greater than high the result is undefined.

For example,

CLAMP(5, 10, 15) is 10.

CLAMP(15, 5, 10) is 10.

CLAMP(20, 15, 25) is 20.

x :
the value to clamp.
low :
the minimum value allowed.
high :
the maximum value allowed.
Returns :
the value of x clamped to the range between low and high.
G_STRUCT_MEMBER()
#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset)
Returns a member of a structure at a given offset, using the given type.

member_type :
the type of the struct field.
struct_p :
a pointer to a struct.
struct_offset :
the offset of the field from the start of the struct, in bytes.
Returns :
the struct member.
G_STRUCT_MEMBER_P()
#define G_STRUCT_MEMBER_P(struct_p, struct_offset)
Returns an untyped pointer to a given offset of a struct.

struct_p :
a pointer to a struct.
struct_offset :
the offset from the start of the struct, in bytes.
Returns :
an untyped pointer to struct_p plus struct_offset bytes.
G_STRUCT_OFFSET()
#define G_STRUCT_OFFSET(struct_type, member)
Returns the offset, in bytes, of a member of a struct.

struct_type :
a structure type, e.g. GtkWidget.
member :
a field in the structure, e.g. window.
Returns :
the offset of member from the start of struct_type.
G_MEM_ALIGN
# define G_MEM_ALIGN GLIB_SIZEOF_VOID_P
Indicates the number of bytes to which memory will be aligned on the current platform.

G_CONST_RETURN
#define G_CONST_RETURN
Warning
G_CONST_RETURN has been deprecated since version 2.30 and should not be used in newly-written code. API providers should replace all existing uses with const and API consumers should adjust their code accordingly.

If G_DISABLE_CONST_RETURNS is defined, this macro expands to nothing. By default, the macro expands to const. The macro should be used in place of const for functions that return a value that should not be modified. The purpose of this macro is to allow us to turn on const for returned constant strings by default, while allowing programmers who find that annoying to turn it off. This macro should only be used for return values and for out parameters, it doesn't make sense for in parameters.

Generated by GTK-Doc V1.17

2011年9月15日星期四

#define用法集锦

Definition:
The #define Directive
  You can use the #define directive to give a meaningful name to a constant in your program. The two forms of the syntax are:
  Syntax
  #define identifier token-stringopt
  #define identifier[( identifieropt, ... , identifieropt )] token-stringopt

Usage:

1. 简单的define定义
#define MAXTIME 1000
一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写
if(i编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。
这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。
2.define的“函数定义”
define可以像函数那样接受一些参数,如下
#define max(x,y) (x)>(y)?(x):(y);
这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。
但是这样做的话存在隐患,例子如下:
#define Add(a,b) a+b;
在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了
c*a + b*d
另外举一个例子:
#define pin (int*);
pin a,b;
本意是a和b都是int型指针,但是实际上变成int* a,b;
a是int型指针,而b是int型变量。
这是应该使用typedef来代替define,这样a和b就都是int型指针了。
所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。
3.宏的单行定义(少见用法)
#define A(x) T_##x
#define B(x) #@x
#define C(x) #x
我们假设:x=1,则有:
A(1)------〉T_1
B(1)------〉'1'
C(1)------〉"1"
(这里参考了 hustli的文章)
3.define的多行定义
define可以替代多行的代码,例如MFC中的宏定义(非常的经典,虽然让人看了恶心)
#define MACRO(arg1, arg2) do { \
/* declarations */ \
stmt1; \
stmt2; \
/* ... */ \
} while(0) /* (no trailing ; ) */
关键是要在每一个换行的时候加上一个"\"
4.在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。
就是:
#ifdef WINDOWS
......
......
#endif
#ifdef LINUX
......
......
#endif
可以在编译的时候通过#define设置编译环境
5.如何定义宏、取消宏
//定义宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName]
//普通宏
#define PI (3.1415926)
带参数的宏
#define max(a,b) ((a)>(b)? (a),(b))
关键是十分容易产生错误,包括机器和人理解上的差异等等。
6.条件编译
#ifdef XXX…(#else) … #endif
例如
#ifdef DV22_AUX_INPUT
#define AUX_MODE 3
#else
#define AUY_MODE 3
#endif
#ifndef XXX … (#else) … #endif
7.头文件(.h)可以被头文件或C文件包含;
重复包含(重复定义)
由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。
通过条件编译开关来避免重复包含(重复定义)
例如
#ifndef __headerfileXXX__
#define __headerfileXXX__

//文件内容

#endif


Instances:

1、防止一个头文件被重复包含
#ifndef COMDEF_H
#define COMDEF_H
//头文件内容
#endif
2、重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
typedef unsigned char boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned 32 bit value */
typedef unsigned short uint16; /* Unsigned 16 bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
typedef signed long int int32; /* Signed 32 bit value */
typedef signed short int16; /* Signed 16 bit value */
typedef signed char int8; /* Signed 8 bit value */
//下面的不建议使用
typedef unsigned char byte; /* Unsigned 8 bit value type. */
typedef unsigned short word; /* Unsinged 16 bit value type. */
typedef unsigned long dword; /* Unsigned 32 bit value type. */
typedef unsigned char uint1; /* Unsigned 8 bit value type. */
typedef unsigned short uint2; /* Unsigned 16 bit value type. */
typedef unsigned long uint4; /* Unsigned 32 bit value type. */
typedef signed char int1; /* Signed 8 bit value type. */
typedef signed short int2; /* Signed 16 bit value type. */
typedef long int int4; /* Signed 32 bit value type. */
typedef signed long sint31; /* Signed 32 bit value */
typedef signed short sint15; /* Signed 16 bit value */
typedef signed char sint7; /* Signed 8 bit value */
3、得到指定地址上的一个字节或字
#define MEM_B( x ) ( *( (byte *) (x) ) )
#define MEM_W( x ) ( *( (word *) (x) ) )
4、求最大值和最小值
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
5、得到一个field在结构体(struct)中的偏移量
#define FPOS( type, field ) \
/*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */
6、得到一个结构体中field所占用的字节数
#define FSIZ( type, field ) sizeof( ((type *) 0)->field )
7、按照LSB格式把两个字节转化为一个Word
#define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )
8、按照LSB格式把一个Word转化为两个字节
#define FLOPW( ray, val ) \
(ray)[0] = ((val) / 256); \
(ray)[1] = ((val) & 0xFF)
9、得到一个变量的地址(word宽度)
#define B_PTR( var ) ( (byte *) (void *) &(var) )
#define W_PTR( var ) ( (word *) (void *) &(var) )
10、得到一个字的高位和低位字节
#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
11、返回一个比X大的最接近的8的倍数
#define RND8( x ) ((((x) + 7) / 8 ) * 8 )
12、将一个字母转换为大写
#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )
13、判断字符是不是10进值的数字
#define DECCHK( c ) ((c) >= '0' && (c) <= '9')
14、判断字符是不是16进值的数字
#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
((c) >= 'A' && (c) <= 'F') ||\
((c) >= 'a' && (c) <= 'f') )
15、防止溢出的一个方法
#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
16、返回数组元素的个数
#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
17、返回一个无符号数n尾的值MOD_BY_POWER_OF_TWO(X,n)=X%(2^n)
#define MOD_BY_POWER_OF_TWO( val, mod_by ) \
( (dword)(val) & (dword)((mod_by)-1) )
18、对于IO空间映射在存储空间的结构,输入输出处理
#define inp(port) (*((volatile byte *) (port)))
#define inpw(port) (*((volatile word *) (port)))
#define inpdw(port) (*((volatile dword *)(port)))
#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))
#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))
#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))
19、使用一些宏跟踪调试
ANSI标准说明了五个预定义的宏名。它们是:
__LINE__
__FILE__
__DATE__
__TIME__
__STDC__
C++中还定义了 __cplusplus
如果编译器不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
__LINE__ 及 __FILE__ 宏指示,#line指令可以改变它的值,简单的讲,编译时,它们包含程序的当前行数和文件名。
__DATE__ 宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
__TIME__ 宏指令包含程序编译的时间。时间用字符串表示,其形式为:分:秒
__STDC__ 宏指令的意义是编译时定义的。一般来讲,如果__STDC__已经定义,编译器将仅接受不包含任何非标准扩展的标准C/C++代码。如果实现是标准的,则宏__STDC__含有十进制常量1。如果它含有任何其它数,则实现是非标准的。
__cplusplus 与标准c++一致的编译器把它定义为一个包含至少6为的数值。与标准c++不一致的编译器将使用具有5位或更少的数值。
可以定义宏,例如:
当定义了_DEBUG,输出数据信息和所在文件所在行
#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
#else
#define DEBUGMSG(msg,date)
#endif

20、宏定义防止错误使用小括号包含。
例如:
有问题的定义:#define DUMP_WRITE(addr,nr) {memcpy(bufp,addr,nr); bufp += nr;}
应该使用的定义: #difne DO(a,b) do{a+b;a++;}while(0)
例如:
if(addr)
DUMP_WRITE(addr,nr);
else
do_somethong_else();
宏展开以后变成这样:
if(addr)
{memcpy(bufp,addr,nr); bufp += nr;};
else
do_something_else();
gcc在碰到else前面的“;”时就认为if语句已经结束,因而后面的else不在if语句中。而采用do{} while(0)的定义,在任何情况下都没有问题。而改为 #difne DO(a,b) do{a+b;a++;}while(0) 的定义则在任何情况下都不会出错

21. define中的特殊标识符
#define Conn(x,y) x##y
#define ToChar(x) #@x
#define ToString(x) #x

int a=Conn(12,34);
char b=ToChar(a);
char c[]=ToString(a);
结果是 a=1234,c='a',c='1234';
可以看出 ## 是简单的连接符,#@用来给参数加单引号,#用来给参数加双引号即转成字符串

2011年9月6日星期二

符号长整数 UL

那不加“UL”与加“UL”有什么区别?符号区别?
为什么宏定义中有的加了UL,有的却不加?
加了UL就不进行类型检查,直接以UL的形式把值赋给某个对应的内存,如果超出定义变量的范围,则截取。

2011年9月3日星期六

字节顺序:大端字节(big-endian)和小端字节(little-endian)

转自:http://www.sf.org.cn/Article/base/200606/18679.html

作者:suyouxin 文章来源:csdn blog 更新时间:2006-6-24 22:20:32

今天碰一个关于字节顺序的问题,虽然看起来很简单,但一直都没怎么完全明白这个东西,索性就找了下资料,把它弄清楚.
因为现行的计算机都是以八位一个字节为存储单位,那么一个16位的整数,也就是C语言中的short,在内存中可能有两种存储顺序big-endian和litte-endian.考虑一个short整数0x3132(0x32是低位,0x31是高位),把它赋值给一个short变量,那么它在内存中的存储可能有如下两种情况:
大端字节(Big-endian):
----------------->>>>>>>>内存地址增大方向
short变量地址
0x1000 0x1001
_____________________________
| |
| 0x31 | 0x32
|________________ | ________________
高位字节在低位字节的前面,也就是高位在内存地址低的一端.可以这样记住(大端->高位->在前->正常的逻辑顺序)

小端字节(little-endian):
----------------->>>>>>>>内存地址增大方向
short变量地址
0x1000 0x1001
_____________________________
| |
| 0x32 | 0x31
|________________ | ________________
低位字节在高位字节的前面,也就是低位在内存地址低的一端.可以这样记住(小端->低位->在前->与正常逻辑顺序相反)

可以做个实验
在windows上下如下程序
#include
#include

void main( void )
{
short test;
FILE* fp;

test = 0x3132; //(31ASIIC码的’1’,32ASIIC码的’2’)
if ((fp = fopen ("c:\\test.txt", "wb")) == NULL)
assert(0);
fwrite(&test, sizeof(short), 1, fp);
fclose(fp);
}
然后在C盘下打开test.txt文件,可以看见内容是21,而test等于0x3132,可以明显的看出来x86的字节顺序是低位在前.如果我们把这段同样的代码放到(big-endian)的机器上执行,那么打出来的文件就是12.这在本机中使用是没有问题的.但当你把这个文件从一个big-endian机器复制到一个little-endian机器上时就出现问题了.
如上述例子,我们在big-endian的机器上创建了这个test文件,把其复制到little-endian的机器上再用fread读到一个short里面,我们得到的就不再是0x3132而是0x3231了,这样读到的数据就是错误的,所以在两个字节顺序不一样的机器上传输数据时需要特别小心字节顺序,理解了字节顺序在可以帮助我们写出移植行更高的代码.
正因为有字节顺序的差别,所以在网络传输的时候定义了所有字节顺序相关的数据都使用big-endian,BSD的代码中定义了四个宏来处理:
#define ntohs(n) //网络字节顺序到主机字节顺序 n代表net, h代表host, s代表short
#define htons(n) //主机字节顺序到网络字节顺序 n代表net, h代表host, s代表short
#define ntohl(n) //网络字节顺序到主机字节顺序 n代表net, h代表host, s代表 long
#define htonl(n) //主机字节顺序到网络字节顺序 n代表net, h代表host, s代表 long

举例说明下这其中一个宏的实现:
#define sw16(x) \
((short)( \
(((short)(x) & (short)0x00ffU) << 8) | \
(((short)(x) & (short)0xff00U) >> 8) ))
这里实现的是一个交换两个字节顺序.其他几个宏类似.

我们改写一下上面的程序
#include
#include

#define sw16(x) \
((short)( \
(((short)(x) & (short)0x00ffU) << 8) | \
(((short)(x) & (short)0xff00U) >> 8) ))

// 因为x86下面是低位在前,需要交换一下变成网络字节顺序
#define htons(x) sw16(x)

void main( void )
{
short test;
FILE* fp;

test = htons(0x3132); //(31ASIIC码的’1’,32ASIIC码的’2’)
if ((fp = fopen ("c:\\test.txt", "wb")) == NULL)
assert(0);
fwrite(&test, sizeof(short), 1, fp);
fclose(fp);
}

如果在高字节在前的机器上,由于与网络字节顺序一致,所以我们什么都不干就可以了,只需要把#define htons(x) sw16(x)宏替换为 #define htons(x) (x).
一开始我在理解这个问题时,总在想为什么其他数据不用交换字节顺序?比如说我们write一块buffer到文件,最后终于想明白了,因为都是unsigned char类型一个字节一个字节的写进去,这个顺序是固定的,不存在字节顺序的问题,够笨啊..

2011年9月1日星期四

vc设置程序置顶

//设置对话框置顶,在OnInitDialog()函数或者其它的函数中响应。
SetWindowPos(&wndTopMost,10,1000,10,1000,SWP_NOMOVE|SWP_NOSIZE);

//设置SDI和MDI程序置顶,在OnMenuTop()虚函数中
::SetWindowPos(AfxGetMainWnd()->m_hWnd,HWND_ TopMost, 10,1000,10,1000,SWP_NOMOVE|SWP_NOSIZE);

利用WM_CTLCOLOR消息实现编辑控制(Edit Control)的文本与背景色的改变

首先要明白:WM_CTLCOLOR是一个由控制(Control)发送给它父窗口的通知消息(Notification message)。

实现步骤:
生成一个标准的单文档应用程序框架,假设应用程序的名称为Color。我将利用它的About对话框做示范。在About dialog中添加两个Edit control,设定其ID为IDC_EDIT1与IDC_EDIT2。

第一种方法(对应于IDC_EDIT1): 按照标准的Windows编程,由其父窗口的消息处理函数负责处理WM_CTLCOLOR消息。

1. 在CAboutDlg中添加一个数据成员:HBRUSH m_brMine;
2. 利用向导映射AboutDlg的WM_CTLCOLOR消息,产生函数:HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
pDC是AboutDlg的设备上下文,pWnd是AboutDlg中发送该消息的control指针,nCtlColor市Control的类型编码。对其进行如下修改:

HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if ((pWnd->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))
{
COLORREF clr = RGB(255,0,0);
pDC->SetTextColor(clr); //设置红色的文本
clr = RGB(0,0,0);
pDC->SetBkColor(clr); //设置黑色的背景
m_brMine = ::CreateSolidBrush(clr);
return m_brMine; //作为约定,返回背景色对应的刷子句柄
}
else
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
}

第二种方法(对应于IDC_EDIT2):
利用MFC 4.0的新特性: Message reflection。

1.利用向导添加一个新的类:CColorEdit,基类为CEdit;
2.在CColorEdit中添加一个数据成员: HBRUSH m_bkBrush;
3.利用向导映射CColorEdit的"=WM_CTLCOLOR"消息,产生函数:

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor);

对其进行如下修改:

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr); //设置黑色的文本
clr = RGB(255,0,0);
pDC->SetBkColor(clr); //设置红色的背景
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush; //作为约定,返回背景色对应的刷子句柄
}

4.利用向导为IDC_EDIT2生成一个数据成员CColorEdit m_coloredit;
5.在定义CAboutDlg的color.cpp文件中加入:#include "coloredit.h"

利用WM_CTLCOLOR消息实现编辑控制(Edit Control)的文本与背景色的改变

首先要明白:WM_CTLCOLOR是一个由控制(Control)发送给它父窗口的通知消息(Notification message)。

实现步骤:
生成一个标准的单文档应用程序框架,假设应用程序的名称为Color。我将利用它的About对话框做示范。在About dialog中添加两个Edit control,设定其ID为IDC_EDIT1与IDC_EDIT2。

第一种方法(对应于IDC_EDIT1): 按照标准的Windows编程,由其父窗口的消息处理函数负责处理WM_CTLCOLOR消息。

1. 在CAboutDlg中添加一个数据成员:HBRUSH m_brMine;
2. 利用向导映射AboutDlg的WM_CTLCOLOR消息,产生函数:HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
pDC是AboutDlg的设备上下文,pWnd是AboutDlg中发送该消息的control指针,nCtlColor市Control的类型编码。对其进行如下修改:

HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if ((pWnd->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))
{
COLORREF clr = RGB(255,0,0);
pDC->SetTextColor(clr); //设置红色的文本
clr = RGB(0,0,0);
pDC->SetBkColor(clr); //设置黑色的背景
m_brMine = ::CreateSolidBrush(clr);
return m_brMine; //作为约定,返回背景色对应的刷子句柄
}
else
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
}

第二种方法(对应于IDC_EDIT2):
利用MFC 4.0的新特性: Message reflection。

1.利用向导添加一个新的类:CColorEdit,基类为CEdit;
2.在CColorEdit中添加一个数据成员: HBRUSH m_bkBrush;
3.利用向导映射CColorEdit的"=WM_CTLCOLOR"消息,产生函数:

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor);

对其进行如下修改:

HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr); //设置黑色的文本
clr = RGB(255,0,0);
pDC->SetBkColor(clr); //设置红色的背景
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush; //作为约定,返回背景色对应的刷子句柄
}

4.利用向导为IDC_EDIT2生成一个数据成员CColorEdit m_coloredit;
5.在定义CAboutDlg的color.cpp文件中加入:#include "coloredit.h"

vc 添加打开文件对话框并读取文件

.创建打开文件对话框:
CFileDialog dlg(TRUE,//TRUE是创建打开文件对话框,FALSE则创建的是保存文件对话框
".txt",//默认的打开文件的类型
NULL,//默认打开的文件名
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,//打开只读文件
"文本文件(*.txt)|*.txt|所有文件 (*.*)|*.*||");//所有可以打开的文件类型
2.点打开文件对话框上面的确定键后
if(dlg.DoModal()==IDOK)
{
CString m_FilePath = dlg.GetPathName();////////取出文件路径
CString m_path;
m_path=m_FilePath;//将文件的路径放入m_path
UpdateData(FALSE);
}
3.打开文件:File.Open(m_path,CFile::modeRead);
4.逐行读取文件:CStdioFile File;///可以逐行读文件的类
CString strLine;
while(File.ReadString(strLine)) //////将每行都放进strLine字符串里
{
AfxMessgeBox(strLine);
}
5判断读出来的字:
strLine=“1|2|3|”;//要判断的字符串
int strIndex1 = strLine.Find('|');//在字符串中寻找“|”
CString a[11];
if(-1 != strIndex1)//只要找到“|”就不会返回-1
{
int i=0;
while( -1 != strIndex1)//
{
strIndex1 = strLine.Find('|');
a[i] = strLine.Left(strIndex1);
strLine = strLine.Right(strLine.GetLength() - strIndex1-1) ;
i++;
if (i > 10)//退出循环
break;
}
}

VC中调用外部程序方式总结

目前知道三种方式:WinExec,ShellExecute ,CreateProcess,别人已经总结的很好了《vc中调用其他应用程序的方法(函数) winexec,shellexecute ,createprocess》,我全文转载一下,另外后面加点自己的总结(黑体部分,除了标题)。
三个SDK函数: WinExec,ShellExecute ,CreateProcess可以实现调用其他程序的要求,其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂。
WinExec 两个参数,前一个指定路径,后一个指定显示方式。
ShellExecute 可以指定工作目录,并且还可以寻找文件的关联直接打开不用加载与文件关联的应用程序,ShellExecute还可以打开网页,启动相应的邮件关联发送邮件等等。
CreateProcess 一共有十个参数,不过大部分都可以用NULL代替,它可以指定进程的安全属性,继承信息,类的优先级等等。如果我们要得到足够多的关于新的进程的信息,控制新的进程的细节属性,若要达到这些目的,我们就需要使用CreateProcess函数了。
三个SDK函数( WinExec、ShellExec、CrateProcess )的语法:
(一)WinExec
这个函数最简单,只有两个参数,原型如下:
UINT WinExec(
LPCSTR lpCmdLine, // 命令路径
UINT uCmdShow // 显示方式
);
使用方法如下:
WinExec("Notepad.exe", SW_SHOW); // 打开记事本
WinExec("D:\\Program Files\\Test\\Test.exe",SW_SHOWMAXIMIZED); // 以最大化的方式打开Test.exe
需要注意的是若用 SW_SHOWMAXMIZED 方式去加载一个无最大化按钮的程序,譬如Neterm,Calc 等等,就不会出现正常的 窗体,但是已经被加到任务列表里了。
这个函数只能打开exe文件。
需要的头文件:windows.h,winbase.h(前者是试验出来,后者是msdn上说明),另外,这两者的先后顺序不能变。
msdn上的说明:[url]http://msdn.microsoft.com/en-us/library/ms687393[/url](VS.85).aspx
(二)ShellExecute
原型如下:
HINSTANCE ShellExecute(
HWND hwnd, //父窗口句柄
LPCTSTR lpOperation, //操作, 打开方式 "edit","explore","open","find","print","NULL"
LPCTSTR lpFile, //文件名,前面可加路径
LPCTSTR lpParameters, //参数
LPCTSTR lpDirectory, //默认文件夹
INT nShowCmd //显示方式
);
使用方法如下:
ShellExecute(NULL,"open","C:\\Test.txt",NULL,NULL,SW_SHOWNORMAL); // 打开C:\Test.txt 文件
ShellExecute(NULL, "open", "[url]http://www.google.com/[/url]", NULL, NULL, SW_SHOWNORMAL); // 打开网页[url]www.google.com[/url]
ShellExecute(NULL,"explore", "D:\\C++",NULL,NULL,SW_SHOWNORMAL); // 打开目录D:\C++
ShellExecute(NULL,"print","C:\\Test.txt",NULL,NULL, SW_HIDE); // 打印文件C:\Test.txt
ShellExecute不支持定向输出。
这个函数可以打开任意文件,会调用系统注册的程序来打开对应后缀名的文件。
需要的头文件:windows.h,shellapi.h(前者是我试验出来的,后者是msdn说需要的)。另外这两者的先后顺序不能变。
msdn上说明:[url]http://msdn.microsoft.com/en-us/library/bb762153[/url](VS.85).aspx
(三)CreateProcess
原型如下:
BOOL CreateProcess(
LPCTSTR lpApplicationName, //执行程序名
LPTSTR lpCommandLine, // 参数行
//下面两个参数描述了所创建的进程和线程的安全属性,如果为NULL则使用默认的安全属性
LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread security attributes
BOOL bInheritHandles, // 继承标志
DWORD dwCreationFlags, // 创建标志
LPVOID lpEnvironment, // 环境变量
LPCTSTR lpCurrentDirectory, // 运行该进程的初始目录
LPSTARTUPINFO lpStartupInfo, // 用于在创建子进程时设置各种属性
LPPROCESS_INFORMATION lpProcessInformation //用于在进程创建后接受相关信息
);
使用方法如下:
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
si.wShowWindow=SW_SHOW;
si.dwFlags=STARTF_USESHOWWINDOW;
bool fRet=CreateProcess("D:\\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,&pi);
这个函数可以打开任意文件,会调用系统注册的程序来打开对应后缀名的文件。
需要的头文件:windows.h,winbase.h(前者是试验出来,后者是msdn上说明),另外,这两者的先后顺序不能变。
msdn上的说明:[url]http://msdn.microsoft.com/en-us/library/ms682425[/url](VS.85).aspx
可以看出,通过上面的几个不同的方法,都可以实现在应用程序中打开其他应用程序的目的,其中有些方法可能会麻烦一点,所以就需要我们根据不同的目的去选择最适合自己的方法去实现自己的目的!
关于三个SDK函数: WinExec, ShellExecute,CreateProcess 的其他注意事项:
1、定义头文件
原作者的内容删去。
这个是引用新函数都必须注意的内容。但是MS的头文件引用顺序有点怪,比如上面的三种清理。另外,如果用了预编译,那么记得在任何源程序中的#include “stdafx.h”之前的引用都会失效,从其后才生效。(不可否认,预编译有他的好处,尤其当程序很大的时候,但是任何好处都是要付出代价的)
2、定义路径
C++中所表示的路径要用 " \\ "而不是平常所用的" \ ",所以以上三个函数表示路径都为:
Disk:\\Directory\\...\\File name
WinExec("D:\\Program Files\\Test\\Test.exe",SW_SHOWMAXIMIZED);
ShellExecute(NULL,"open","C:\\Test.txt",NULL,NULL,SW_SHOWNORMAL);
bool fRet=CreateProcess("D:\\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,&pi)
3、注意文件的路径
在程序a调用程序b的时候,b原来的默认的当前路径都会变成a的当前路径。所以,一定要注意。
可以养成使用绝对路径的习惯,另外,记得打开文件之类的操作,一定要验证是否有错。

MFC中建个Cmd控制台

1.初始化的时候
AllocConsole()

2.在想输出内容到 控制台窗口的时候调用
int _cprintf(const char *, ...);


3.使用完了释放
FreeConsole()

用 avrdude 燒錄 Arduino Sketch

這篇說明如何用 avrdude 燒錄 Arduino Sketch,以下指令的方式燒錄韌體。

用 Arduino IDE 就可以燒錄韌體了,而且很方便,只要按個 upload 鍵就行了,為什麼還要學下指令的方式燒錄韌體呢?理由很簡單,其實 Arduino IDE 也是透過 avrdude 進行韌體燒錄的工作,下指令可以讓我們知道更多技術細節。

設定 PATH 環境變數

首先,為了使用 avrdude,你必須先把底下幾個路徑加到 PATH 環境變數裏:

C:\arduino-00xx\hardware\tools\avr\bin;
C:\arduino-00xx\hardware\tools\avr\utils\bin;
C:\arduino-00xx\hardware\tools\avr\etc

其中,arduino-00xx 是 Arduino IDE 的版本號碼,例如 arduino-0021。

燒錄 Arduino Sketch

以 Blink 為例,當你下底下這行指令時,avrdude 會把 Blink.cpp.hex 燒錄到 Arduino 板子上:

avrdude -q -c stk500v1 -P com4 -b 57600 -p atmega328p -U flash:w:Blink.cpp.hex:i

這行指令在做什麼呢?

● -q

省略燒錄訊息。如果你想看燒錄過程中的資訊,可以把 -q 換成 -v 選項。

● –c stk500v1

使用 stk500v1 協定燒錄程式。Arduino 大部份 bootloader 用的都是講 stk500v1 的協定。

● –P com4 –b 57600

使用 COM4 並且以 57600 bps 的 baud rate 速率。如果你的 Serial port 不是 COM4,請適當調整。關於 baud rate 的設定,稍後會補充說明。

● –p atmega328p

使用 atmega328p 晶片。你必須知道你 Arduino 板子所用的 AVR 晶片為何。

● –U flash:w:Blink.cpp.hex:i

把 Blink.cpp.hex 寫到 Flash 中。最後的小寫 i 代表 intel hex format,可省略。

要怎麼取得 Arduino IDE 產生的 HEX 檔呢?這部份請參考「Arduino IDE Tweak (開發環境調校)」或「Arduino 產生的 HEX 檔」。

底下是實際操作畫面:


▲ Blink.cpp.hex 上傳到 Arduino 板子後,pin 13 上的 LED 就會開始閃爍

查詢適當的 baud rate

前面的範例使用 baud rate 是 57600 bps,其實並不是所有 Arduino 都用 57600。那麼要怎麼知道你的 Arduino 板子所用的 baud rate 是多少呢?答案是到 "arduino-00xx\hardware\arduino\boards.txt" 這個檔案裏查詢。

我用的板子是 Arduino Duemilanove,在 boards.txt 裏有這麼一筆記錄:

1
atmega328.name=Arduino Duemilanove or Nano w/ ATmega328
2

3
atmega328.upload.protocol=stk500
4
atmega328.upload.maximum_size=30720
5
atmega328.upload.speed=57600

從這裏我就可以知道 Duemilanove 所用的燒錄速度是 57600 bps。其它 Arduino 板子的燒錄速度也都可以在 boards.txt 裏查出,例如 Diecimila 用的是 19200, Mega (Atmega1280) 用的是 57600,而較新款的 UNO 和 Mega 2560 則使用 115200。

用其它 ISP 燒錄韌體

除了透過 Arduino 的 bootloader 燒錄的方法外,avrdude 也支援其它 ISP (In System Programmer) 燒錄器,支援的種類很多,例如 AVR Dragon, USBTiny, avrispmkii 以及 arduinoisp 等。

以走 USB 介面的 AVR dragon 為例,燒錄 Flash 的指令是:

avrdude -c dragon_isp -P usb -p atmega328p -U flash:w:Blink.cpp.hex

如果你把 Arduino 當成 ISP 用,燒錄的指令則是:

avrdude -q -c stk500v1 -P com4 -b 57600 -p atmega328p -U flash:w:Blink.cpp.hex:i

注意!這行指令跟最前面介紹的是一樣的,不過 Arduino ISP 硬體接法不一樣,而且結果也不同。這部份請參考「Arduino 當成一個 AVR ISP (In-System Programmer) 使用 (3)」的說明。

另外,用 ISP 直接把 Arduino Sketch 燒錄到板子上,這種方式沒有用到 bootloader,這讓你得以使用 ATmega 晶片全部的程式空間 (program space)。

2011年8月28日星期日

新奥尔良烤翅

材料:10个鸡翅、蜂蜜、酱油、盐、料酒(红酒也可)、姜、红干辣椒、五香粉、黑胡椒。 作法:
  1.如果是速冻鸡翅,请先解冻。把10个新鲜鸡翅放在一个可在微波炉内加热的器皿内。
  2.加入少量酱油,放2勺酱油足可。
  3.加入料酒或红酒,大约2勺子,主要用于去掉鸡翅的腥味。
  4.加入盐、少许姜沫、少许辣椒子,少许五香粉(一般超市都有卖)、少许黑胡椒。
  5.将鸡翅和作料搅拌均匀,充分粘取作料。
  6.盖好盖子将鸡翅放在冰箱冷藏室腌制,电视上讲最好是一宿(所以一定要提前准备,不能现吃现做。如果实在很急,也要腌制2-3个小时,充分进味儿)。
  7.将腌制好的鸡翅取出,涂抹上蜂蜜(这样色泽味道才对!)可根据口味适当增加蜂蜜涂抹的多少。
  8.将涂抹好蜂蜜的鸡翅放进微波炉,中高火加热(一般是3个火苗那档)11分钟即可
编辑本段
爱心提示

  1. 最好不要增加水的添加比例,以免影响烤肉的口味质量。 2.烤箱或微波炉设备不同,烤肉的时间也不完全相同,请在第一次烤肉时注意观察烤肉变化,避免烤糊或烤干。
  3.如果配料开袋后一次没有使用完毕,请密封口放在阴凉干燥处保存,以免失去风味.
  4.腌好的肉如果没有用完,可以包装好放在冰箱内速冻存放,下次解冻后即可直接烤制.
  (聪明人们/懒人们一般都是一次腌很多,存放起来,下次解冻后很快就可以烤了..)

2011年8月21日星期日

炝拌土豆丝

材料:

长型土豆2颗、胡萝卜少量、香菜少量、花椒10颗、干红椒10颗、沙拉油适量

调味料:

盐1/3小匙、鸡精1/4小匙、香醋2小匙、砂糖1小匙、芝麻香油1小匙

做法:

1.将土豆去皮,先切成薄片,再切成细丝。(图1)将切好的细丝用清水洗去表面的淀粉质(图2)

2.锅内烧开水,放入土豆丝和少量胡萝卜丝,氽烫1分钟捞起,(图3)用水冲凉后,浸泡入凉开水中(图4)

3.将放凉的土豆丝彻底沥干水份(图5)将土豆丝放入盆内,放入盐,鸡精,醋,糖,芝麻香油,香菜碎,不要拌放着备用。(图6)

4.锅内放入1大匙沙拉油,冷油放入花椒粒炒至出香味,捞起香椒粒,熄火让油温降至3成热。(图7)

5.再放入干椒段,用小火炒出香味,但不要炒焦了。(图8),乘热将热油和红椒淋在土豆丝上,并加盖焖上1分钟,再拌匀即可食用(图9)

2011年8月7日星期日

When your project grows bigger

From:http://www.embedds.com/when-your-project-grows-bigger/

Until now we used pretty simple program examples where all code fit in to single file and didn’t look very complicated. Probably because we programmed one simple function at a time. We didn’t care much about programming styles and modularizing. But due time, programs are going to grow bigger and more complex. It may become very hard maintain your own code and even harder for other developers to read. We should follow some simple rules that makes microcontroller programming more fun than scratching along.

Split your programs


Say you are writing pretty complex program which deals with LCD, USART and even more peripherals. To make them all work, you need routines to init , read, write, change mode. Imagine how many functions your single file would have to hold and I am not talking about main routine. It would end up with more scrolling than coding. So, smart solution is to split your project in to several files – libraries. Each library would have to take care of one type tasks like controlling USART, other LCD and so on. For instance, our program needs these functions:
-----------------------------------------------
int main();
void MainPortInit();
uint8_t MainReadPort();
void USARTInit();
void USARTSendByte(uint8_t Data);
uint8_t USARTReceiveByte();
void LCDInit();
void LCDclr();
void LCDGotoXY(uint8_t, uint8_t);
void LCDSendChar(uint8_t);
-----------------------------------------------
Putting all these functions in one file would work, but code would become heavy, hard to read and reuse. So lets split all these routines by assigning some logic. Logic basically relies on related functions like USART functions would go to one group, LCD to another. Some general functions may stay in main code. After grouping our example we have three groups of functions that goes to separate files:
-----------------------------------------------
main.c

int main();

void MainPortInit(void);

uint8_t MainReadPort(void);
usart.c
-----------------------------------------------

void USARTInit(void);

void USARTSendByte(uint8_t Data);

uint8_t USARTReceiveByte(void);
lcd.c
-----------------------------------------------

void LCDInit(void);

void LCDclr(void);

void LCDGotoXY(uint8_t, uint8_t);

void LCDSendChar(uint8_t);
After this operation we end up with three source files. But how to link them in to single program. This is done by using header files. So we need to create a pair file to each source file.

main.c – main.h(not required)

usart.c – usart.h;

lcd.c – lcd.h

Header files must be same name as source files but with extension .h. So when one source file needs to use routine from another source file, you must include a header file by defining header file using quotes:
-----------------------------------------------

#include"main.h"

#include"usart.h"

#include"lcd.h"
We already include some headers in our programs but in side brackets, meaning that these are system header files located in system directories.
-----------------------------------------------
#include

#include
Last thing to do is to make header files work. Header file is wrapped around preprocessor defines so called header guard:
-----------------------------------------------
#ifndef LCD_H

#define LCD_H

//contents

#endif
This prevents from multiple includes of same header. First it checks if this file has been included, if not then current is included. The current situation may occur when several source files use same include or include each other. For instance usart.c would include lcd.h and lcd.c would include usart.h – this would lead to recursive inclusion during compilation. So don’t worry to much and use preprocessor defines. Header guard has to be named with all caps. Better use same name as file with underscore instead dot like LCD_H. In order to make header function we need to put something in it. First of all header must have all function prototypes from c file included. For instance lcd.h may look like:
-----------------------------------------------
#ifndef LCD_H

#define LCD_H

//is 4 bit mode?

#define 4BIT

void LCDInit(void);

void LCDclr(void);

void LCDGotoXY(uint8_t, uint8_t);

void LCDSendChar(uint8_t);

#endif
Also there can be various definitions, type definitions or macro functions.

External globals
Also header files can declare global variables that might be used in multiple source files. To make it possible declare variable inside c file:
-----------------------------------------------
uint8_t Mode = 1;
Then in header file lcd.h define this variable by adding “extern” keyword.
-----------------------------------------------
extern uint8_t Mode;
This will make this variable visible in other c files if header is included. Just be sure not to define variables in header files – do this in c file.

Static functions
Last thing to mention about modularizing code is “static” functions. Lets say we created separate lcd.c and lcd.h files. We wrote a bunch of routines like LCDsendCommand(uint8_t), LCDInit(), LCDWrite(uint8_t), LCDGotoXY(uint8_t, uint8_t), and so on. Some of these functions definitely will be used in other files, but some not. For instance LCDsendCommand(uint8_t) will be used only inside lcd.c to make other routines work. We don’t need this function to be accessible by other c files. To do so we add keyword “static” to this function.
-----------------------------------------------
static void LCDsendCommand(uint8_t);
Add this keyword in both – c and h files. This is useful practice that helps compiler to optimize function as it doesn’t have to be called outside the own c file.

Benefits of modularizing
It may seem complicated at the beginning but it is really easy and makes programming smooth. It is good practice to write separate libraries for separate function groups like USART, LCD, ADC, TWI, because once written you can include these libraries multiple times in different projects– just be smart and write them to be more universal – don’t tie to specific hardware, but use preprocessor defines for hardware specific stuff. Later you will see that programming microcontrollers may be same as using/adapting right code library with minimal coding efforts.

Again this is only a scope of few things. We are not going back to them as these are basics of C programming and can be found on every corner in internet where “C tutorial” is mentioned. Better lets focus on microcontroller stuff again.

2011年8月2日星期二

修改Windows XP的登录背景色和图案

1修改Windows XP的登录背景图案:面对长久不变的单调的登录图案,你可能日久生厌,我们可以通过注册表来把它换成自己喜欢的图案,步骤如下:打开注册表编辑器,找到HKEY_USERS\.DEFAULT\Control Panel\Desktop子键分支,双击wallpaper,键入你选择好的图片的路径,如:c:\Documents and Settings\My Documents\My Pictures\mypic.bmp,点击“确定”,然后找到Tilewallpaper,双击它输入键值“1”,重新启动系统即可看到效果。

2修改登录时的背景色:如果你还想修改登录时的背景颜色,可以按以下步骤操作:打开注册表编辑器,找到HKEY_USERS\.DEFAULT\Control Panel\Colors子键分支,双击子键分支下的Background键值名,出现“编辑字符串”对话框,在“数值数据”文本框中输入代表颜色的键值(比如黑色的RGB值为000,白色的RGB值为255 255 255,系统默认值是58 110 165),点击“确定”按钮,重新启动系统即可。

3设置启动信息或增加警告信息:如果在启动Windows XP时,希望显示一些自己定义的个性化信息,可以按以下步骤来操作:打开注册表编辑器,找到KEY_LOCAL_MACHINE_SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon子键分支,双击在它下面的LegalNoticeCaption健值名称,打开“编辑字符串”窗口,在“数值数据”文本框中输入信息对话框的标题,比如“你好,欢迎使用本机器”,然后双击LegalNoticeText,在随后出现的“编辑字符串”窗口中输入想要显示的警告信息,比如“请不要随意修改本级的设置,谢谢!”,单击“确定”按钮,重新启动即可看到修改后的效果了。

2011年7月25日星期一

新手指南:彻底明白操作系统环境变量

 1.环境变量的设置有几种方式?
设置环境变量有两种方式:第一种是在命令提示符运行窗口中设置;第二种是通过单击“我的电脑→属性→高级”标签的“环境变量”按钮设置。需要注意的是,第一种设置环境变量的方式只对当前运行窗口有效,关闭运行窗口后,设置就不起作用了,而第二种设置环境变量的方式则是永久有效。

  2.如何在命令提示符窗口中设置环境变量?

  在“开始→运行”框中输入“cmd”后按“确定”按钮,出现命令运行窗口。在命令提示符下输入“set”即可查看环境变量设置。要查看具体某个环境变量的设置,比如要查看path环境变量的设置,可以输入“set path”。要创建一个环境变量,比如要创建一个名为aa的,值为“c:”的环境变量,可以输入“set aa=c:”命令。而要删除一个环境变量,比如要删除aa环境变量,则可输入“set aa=”命令(注意=后面不能有空格)。如何更改一个环境变量的设置呢?更改环境变量有两种情况:一是追加方式,即在不改变环境变量现有设置的情况下,增加变量的值,比如要给环境变量aa增加一个值为“D:”的设置,可以输入“set aa=%path%;D:”。另一种是完全修改方式,对于这种方式,我们可以采用直接创建一个环境变量的方法来实现。

  3.用户变量和系统变量的关系是什么?

  点击“我的电脑→属性→高级”标签的“环境变量”按钮,出现“环境变量”对话框,如果当前是以Administrator登录系统的用户,对话框的上面为Administrator的用户变量,对话框的下面为系统变量(即相当于系统中所有用户的用户变量)。有的时候我们会看到在用户变量和系统变量中都存在某一个环境变量,比如path,那么path的值到底是用户变量中的值还是系统变量中的值,或者两者都不是呢?答案是两者都不是。path变量的值是用户变量中的值与系统变量中的值的叠加。

  4.改变环境变量和环境变量中的值应该注意什么?

  环境变量和环境变量的值不要含有空格,也不要用中文,切记!

批量修改快捷方式的路径VBS脚本源码

这个是以前维护网吧的时候经常用到的工具,曾经为我节省了不少的麻烦,现在共享给大家,希望大家喜欢~~

把以下代码复制到记事本中,并改扩展名为“.VBS”即可,使用也很简单只要在代码注释的地方修改引号中的原路径和新路径,然后把这个VBS文件放到快捷方式的文件夹中运行即可。

Option Explicit
Dim oldpath,newpath

oldpath = "E:\小游戏\" '设置原路径中将被替换的内容
newpath = "d:\小游戏\" '设置新路径中要使用的内容

Dim Wsh,fso
Set Wsh = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Dim ji_1,ji_2,Folder
ji_1 = 0
ji_2 = 0
Folder = Wsh.CurrentDirectory
if Ask("将要修改"&chr(34)& Folder &chr(34)&"里的所有快捷方,是否继续") then
Dim f,fc,f1,ext
Set f = fso.GetFolder(Folder)
Set fc = f.Files
For Each f1 in fc
ext = LCase(fso.GetExtensionName(f1))
if ext = "lnk" then
ji_1 = ji_1 + 1
call Doit(f1)
end if
Next
end if

Set WSH = Nothing
msgbox "找到 "&ji_1&" 个快捷方式"&vbCrLf&"修改 "&ji_2&" 个快捷方式",64,"执行完毕"
WScript.quit

Sub Doit(strlnk)
Dim oShlnk
Set oShlnk = Wsh.CreateShortcut(strlnk)
If Instr(oShLnk.TargetPath,oldpath) > 0 Then
oShLnk.TargetPath = Replace(oShLnk.TargetPath,oldpath,newpath)
oShLnk.Save
ji_2 = ji_2 + 1
End If
Set oShLnk=NoThing
End Sub

Function Ask(strAction)
Dim intButton
intButton = MsgBox(strAction,vbQuestion + vbYesNo,"询问")
Ask = intButton = vbYes
End Function

批量修改快捷方式路径的VBS脚本

Option Explicit
Dim oldpath,newpath

oldpath = "x:\game" '设置原路径中将被替换的内容
newpath = "g:\game\langame" '设置新路径中要使用的内容

Dim Wsh,fso
Set Wsh = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Dim ji_1,ji_2,Folder
ji_1 = 0
ji_2 = 0
Folder = Wsh.CurrentDirectory
if Ask("将要修改"&chr(34)& Folder &chr(34)&"里的所有快捷方,是否继续") then
Dim f,fc,f1,ext
Set f = fso.GetFolder(Folder)
Set fc = f.Files
For Each f1 in fc
ext = LCase(fso.GetExtensionName(f1))
if ext = "lnk" then
ji_1 = ji_1 + 1
call Doit(f1)
end if
Next
end if

Set WSH = Nothing
msgbox "找到 "&ji_1&" 个快捷方式"&vbCrLf&"修改 "&ji_2&" 个快捷方式",64,"执行完毕"
WScript.quit

Sub Doit(strlnk)
Dim oShlnk
Set oShlnk = Wsh.CreateShortcut(strlnk)
If Instr(oShLnk.TargetPath,oldpath) > 0 Then
oShLnk.TargetPath = Replace(oShLnk.TargetPath,oldpath,newpath)
oShLnk.Save
ji_2 = ji_2 + 1
End If
Set oShLnk=NoThing
End Sub

Function Ask(strAction)
Dim intButton
intButton = MsgBox(strAction,vbQuestion + vbYesNo,"询问")
Ask = intButton = vbYes
End Function

2011年7月24日星期日

MATLAB Newsreader > preferences setting, shortcuts backup

On 29/09/10 9:40 AM, james han wrote:

> i just have a simple questions, whenver i install matlab i need to spend
> some time to make the program of my own styles like....color, fonts,
> shortcuts...
>
> i'm just wondering is there any way to backup those settings so that i
> can use it again next time i install it?

At the matlab command prompt, tell it to display the "prefdir" variable.
The result will be a directory name. Look in that directory and you will
find at least one of matlab.prf (a text file) or matlabpref.mat (a
matlab binary file). It appears to me that matlab.prf is the newer
mechanism, but I am not certain.

PS:
C:\Documents and Settings\[User name]\Application Data\MathWorks\MATLAB\R14
下有两个文件

matlab.prf --- 这个是背景色,字体等等的设定保存文件
MATLABDesktop.xml --- 是Matlab主窗口的布局设置保存文件
history.m --- 是Command的历史文件
cwdhistory.m --- 是文件路径的历史文件

重新装MATLAB时主要把前两个文件备份了就OK了
还有就是自己安装的一些函数库要备份一下,(待继。。。。)

关闭Windows XP的“自动播放”功能

 默认情况下,一旦将光盘插入光驱,或者接插上闪存、移动硬盘时,Windows XP的自动播放功能就读取驱动器,同时显示一个对话框,要求你选择是否打开其中的视频、音频、图片文件。有时,这项自动功能可能会给你带来不小的麻烦,如果你想关闭这项功能,跟我来吧。

  一、属性设置法

 如果你要关闭单个移动存储设备的“自动播放”功能,操作步骤如下:

  1、单击“开始→我的电脑”;

  2、在“有可移动存储的设备”下,右键单击需要的设备,如数码相机或CD-ROM驱动器,然后单击“属性”;

  3、单击“自动播放”选项卡,再单击“要更改的多媒体内容”,然后选中“选择一个操作来执行”复选钮,再单击“不执行操作”。对其他的多媒体类型,重复该步骤,最后“确定”。

  对于光驱以外的可移动存储设备,必须在连接到计算机时,它才会出现在“我的电脑”的“移动存储设备”下。

  二、组策略法

  如果你想一次全部禁用Windows XP的自动播放功能,那么请按下述步骤操作:

  1、单击“开始→运行”,在“打开”框中,键入“gpedit.msc”,单击“确定”按钮,打开“组策略”窗口;

  2、在左窗格的“本地计算机策略”下,展开“计算机配置→管理模板→系统”,然后在右窗格的“设置”标题下,双击“关闭自动播放”;

  3、单击“设置”选项卡,选中“已启用”复选钮,然后在“关闭自动播放”框中单击“所有驱动器”,单击“确定”按钮,最后关闭“组策略”窗口。

  在“用户配置”中同样也存在这个“关闭自动播放”设置。但“计算机配置”中的设置比“用户配置”中的设置优先。需要注意的是:“关闭自动播放”设置并不能够阻止自动播放音乐CD盘。要阻止音乐CD的自动播放,你就只有使用“属性设置法”了。

给右键菜单加入CMD命令行快速通道

很多人都很喜欢在CMD命令行下来操作计算机,我也是其中之一。 如何快速打开CMD并且定位到指定的路径呢?很多优化软件(比如优化大师)都提供了往右键菜单中加入“CMD快速通道”的功能,当右键点击文件夹时,就打开CMD并定位到该文件夹。网上也有修改注册表来实现的,其实根本不用这么麻烦。

打开“我的电脑”,点击菜单中的“工具”-“文件夹选项”,选择“文件类型”,找到“(无)资料夹”,点“高级”,“新建”,在“操作”中填入“CMD快速通道”(其实爱填什么都可以),“用于执行操作的应用程序”中填入“cmd.exe /k cd %1”(这个是关键),确定即可。

右键打开任何一个文件夹、分区,点击“CMD快速通道”,就可以打开CMD命令行了。

2011年7月22日星期五

Google日本語入力のオフィシャルな移行について

From: http://www.google.com/support/forum/p/ime/thread?tid=644be0e794fa72a3&hl=ja

(1)Windows 7をインストールし直す前に、
次のフォルダーにあるファイルをバックアップしておく。
C:\Users\[ユーザー名]\AppData\LocalLow\Google\Google Japanese Input


PS:Windows XP 場合は C:\Documents and Settings\[ユーザー名]\Local Settings\Application Data\Google\Google Japanese Input

自分の環境では以下のファイルが存在した。
boundary.db
cform.db
config1.db
segment.db
user_dictionary.db


(2)Windows 7を再インストールした環境に、Google日本語入力をインストールする。


(3)次のフォルダーにバックアップしておいたファイルを移行する。
C:\Users\[ユーザー名]\AppData\LocalLow\Google\Google Japanese Input



Google 工藤です

オフィシャルに移行作業をサポートしているわけではないので、今後変わるかもしれませんが、

boundary.db
cform.db
config1.db
segment.db
user_dictionary.db

の各ファイルをコピーすれば、学習結果、ユーザ辞書、半角・全角の学習結果は移行されます。ただし、変換エンジンが動作してる時に、コピーすることを想定していないので、コピーする前に変換エンジンのプロセス (GoogleJaIMEConverter.exe) を終了しておく必要があります。(タスクマネージャからプロセスを終了してください)

なお、入力履歴からのサジェストデータにつきましては、同フォルダに隠しファイルとして保存されていますが、これはマシン固有の暗号キーを使って暗号化されているため、別のマシンにコピーしても動作しません。

よろしくお願いいたします。

2011年7月16日星期六

转:九大絕招巧妙應付公司各類人

謹以此文分享給就業中和即將就業的同學們,不過該文某些地方太過功利,希望大家在浏覽時取其精華,棄其糟粕。俗話說,人在江湖漂,哪能不挨刀!職場就是一個不大不小的糨糊江湖。當我們踏上工作崗位后,會遇到形形色色的人,如果遇人不淑,你將麻煩不斷。工作比別人多做不說,還可能出力不討好,功勞全被別人搶走。所以,我們需要學習一些招數,來對付某些人。當然了,在現在這個這麽難找工作的時期,把自己的工作做好,做出色才是王道!

應付口蜜腹劍的人:微笑著打哈哈

面對這種人,如果他是你的老板,你要裝得有些癡呆的樣子,他讓你做事情,你都唯唯諾諾滿口答應。他和氣,你要比他更客氣。他笑著和你談事情,你就笑著猛點頭,萬一你感覺到,他要你做的事情實在太毒了,你也不能當面拒絕或翻臉,你只能笑著推诿,誓死不接受。
如果他是你的同事,最簡單的應付方式是裝得不認識他。每天上班見面,如果他要親近你,你就要找理由馬上閃開。能不做同一件工作,盡量避開不要和他一起做,萬一避不開,就要學著寫日記,每天檢討自己,留下工作記錄。
如果他是你的部下的話,只要注意三點:其一,找獨立的工作或獨立工作位置給他;其二,不能讓他有任何機會接近上面的主管;其三,對他表情保持嚴肅,不帶笑容。

應付吹牛拍馬的人:不要與他爲敵

如果你碰到這一類的主管,要和他搞好關系,他吹牛拍馬對你無害。當此類人是你的同事時,你就得小心了。不可與他爲敵,沒有必要得罪他。平時見面還是笑臉相迎,和和氣氣。如果你有意孤立他,或者招惹他,他就可能把你當做往上爬的墊腳石。如果他是你的部下,要冷靜對待他的阿谀逢迎,看看他是何居心。

應付尖酸刻薄的人:保持一定距離

尖酸刻薄型的人,是在公司內較不受歡迎的。他的特點是和別人爭執時往往挖人隱私不留余地,同時冷嘲熱諷無所不至,讓對方自尊心受損,顔面盡失。這種人平常以取笑同事、挖苦老板爲樂事。你被老板批評了,他會說:“這是老天有眼,罪有應得。”你和同事吵架了,他會說:“狗咬狗一嘴毛,兩個都不是好東西。”你去糾正部下,被他知道了,他也會說:“有人惡霸,有人天生賤骨頭,這是什麽世界?”尖酸刻薄型的人,天生伶牙俐齒得理不饒人。由於他的行爲離譜,因此在公司內也沒有什麽朋友。他之所以能夠生存,是因爲別人怕他,不想理他。但如果有一天遭到衆怒,他也會被治得很慘。
如果不幸這類人是你的老板,你唯一可做的事就是換部門或換工作。但在事情還沒有眉目及定案時,不要讓他知道。否則,他的一輪人身攻擊,你恐怕會承受不了。
如果他是你的同事,和他保持距離,不要惹他。萬一吃虧,聽到一兩句刺激的話或閑言碎語,就裝沒聽見,千萬不能動怒,否則,是自討沒趣,惹鬼上身。
如果他是你的部下,你得多花時間在他身上。有事沒事和他聊聊天,講一些人生的善良面,告訴他做人厚道自有其好處。你付出的愛心和教誨,有時會帶來一份意想不到的收獲。

應付挑撥離間的人:最好謹言慎行

同樣是一張嘴巴,有人用來吹牛拍馬,有人用來諷刺損人,有人用來挑撥是非離間同仁。吹牛拍馬是損人利已;尖酸刻薄是損人利己;挑撥離間是將公司弄得亂七八糟,人心惶惶,變文明爲野蠻,人人自危,人人戰斗。這類型的人,給公司帶來的殺傷力非常之大且迅速,只要一不注意或處理不當,便可能灰飛煙滅,處處殘迹。應付這種類型的人,沒有什麽辦法,只能防微杜漸,不讓這類人進來,或一有發現就予以制止或消除。否則,后果不堪設想。
挑撥離間型的人做了你的老板,你首先要注意的是謹言慎行,和他保持距離,在公司建立個人信譽,同時要保持著“能做就做,不能做就走”的寬廣心胸。
這種人做了你的同事,你除謹言慎行及和他保持距離外,最重要的是你得聯絡其他同事,建立聯防及同盟關系,將他孤立起來,如果他向任何人挑撥和離間,不要爲之所動和不受影響。
如果他是你的部下,那你就要想辦法弄走他,孤立他。如果下不了手,他就會孤立你,弄走你。

應付雄才大略的人:虛心地學習

這一類型的人,胸懷大志,眼界開闊,而不計較一些小的得失。他在工作時,不忘掉充實自己及廣結善緣。除了完成自己的工作外,他也會幫助別人和指導同事。每到一個地方,不論他是否已呆很久,或已成爲組織中的正式主管,他都能在極自然的情況下,影響人,控制群體的行爲。俗話所說的“虎行天下吃肉”,指的大概就是這種人。雄才大略的人,見識往往異於常人,思維邏輯方式也有其個人特色。他在時機不成熟時,可以忍耐,不論是臥薪嘗膽或是從你的胯下爬過,他都能欣然接受。但是,時機成熟,他奮臂而起,如大鷹沖天,沒有人能與之爭鋒。不是每一個雄才大略的人,都是成大功立大業的。但是,做人處事自有風格,不卑不亢、不急不躁是他的本色。
碰到有雄才大略的老板,你是跟對人了。於是亦步亦趨,片刻不可相離,他晉升你也跟著晉升。砬到這種老板,你要慮心向他學習。因爲天下沒有不散的筵席,當曲終人散時,別人都受益匪淺,自然你也不會兩手空空。
有雄才大略的同事,如果大家利害一致,大可共創一番轟轟烈烈的事業。如一山不能容二虎的話,也可一相合縱挂六國相印,一相秦皇以連橫合並天下,各取所需,各享盛名,而得其利。如果以上都行不通的話,你就全心全意地幫助他成功,自己多少也留下識才的美名。
有了這種部下,你應有自知這明。知道他終非池中之物,有朝一日定會超過你。虛心地接納他,給他實質上的資助肯定。在會計學上稱爲投資,到時候一定是有利潤的。

應付翻臉無情的人:應該留一手

這類型的人最大的特征就是,翻臉如翻書。說翻就翻,一翻就是好幾面。在他翻臉時,你不要問他理由,你不必述說從前對他的恩情和助益,他一個字都聽不進去。翻臉無情的人,他似乎是得了一種“忘恩記仇病”。你對他的百般呵護,只要小事一樁不順他的心,就全盤翻覆。這有如野心狼子,你養育愈久,對自己的危險就愈大。這種情形,在國內的連續劇的劇情中,最常看得見。三十集中,讓他橫行二十九集半,最后,還是編劇者應觀衆要求,將他在銀幕內正法。翻臉無情的人發現,他利用這種方式來處理他的人際關系,簡直是無往不利,處處占有便宜。他知道每次利用完別人,又找到新利用對象時,此時就可翻臉。反正每次翻的都是不同的人,別人不但記不住也無可奈何,只能自認倒黴!
如果不幸你的老板是這種翻臉無情的人,你在他手下做事時,千萬要記住“留一手”。任何事情做完了,你就得小心被炒鱿魚。怎麽樣化被動爲主動,當他要翻臉的那一刹那,你也告訴他我等你好久了,爲什麽你今天才要翻!少來這一套,你這種手段我看多了。
如果有這種同事,你倒是大可不必和他一般見識。反正沒有利害關系,各干各的活,要翻不翻隨便你!
有這種部下最令人傷腦筋,也沒有什麽好的辦法。最重要的是不能因爲他常翻臉而特別將就他,別的部下會以爲你是欺善怕惡,這就劃不來了。

應付憤世嫉俗的人:睜只眼閉只眼

這一類型的人,對社會上的一些現象非常地看不慣,認爲社會變了,世風不古,人心愈來愈險惡,快活不下去了。和憤世嫉俗的人共事,說不上好還是不好。只要他所憤的事不是公司福利制度,對你來說這只是其個人行爲,沒有什麽好說的。當有一天他對公司的制度、福利有意見時,你就有福了。他往往會犧牲自己,爲你們去謀一些好處來。
對憤世嫉俗的部下,要勸他多吸收新的知識。告訴他現在社會進步了,風氣開放了,他的那一套理論已經過時了,要收起來,否則,會跟不上進代。罵不得要領,你會被見笑,我也失面子。

應付敬業樂群的人:工作得賣力氣

這一類型的人,由於工作態度和做事方法正確,頗受公司的肯定和同事的愛戴。凡是他在單位及群體,都會有著不錯的生産力和業績。這一類型的人,會感染其他的工作同仁,讓組織朝著正面的方向發展,給員工帶來一個合作而和諧的工作環境。當公司順時,大家共同努力,共享成果;當公司不順時,大家咬緊牙關,奮發圖強,再創生機。平時沒事的當兒,他會主動地訓練新手,培養團體實力;工作 忙碌的刹那,他又能影響同仁,相互支援,共渡難關。
這一類型的人,不論是你的主管、同事和部下,在和他們一起工作時,你都要學著和他一樣地敬業樂群。只要你表現出不是那個樣子的話,你就會被他比下去。

應付躊躇滿志的人:盡量順著他

躊躇滿志的人,對任何事情都有他自己的定見。他之所以會躊躇滿志,是因爲一直處在一種極順的狀況下,使他不曾嘗過失敗的苦頭。因此也不怕失敗。上帝既然對他如此地眷顧,只要上帝不死,他自然會再受眷顧下去。他沒有辦法接受別人的意見,如果別人夠聰明的話,也不用和他辯。要知道一個長久不曾失敗過的人,是因爲他的智慧,而不是他的運氣。朋友,相信“智慧”這兩個字,雖然很好寫,但不容易了解。
如果他是你的老板,在他的面前不要亂出點子。盡量照著他的意思去做,他會把他的意思講得很清楚。因爲他怕你笨,所以他會多講一遍。最后,再問你一次,懂了嗎?等你回答懂了,他才放心。有時,他會禮貌性地問你一次,對他的做法,有沒有意見?此時你就立即肯定他的做法。此時你若稍有猶豫或再多問兩句,都會被他嗤之以鼻。
和這類人同事,不能太順著他,只有讓他嘗到一些失敗的苦果,才能真正地改變及幫助他。
對這種部下,交一些難度較高的工作給他做。做成功了,也不贊許;做失敗了, 交給別人做。讓別人做成功,讓他知道人外有人天外有天的道理。不用訓練他和告訴他做事的方法,他聽不進去。多花一些精神在別的人身上,對他絕對是有益的。