1. Ctrl+S为保存当时文件,如图
翻开了两个文件,能够看到有个文件是带星号且有个红叉的,有个红叉阐明它为当时翻开的文件,也便是正在修改的文件。当按下Ctrl+S时只保存了当时文件。另一个文件没有保存,当你的电脑意外断电或死机时,假如你在那之前按了Ctrl+S那么能够拯救点丢掉,但是另一个文件的信息或许就丢掉了。所以引荐按F7(对所以文件进行编译,而且保存),这样就能够在编译的一起将所以文件保存一次。所以在真实做工程的时分就要学会守时按F7,不是说一定要程序编写完好后才按F7。
2. 默许状况下头文件和源文件应该放在同一个文件目录下,假如将头文件放在一个独立的文件夹中如名为include的文件夹,此刻就读取不出。要进行一下设置才干读取出来。如图:
在C51选项中的Include Paths 选项中要设置头文件的途径后方能翻开头文件,仇人文件进行编译!
3. 关于不改动的变量,如数码管显现的数组,要经过前缀code将它放在ROM中防止占用了RAM的空间。
4. 宏界说的内容全用大写字母,当有两个单词时用_将他们分隔,如#define LED_SEG P1_1;在特别状况下才用小写字母。
5. 变量名的界说一般为 i , Led , DispBuff 即单个字母时小写,多个字母一个单词时首字母大写,多个单词时连写且每个单词的首字母大写。
6. 函数名的界说一般为 delay ,write_byte 即单个单词时全小写,多个单词时也是小写,但是单词间用 _ 离隔。
7. 不必纠结于该换行多少,空格多少,只需自己知道哪里该换行,哪里改空格就行了,像这些东西的规范只要自己真实实践的时分就能领会出来。当然这没有肯定的规范,就算是十分超卓的工程师也很难做到精确的换行,当是他们的程序全体看起来规整有可读性高就OK了。要懂得把精力放在恰当的当地。
8. 不要太呆板,一定要照着那些条条框框,但我信任小宋教师我需求向他学习,他的程序有很高的价值。
9. 中止函数书写
10. 在函数中不管是被调函数仍是主函数都要懂得对一些变量进行初始化,这是一个好习惯,别以为没必要,或许繁琐。这其实不是繁琐,而是谨慎。写程序就应该有谨慎的情绪。
11.main函数的规范写法为:
int main(void)
{
……
return 0;
}
12. 在守时器溢出进入中止时,在履行中止时TF0或TF1会硬件(主动)清0,重新开端计数。但在串口发送或承受标志方位1并引起中止时,在履行中止过程中TI或RI 需软件(手动)清0.
13. 有关UART通讯守时器1方法2中 TH1 与 TL1(与TH1持平)的初始化。在实践核算中TH1 = 256 – 11059200/(12*32*9600); 能够核算得 TH1 = 0xFD; 但是当你把TH1 = 256 – 11059200/(12*32*9600); 写入编译器中让编译器来完结核算时,那么这样写便是过错的了,在keil里默许整数常量是 uint16 类型,取值为0~65535.故应写为TH1 = 256 – 11059200UL/(12*32*9600UL);要留意的是keil 对这类过错不报错!
14. 在串口通讯中,如:
串口调试帮手一般挑选“字符格局显现”。假如想显现数字则写入句子UART_send_byte(‘8’) ,要留意显现数字时只能显现一位即0~9;想显现字母时可写入句子UART_send_byte(‘A’)。留意别掉了‘’尤其是写数字时。写字母丢掉的话还会报错。写数字丢掉的话就不会报错。此刻显现的是数字相应的ASII码。
15. 若uint8 temp = ‘A’; 则 temp = ‘A’ + 1 时temp = ‘B’ , 即字符与数字相加为对应ASII码相加。
16. 在串口调试帮手中,要发送字符时不必带‘’因为软件现已默许带上了。
17. 关于对数组各元素赋值,有两种办法,如uint8 table [11] = “how are you”; 另一种是 table[0] = ‘h’; table[1] = ‘o’;……其间第一种赋值只能在界说数据类型时运用,如上所示。
在数据类型界说完毕后不能经过table [11] = “how are you”;来改动数组里边的元素,这样做在keil 下会有正告!但不报错,实践是不正确的。那么要改动数组的元素只能经过对里边元素逐一赋值。
18. UART通讯是从低位开端接数据,而I2C通讯是从高位开端接数据。
19. 关于bit 类型的函数。如
bit i2c_read_buf(uint8 *buf, uint8 addr, uint8 len)
{
while (len–)
{
if (i2c_readbyte(addr++, buf++))
return 1;
}
return 0;
}
在主函数中能够直接写为bit i2c_read_buf(&a, b, c); 也能够写为 y = bit i2c_read_buf(&a, b, c),将函数的返回值给了y。
20. uint8 table[] = “I”; 与 uint8 table[]={‘I’}; 两者运用时同等,但是前者为字符串,故比后者多一个字节。
21. 结构体分配的地址是接连的。如:
22. 关于结构体指针问题。先看看以下一些程序经过成果进行剖析得出结论.程序如下:
(1)成果为:44
是否就阐明结构体指针 p 指向了整个 int a 呢?
(能够从第一个字节地址开端逐一指向下一个字节地址直到第4个停止)
(2)接着把tmp={44}该为tmp={127};
成果为:127
依然正确
(3)持续改为tem={128};
成果为:-128
明显不是咱们想要的,假使 p 指向了整个 int a,那么成果应该为 128 才对,明显*p 仅仅指向int a的第一个地址。不会主动指向下一地址持续将剩余的3个字节读完,只要将剩余的三个字节读完才干读取一个完好的INT型数据。以上是在指针为char 类型的时分。(4)接受上面的,持续把char *p 改为 int *p
成果为 128
正常了。为什么?因为char类型指针一次只能放一个地址(一个字节一个地址),
而int *p 一次能放4个地址,所以此刻 p 能够一次指向4个int a 的四个地址
23. *p+1 的运算次序是先 *p 后 +1,不要误以为是*(p+1).
24. 如有数组 int table[]={111,323,3423,3322}; 指针 char *p; 且 p = &table;
那么 p 指向了一个地址(table的首地址),至于能够指向几个地址这个由指针的类型决议。现在指针类型为char而char占一个字节只能放一个地址,所以 p 一次只能指向一个地址,所以 *p != 111,因为*p只读取了111的第一个地址的数据,还有三个地址的数据没读。留意此刻 p+1不指向table[1]这个元素的首地址。而是指向第一个元素的第二个地址。能够做一下改进来一次读取4个地址,即让指针一次指向int类型数据的4个地址。
把 char *p改成 int *p,这样就能够一次指向四个地址了。则 *p = 111, *(p+1) = 232;留意括号一定要带上,不然成果是 112.
能够得出结论。p不是指向一个地址,指向几个地址由p 的数据类型决议。p + 1不是代表下一个地址。如 int *p,则p+1代表下一段接连的4个地址。能够理解为 p+1指向了4个接连的地址。在进行*(p+1)运算后将4个地址的数据接连读取出来,合成了一个完好的int类型的数据。
25. 有关数组的长度。如 uint8 table[]={‘a’}; 与 uint8 table[]=”a”; 后者是用字符串方法来进行初始化。需求留意的是 若有 uint8 *p=&table. 关于两者均有 *p=‘a’;但是关于 *(p+1)两者的状况却是不同的,后者有 *(p+1)= ‘’; 而前者却没有这种状况,在实践实验中是要推后几位才有这种状况。
26. 有关二进制(BCD码)与十六进制的彼此转化,0xFF—0b1111 1111 ,0xFE—0b1111 1110.
别离写成第一个数字或字母所对应的二进制数即可。至于二进制到16进制的转化也是如此,倒过来便是了。横竖记取,4位二进制数对应一位十六进制数。
27. 字符类型数据(uint8)在与整数运算时都是以ASII码方法或十进制数存在的。若uint8 型变量里边放的是字母或2个BCD码(8421),8位二进制数,在于整数进行运算时能够看出是ASII码或十进制数的运算。
28. 别误把if 句子当成循环句子了,if句子在履行时先判别括号内的句子是否建立,建立的话就履行{}里的内容(if句子嵌套的内容)。假如建立那么履行{}里的内容,履行完后不再进行一次if的判别,而是履行下一句子,即使判别依然建立。首要仍是要阐明if不是循环句子,只判别一次,不管建立与否,在履行完所需内容后就直接履行下一句子。
29. 关于取地址符号&的运用,变量本来就表明地址了,那么就不能再加&这样会报错。特别比方是数组名a,它本身就代表第一个元素的首地址。但能够运用取地址符号,且不会报错。加去地址符号后&a表明的意义发生了改动而是代表该数组的首地址,数值上好像与a的相同,但意义却是有不同的。
30. *p+1等价于(*p)+1,因为*优先级高于+;*p++等价于*(p++),因为++优先级高于*;
&a+1等价于(&a)+1.不能呈现&(a+1)的状况,体系不认同,会报错!
31. 关于数组 int a[4]={1,2,3,4}; 其间 a+1表明第二个元素的首地址(第一个字节的地址)。而(int)a+1表明第一个元素第二个字节的地址。
32. 关于结构体变量命名。如图
这种命名办法在KEIL下会报错,然而在VC++下却没问题。当你把code改成其他字母(不要与本来的code相同就行),你会发现都没问题。能够看出并不是命名的大小写出问题。原因是KEIL不认同以结构体小写字母来命名(这儿是指全小写),当你把其间一个字母该为大写时就没问题了。如把最终一行改成 CODE Code 让变量名的第一个字母为大写就行了。
33. 在单片机要进行通讯时要留意先关掉一切中止(EA=0),在通讯完毕后才翻开(EA=1).因为通讯时一般要恪守时序,而中止一旦被触发便会打乱时序,使得传输数据失利或许反常!留意通讯中时序是十分重要的!
34. 在通讯过程中需求留意,比方在传输一个字节数据时是一位一位地传让后凑够8位构成一字节的。要从低位开端传仍是高位开端传,要传低位开端接仍是高位开端接。这些不能处理好的话会直接影响到成果。也便是说发送端和接纳端要保持共同,有两种办法,一是从低位开端发(发送方),然后从低位开端接(接纳方)。另一种便是从高位开端发(发送方),然后从高位开端接(接纳方)。还有一个字节接纳和发送的方向也要共同,只要这些确保了,才干确保信息精确传输。比方:在UART通讯中,假如你要用单片机IO口模仿UART通讯就需求留意这些,一般采纳UART通讯的统一规范,从低位开端传输。这样跟规范UART器材就能很简单接上,不需求再作处理。当两个通讯器材都接规范UART接口时,那么就不必考虑这儿了,这个在传输过程中他们自己会进行处理,咱们无需考虑。只需把字节的排序弄好就行了。位的处理他们会自己完结。
35. 守时器1作业在方法1时的溢出是指在TH1=255(0xFF),TL1 =0的状况下,TL1到达255再 +1 就溢出了,此刻溢出标志位TF1=1,需求清零才干让守时器持续作业。不然不守时,而是处于等候状况,等候TF1=0,然后才开端守时。要澄清什么时分才会溢出!
还有便是TL1每加1表明现已守时一个机器周期,在12T/11.0592MHz的单片机中机器周期为12/11059200 s 大约为1us.也便是说TL1每加1表明现已守时1us 。而TH1加1就表明现现已历了256个机器周期。这儿说的+1并不会使守时器溢出,只要TH1到达255了那么接下来的256个机器周期后就会溢出了!
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/256656.html