也用了那么久的C8051单片机了,特记录了一点点心得,贻笑大方了。。。

1.数组溢出不会报错,必须小心小心。。。很容易导致程序跑飞等重大问题。
2.编译器有时会过度优化,数据有时不正确。
解决方法1:为变量添加volatile,2. 减少优化级别
3.unsigned char i;
for(i=0;i<4096;i++){} 死循环!!!
4.中断问题,中断里不要进行耗时长的工作,
可以添加一个标志,在主循环里判断标志并执行相应动作。
5.几个中断的优先级应该小心选择。有些中断需要避免打扰。
6.看门狗的问题,C8051默认使能看门狗,有时全局外部变量过多,在
初始化全局外部变量的时间大于喂狗时间,导致单片机不能进入main函数。
此时要么减少全局外部变量的个数,要么在汇编初始化代码中禁止看门狗。
7.函数内变量可用static,减少每次定义时间。
8.善用bdata类型;可用于并行通讯的无序引脚赋值中。
bdata uchar bDat;
sbit P1^0 = bDat^0;
sbit P1^1 = bDat^1;
9.精确延时用定时器即可,禁止定时器中断,手动查询溢出标志;
假如单片机时钟12M,故他每秒滴答12000000(12M) 次,每毫秒滴答12000次,每微妙滴答
12次(所以延时只能精确到微妙),将定时器的装载值设为滴答的次数即可。
void Delay(unsigned int ms)
{
 unsigned int i; 
 TMR2CF &= ~0x18;                    // Timer2 uses SYSCLK/12
  for (i = 0; i < ms; i++) {
  TR2 = 0;//禁止定时器2
  RCAP2 = -SYSCLK/TIMER_PRESCALER/1000 ; 
  TMR2 = RCAP2;
  TR2 = 1;//启用定时器2
  while(TF2 == 0);//检查溢出标志
  TF2 = 0;
 }
}
10.ADC查询方式好用一些,特别是其他中断多的时候。BUSY标志。。。
11.推挽用于输出,开漏用于双向IO(输入和输出均可),也可动态切换这两种方式。
12.工作时钟越大功耗越高,也更易受干扰,简单配置的单片机软件不需要很高的时钟。
13.外部存储器总线方式,引脚均要设为推挽,包括wr,rd,data,address. FPGA通讯。。。
14.看门狗喂狗方式有主循环喂狗和中断喂狗两种方式,个人偏向于主循环喂狗。
15.下载器的固件程序在带电插拔的情况下可能损坏,所以有时需要手动更新下载器的固件程序。
16.单片机最终不过是控制外部引脚输出高低两种电平而已,
他有串行和并行数据通信,和外部器件通过标准协议进行通信(SPI,I2C,USB,LAN,CAN...)。
17.外部存储器总线通讯:
unsigned char xdata *pchar;
for (i = 0; i < RAM_SIZE; i++) {
      *pchar++ = 0;
}
#define XBYTE ((unsigned char volatile xdata *) 0)
XBYTE[0x1000]=100;//Write   <absacc.h>
char tmp = XBYTE[0x1000];//read
内部存取器读取:
char tmp = CBYTE[0x0100];
dat = *(uchar code *) addr;
18. 只读变量存放代码区,可用于查表用:
 unsigned char code arr[10]={1,2,3,4,5,6,7,8,9,10};
专一,究其极致,《暗时间》

19.data空间不够,可用idata(128byte),再pdata,再xdata。速度从高到低。
20.F0=1;F1=0;//user flag  可用用,其实没啥大用。
21.只读:
enum{}; #define; const; code; typedef ...
22.内容为王,傻瓜!!  GUI 不过是显示而已,数据为王,数据处理为王,显示其次...

//-------------------------------------------------------------------------

在信息时代客观障碍已不复存在所谓障碍都是主观上的如果你想研发什么新的技术你不需要几百万美元的资金你只需要在冰箱里放满比萨和可乐再有一台便宜的计算机和与之献身的决心你即可拥有任何你想拥有的编程境界......     - John Carmack