吃鸡安装包有多大在C盘哪里

使用keil编译软件的常见错误
Error:&L6200E
&Error:&L6200E:&Symbol&temp&multiply&defined&(by&wenshidu.o&and&main.o).在编译的时候出现了这个问题,但是检查不出来,希望各位大侠帮帮忙
&什么变量你给付了两次值
你看看是不是那个外部变量你又给赋值了
main.c申明,其他.c文件对应的.h文件中用extern引用
error:&#20
error:&#20:&identifier&"TIM2_IRQChannel"&is&undefined&谁能说说,哪里错了
你的固件库里的库文件没有添加进工程里面,所以出现未定义的情况。
TIM2_IRQChannel指定时器2的中断通道没有定义,其实在固件库对这些参数都有定义,宏定义代替了一串寄存器地址数据。需要将.C文件添加到工程文件中
warning:&&#1-D&
main.c(7):&warning:&&#1-D:&last&line&of&file&ends&without&a&newline
当使用keil编译时,弹出这样的警告信息:main.c(7):&warning:&&#1-D:&last&line&of&file&ends&without&a&newline&
这个是由于在main函数的“}”后,没有加回车。
只要在main函数的“}”后加回车键,此警告信息即可消除。
...test_menu.c(27):error:#65:expected&a&";"
分数送你了,问题在你回答之前已经解决了,头文件里的结构体定义里的最后一行没有加";"&如&NB&menu{..};
error:&#1113:&
折腾了大半天,才搞明白一个空操作的指令
先在网上查有的说是__asm{NOP;},从intrins.h里调用,可犄角旮旯全找了,也没看到什么intrint.h的文件。如果直接用,就出现error:&#1113:&Inline&assembler&not&permitted&when&generating&Thumb&code&
最后搜索这条错误,知道是因为__asm("指令");这种语法是内联汇编(inline&assembly)的语法。而RMDK下,内联汇编仅支持ARM汇编语言,不支持Thumb或者Thumb-2汇编语言;但内嵌汇编器支持Thumb和Thumb-2。&
__asm放到一个单独的子函数再被调用就没问题了
__asm&void&nop(void)
然后在之后的C代码中调用该函数:
void&main()
来自KEIL官网
warning:&&#223-D
..\..\source\CCxx00_New.C(718):&warning:&&#223-D:&function&"_NOP_"&declared&implicitly
在使用的文件中添加extern&void&_NOP_();既可
warning:&&#1295-D
..\..\include\CCxx00_New.h(20):&warning:&&#1295-D:&Deprecated&declaration&CC_XCal&-&give&arg&types
没有用形参&定时时用void&CC_XCal(void);即可
Error:&L6218E:&Undefined&symbol
.\Obj\output.axf:&Error:&L6218E:&Undefined&symbol&FSMC_NORSRAMCmd&(referred&from&tft_lcd.o).
.\Obj\output.axf:&Error:&L6218E:&Undefined&symbol&FSMC_NORSRAMInit&(referred&from&tft_lcd.o).
Target&not&created
请教高人,我该如何处理。
你看看tft_lcd里面有没有添加fsmcXXX.h之类的头文件,这个错误是说你使用的函数没有被定义。一般只要添加相应的头文件即可
error:&#101:
error:&#101:&has&already&been&declared&in&the&current&scope
#ifndef&__STM32F10x_LIB_H
#define&__STM32F10x_LIB_H
#endif调整到最后!
error:&#247:&function&"DelayUs"&has&already&been&defined
有一个同名的&DelayUs类已经被定义过了
error:&&#109:&expression&must&have&(pointer-to-)&function&type
这个问题就是那19个error中的大部分,意思是表达式需要一个(指针)函数参数,我一开始以为是自己函数声明或者调用上的错误,但是看了下发现并没有错,后来查了好久发现原来是犯了一个很低级的错误:将宏定义和函数名重名了。因为我一开始想的是每一个宏定义对应一个函数名,这样做起来就比较清晰,但是我却很傻逼地将函数名每次直接复制到宏名,导致了这种蛋碎的结果。
warning:&&#61-D
warning:&&#68-D:
在KeilARM的LPCARM,存在(1&&31)编译警告问题
main.c(174):&warning:&&#61-D:&integer&operation&result&is&out&of&range
main.c(174):&warning:&&#68-D:&integer&conversion&resulted&in&a&change&of&sign
由于编译器默认signed&int即32位有符号整数类型,而1&&31实际为0x,
这样就有可能改写了符号位(最高位)
依此类推,(2&&30),(3&&29)...等都会出现编译警告问题.
解决办法为:&((unsigned&int)1&&31),((unsigned&int)2&&30),...
warning:&&#1295-D:&
warning:&&#1295-D:&Deprecated&declaration&ShowSendTime&-&give&arg&types
解决方法:将void&ShowSendTime()改为void&ShowSendTime(void)
warning:&&#550-D:
warning:&&#550-D:&variable&"d"&was&set&but&never&used
描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.
解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
error:&&#159:
.error:&&#159:&declaration&is&incompatible&with&previous&"wr_lcd"&(declared&at&line&40)
void&a(void)&//函数a的实体
&&&&&&&b();&//调用函数b
void&b(void)&//函数b的实体
&&&&&&&...
这样如果点编译,就会产生error:&&#159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.
解决方法:在函数a调用函数b之前,对函数b进行声明,如:
void&b(void);&//对函数b进行声明
void&a(void)&//函数a的实体
&&&&&&b();&//调用函数b
void&b(void)&//函数b的实体
error:&&#70:
error:&&#70:&incomplete&type&is&not&allowed
原来是重复定义了,包含了两次的psock的定义,所以才会出现这种情况。因为我发现psock和pt是一样定义的,但是pt是不报错的,所以我就试图删除头文件中include头文件的那一行,错误消除了,谢谢你了,还是实践出真知啊,有些时候不能死编,要思考,哈哈。
keil&MDK编译器警告和错误详解(不定期更新)&工作后从单片机转成ARM,刚开始用ADS1.2编译器,用了一段时间,因为我接手的项目的老程序正是用ADS编译的,部门也大都在用.在学单片机的时候用的是keil&c51编译器,ads和这个编译器在易用性上真是无法比较.后来渐渐知道keil已经被arm公司收购,现在keil&MDK成为了arm官方编译器,所以决定重新投奔keil,利用平时的时间,将原程序重新用mdk编译.mdk的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.
warning:&#550-D:
1.warning:&#550-D:&variable&"d"&was&set&but&never&used
描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
warning:&#1-D:
2.warning:&#1-D:&last&line&of&file&ends&without&a&newline
描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.
warning:&#111-D:
3.&warning:&#111-D:&statement&is&unreachable
描述:声明不可能到达.多出现在这种场合:int&main(void)
{...while(1)&//无限循环,这在不使用操作系统的程序中最常见{...}return&0;&//这句声明在正常情况下不可能执行到,编译器发出警告
}解决:不理会.
warning:&C3017W:
4.&warning:&C3017W:&data&may&be&used&before&being&set
描述:变量'data'在使用前没有明确的赋值.如:uint8&i,&//定义变量i和data,二者都没有明确赋值
for&(&i&=&0;&i&&&8;&i++)&//变量'i'在语句中被赋值0
{if&(&IO1PIN&&&SO_CC2420&)
data&|=&0x01;&//变量'data'在使用前没有明确赋值,编译器发出警告
elsedata&&=&~0x01;
}解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.
warning:&#177-D:
5.&warning:&#177-D:&variable&"temp"&was&declared&but&never&referenced
描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning:&#550-D:&variable&"temp"&was&set&but&never&used不同之处在于temp从没有使用过.
解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.与该警告类似的还有&warning:&#177-D:&function&"MACProcessBeacon"&was&declared&but&never&referenced
warning:&#940-D:
6.&warning:&#940-D:&missing&return&statement&at&end&of&non-void&function&"DealwithInspect2"
描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:int&DealwithInspect2(uint32&test)
{.........//此处应该是return&x;返回一个int型数据,若是没有返回值,编译器产生警告}
.warning:&#1295-D:
7..warning:&#1295-D:&Deprecated&declaration&lcd_init&-&give&arg&types
描述:在定义函数的时候,如果你写上函数参数,就会有这个警告,比如void&timer_init();&这里就没有形参,如果这样的话,编译器会给出警告.
error:&#65:
1.&error:&#65:&expected&a&";"
描述:缺少分号.大多是漏忘';'.解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.
error:&#65:&error:&#20
2.&error:&#65:&expected&a&";"和&error:&#20:&identifier&"xxxx"&is&undefined一块出现,而且后面的error:&#20错误可能一大堆
描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.解决:仔细检查.h文件,将分号补上.
Error:&L6200E:
3.&Error:&L6200E:&Symbol&flagu&multiply&defined&(by&uart0.o&and&main.o).
描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:
uint8&flagu=0;
在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:
extern&uint8&flagu=0;
然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:
extern&uint8&
解决办法:找到重复定义的变量,看情况修改一处.
error:&#159:
4.error:&#159:&declaration&is&incompatible&with&previous&"wr_lcd"&(declared&at&line&40)
描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:void&a(void)&//函数a的实体
{b();&//调用函数b}void&b(void)&//函数b的实体
{...}这样如果点编译,就会产生error:&#159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.解决方法:在函数a调用函数b之前,对函数b进行声明,如:void&b(void);&//对函数b进行声明
void&a(void)&//函数a的实体
{b();&//调用函数b}void&b(void)&//函数b的实体
error:&#137:
5.&error:&#137:&expression&must&be&a&modifiable&lvalue
描述:表达式必须是一个可以修改的左值.主要出现在这种现象:
NUM是一个数值或表达式,a为一个变量,但a被定义为像const这种不可更改的类型,导致NUM不能赋值给变量a.
解决方法:要么放弃赋值,要么修改变量属性.
.error:&#18:
6.error:&#18:&expected&a&")"
如果是出现在c文件中,&多半是因为少了一个")",或者错误行有编译器不识别的字符如果出现在头文件中,错误行又是一个函数声明,多半是因为在函数声明中有编译器不认识的字符
L107: ADDRESS SPACE OVERFLOW
用KEIL选用small模式编译一个程序时老时出错,信息如下。&
*** ERROR L107: ADDRESS SPACE OVERFLOW&
Program Size: data=217.6 xdata=0 code=5314&
Target not created&
芯片我选的是AT89C52,RAM有256呀,怎么会OVERFLOW呢?&但是如果编译模式选用Compact或large时就一切正常。&
Program Size: data=110.6 xdata=111
code=5914&
"test" - 0 Error(s), 22 Warning(s).&
---------------------------------------------------------------&
另外的可能性:
比如全局变量中定义的过多如下所示:
coma1,comb1,comc1,coma2,comb2,comc2;
局变量是不是用得太多了,另外用的是什么单片机,RAM总共有多大,定义变量的时候
一定要注意变量是定义在那个区域的,系统默认为直接寻址DATA区,但DATA区只有128个字节,很容易用完和溢出的,
51单片机超出128个字节的RAM区定义变量的时候一定要要变里前面加IDATA,
这样表明这个变量是定义在IDATA区的,IDATA区是128到256之间的间接寻址RAM区.
建意你在全局变量和数组前都加在IDATA
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。【图片】34岁“高龄”学单片机,第3天了,以此贴记录重难点,坚持!坚持_单片机吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:135,721贴子:
34岁“高龄”学单片机,第3天了,以此贴记录重难点,坚持!坚持收藏
先简单介绍下自己吧。高中毕业后家里经济上遇到点事就没继续读大学,自学了一些电脑基础后,朋友介绍去一家网络公司工作,做系统集成工程。后来在方正公司的维修站工作了2年,做返修管理和笔记本维修。也算是技术出身。06开始自己创业,做电脑配件渠道批发。本来嘛,生活可能也就这样安逸的过下去了,结果10年一次投资失败让我亏了上百万,到现在还没还清银行欠款,为还债,也就房子还没卖掉。整整颓废了2年啊。因为没资金了,生意也没什么心思管,全靠老婆在撑着。现在想想真对不起她。去年开始振作精神,因为有很多老客户的关系,生意慢慢也又有了起色。但经历这一劫,我开始慢慢懂得,做生意,玩资金是很不保险的。尤其是现在电脑行业整体低迷的情况下,生意更加难做。怎么样提高竞争力呢?资金是没什么了,赚点钱就要拿去还贷款,没有太多流动资金备货。那么只有靠技术了,但以前我所掌握的技术在现在根本不能称之为技术。就比如装机装系统,以前装个WIN98需要在DOS下操作一大堆命令,还得装驱动、装应用软件,整个弄下来要大半天时间。现在呢,一个GHOST20分钟什么都搞定了。以前做网络系统集成工程、监控什么的好像很神秘,现在呢,很多非专业的电工都可以去做了。以前笔记本上万块一台,换个主板怎么着也有几百块钱赚,现在一台笔记本便宜的两千多,坏了直接扔。一定要学一学能真正称之为技术的东西了。综合比较来看,我看上了硬件开发。起码以后如果自己开发出产品,凭借自己的渠道能力,销售上不会成太大问题。然而现在心里还有有点没底,到了我这个年龄,女儿都上小学了,再来学这个,还能学的会么,还能学的精么?即使学会了,在这个年龄去找个工作实习一下的机会可能都没有,只能靠自己摸索。(相关从业的朋友能不能给点建议)不过,既然决定要学,那也不能瞻前顾后。查了一些信息后,下载了郭天祥的视频(想想真是悲催,郭天祥比我还小2岁,看看人家,再看看自己。更加坚定了决心。),下载了相关的软件,proteus,keil4,以及各种需要用到的工具书。本来打算买块板,一两百块钱说起来也不算太贵,但后来看了一些介绍决定先用仿真入门,以后自己做块板。仿真的实验板找了2版不同的,第一个后来发现问题挺多,就又找了一个。TX1-C-1.0这块蜂鸣器一直会响,同时做流水灯实验时做不成功。下面这一块TX1-C型实验板基本就很好了,用之前把蜂鸣器的三极管Y镜像一下就可以正常使用了。(这里有个小问题,郭天祥视频里可能对这个开关三极管讲的不对,后面再说,请高手解读一下) 下载地址我忘记了,有需要用的朋友说一声我发给你们把。
先说说对学习方法的理解。我觉得郭天祥的方法很好,在做实例的同时穿插学习所要用到的知识点。当达到一个层次的时候再回头学习一些以前难以理解的概念。这样可以很快的入门,同时不会产生畏惧和放弃的心理。虽然基础可能会不牢,但掌握了基本方法,有了基本的理解,基础可以慢慢补。那时就容易多了。我在学单片机之前,本来给自己的计划是先学易语言(因为自己英文底子不好,想通过中文编程来入门,了解编程的基本方法和思路),然后学C语言和模拟电路数字电路,然后再学单片机。其实这就是一种畏惧心理,不敢碰,怕碰了以后学不会反而打击了积极性。可是在学易语言的过程中(大概学了一个多礼拜),偶尔看到了郭天祥的那本《新概念51单片机C语言入门、提高》后,突然发现郭天祥教授的思路和我学习的方法非常契合。比如我学易语言时就是这样,简单看了2天基础概念,就开始做一个返修管理软件(自己刚好公司要用,网上又找不到合适的),在做的过程中,碰到不会的就去查资料,感觉到基础知识不牢,就去系统的看书。软件很快做了大半,老婆一天看到了,很惊奇的说你怎么还会这个。我告诉她我业余学了一礼拜她根本不信,她每天睡的早,还以为我在书房天天弄到半夜是在玩游戏。本打算把易语言学精通,然后学好C语言和模电数电再来学单片机,但现在发现跟着郭的视频和思路走,根本不必要这样。因为我时间耗不起。
下面是之前用易语言做的返修管理,还没完工。 呵呵等一鼓作气跟着郭天祥的视频学完这十几天的课程,我还是要把它给做完的。
接下来进入正题了。先总结一下这几天碰到的一些印象深刻的东西。1.仿真板就是个虚拟的开发板,在proteus通过菜单“打开”来打开运行,或者直接双击仿真板的文件也可以。仿真板所运行的C语言源程序是在proteus运行仿真板后,通过双击仿真板上的单片机,然后选择电脑里的路径来打开,相当于给开发板下载源程序。仿真板可以和KEIL设置成同步调试(似乎是需要装个KEIL驱动,有点记不清了,我也是按网上的教程做的)。这样后面使用起来就很方便了。2.郭天祥视频第2课里的例子:while(1)
while(a--) ;
while(a--) ;
while(a--);
while(a--);
}这里我开始始终不理解怎么延迟,程序又是怎么走的。后来慢慢明白了。给变量a赋个值51000,然后去循环减它,至于减的速度跟系统频率有关,也就是说,系统(CPU或总线)运行的越快,这个值减的就越快。51000这个数看起来很大,但系统给减完就几百毫秒。这个程序运行的顺序是自上而下的,,打开后,减完第一个51000,这时候a=0了,因为a!=0是while()为真的条件,于是while(a--)循环的条件就不具备了,于是跳出循环,继续执行下一条语句。然后再打开LED,再减个51000,这样做的原因是定义的变量是无符号整型,最大只有65535,我们要让它多延迟一会的话,就得再写一条,而不能写a=102000。执行完后接下来再去关闭,再去延迟。因为外面还有个while(1)大循环,所以只要不断电,等会一直闪下去。总结下来,这里我开始的不理解可能是忽略了当a减到0的时候while(a--)会跳出循环继续执行下一条语句。导致整个程序没能理解。
谢谢大家回帖。下面我赶紧先把前几天碰到的问题写下来,写完暂时就先不回复了。总结一下,对自己也算是复习和存档,以便日后查阅加深印象。3.关于C语言语法暂时碰到的主要是分号的用法。刚开始有点糊涂,总结一下:带#号的: #include 和#define 这些语句后面不加分号声明变量要加分号声明子函数要加分号调用子函数也要加分号但建立子函数时不要加分号(后面有大括号的都不要加分号)执行的动作、定义变量这些,赋值语句都要加分号
4.关于进制转换感觉在单片机里,主要要掌握16进制&—&2进制互相转换。我看郭天祥视频里算的非常快,自己于是研究了一下算法。2进制转换为16进制比较简单,口算基本没问题。通常算法为:比如 换成10进制:11012的3次方+2的平方+1=8+4+1=1301012的平方+1=5那么16进制就是0xd5如果还想更快,那么就要记得几个基本的数:2的3次方是8,在千位上(就好比10的3次方是1000)2的平方是4,在百位上 ,2的一次方是2,在10位上。记住这几个数,1101就可以直接反映到脑子里8+4+1=13这就个是熟能生巧的事。16进制转换2进制就麻烦点了,口算有点累,正常算算要打打草稿比如0xfa正常算法为:f=15 a=10那么就是15,10就是 15/2=7 余 1
余 1结果就是111110也同样但这样算太麻烦了 搞不好还要错单就F来说 ,完全就可以直接记住,就是1111至于10,我觉得可以分解一下来算:10=8+28是2的3次方,在10进制中,10的3次方是1000,在千位(第四位)上,于是在2进制里也是在千位(第四位),那么就是1000, 2是2的1次方,那么在十位上,就是10,于是合在一起就是1010这种算法是不是很直观简单?扩展开去,再大的数,转换成2进制都不难算.当然超过16基本在这里用不到比如135=128+7=128+4+2+1=2的7次方+2的平方+2+1于是就是
,100 ,10 ,1'合起来就是用这种算法最好记住这些数:2,4,8,16,32,64,128,256,512,,是2的几次方。对我来说,因为本身做电脑,这些数就是内存大小,倒是很熟悉。记住以后,看到一个数,基本很快就能心算出来,顶多用笔稍微辅助一下。如果要算的数是254这种数,比128大很多,但比256只小一点,那么可以这样来:256=254=256-2那么就给退位256-1就变成256-2就是 这里还是有点绕的,写了好长时间 呵呵
5.还是关于进制的开始犯了概念性错误,视频里也没讲清楚,查资料才了解到:举个例子,比如流水灯p1^1
1我开始以为这个“位”的16进制数为:0xeb实际上应该是0xd7错误根源在这个状态表示为16进制数应该从后往前数是而不是原因是跟10进制一样,数字从左往右排列的顺序是从高位到地位,P1^8口是高位,所以应该在最前面,P1^1口在最低位,所以要在后面结果表示出来就是
先写到这里,吃完饭继续
吃完饭就睡着了,醒来还是惦记着把前几天学习的先给总结完。6.关于数码管和锁存器视频里的图不太好理解,看了半天,视频里学生似乎也没弄明白。后来在纸上画了个图就明了了。单片机控制数码管流程为:DU和WE锁存控制口控制位选和段选锁存器的打开和关闭。先打开位选锁存器的开关,给连接位选锁存器的WE1到WE8口要打开的某一或某几个数码管送低电平。由于WE1-8是共阴的公共端,所以要送低电平。然后关闭位选锁存器,这样就空出了和位选锁存器的共用线路,并且因为锁存器的特性,在位选锁存器另一端保持了在WE1-8的电平信号。再打开段选锁存器,给某一或某几个数码管中某几个二极管(a到h的其中几个)送高电平。这样,在这些二极管的阳极和共阴极都有了我们需要的电平。于是我们想要点亮的数码管就可以点亮,并且显示我们希望它显示的数字。
事实上,通过段选锁存器是给所有数码管中我们想要点亮的二极管送高电平,但因为首先已经“位选”了的缘故,没那些被“位选”给阴极送低电平的数码管尽管阳极有高电平信号,但因为其阴极也是高电平,所以不会有压差,于是不会亮。
7.关于蜂鸣器的开关三极管原图:视频里说要改成这样才对:这个我始终还没闹明白。我在仿真里把这个三极管Y镜像一下,让发射极接地,集电极连接蜂鸣器和VCC,变成他在视频里说的,蜂鸣器就再也不会响了。查了资料大概能确定郭天祥在视频里讲错了,原来的原理图是对的。但因为没有模电基础的缘故,不知道怎么分析。 另外,查资料的过程中,在一个论坛上看到,说这种接法三极管没能饱和导通,所以即使蜂鸣器会响,也不是满功率运行。有没有模电比较好的朋友帮忙解析一下,弄不明白始终放在心里是个疙瘩。谢谢了!
8:时钟周期=晶振震荡频率的倒数一个机器周期=12个时钟周期复位电路提供2个机器周期,也就是24个时钟周期的高电平,就可以让51单片机复位。例如:TX1C开发板用的晶振频率为11.0592MHZ那么,机器周期为1/11.0592MHZ ,约等于1/11.1微秒于是,机器周期为:12/11.1微秒,差不多就是1微秒多点的样子所以要想给TX1C复位,只要提供2微秒多点的高电平就可以了这下比较有感性认识了,虽然微秒是多长还是感觉不出来,不过随便怎么按一下起码也得几十到几百毫秒把。不过这个时间对于复位电路中的电容应该还是有意义的。视频说,每次启动时,电容都会放电,给单片机复位管脚一个高电平以便让单片机复位。于是,我想电容的容量应该和这个放电时间密切相关。谁来告诉我怎么计算这个电容的取值,以便能让他放电时能够满足复位的时间呢?又是模拟电路,看来学完视频得好好把模电学一学。
抽空看了第三课后半段的视频:中断、定时器。硬着头皮看完了,大部分还是不知道讲的什么,各种名词和新概念,有种听天书的感觉。基础啊基础。。晚上回去的计划就是看书,仔细把单片机结构和各部分作用系统的看一遍。理解以后再来写总结。
中断和定时器这一块总算给弄明白了,一看时间居然4点了。明天早上还有个单位的服务器和机柜要送去安装,看来这觉也别睡了~卡在这整整迷糊了1天,究其原因,主要是突然冒出很多名词和字母,SCON,TCON,IE,IP,以及他们的控制位IT0,IT1,EX0,EX1,还有什么IE0,IE1,TF0,TF1,TI,RI,PX0,PX1,PT0,PT1,PS。还有各种基本概念。再加上之前连40个引脚的功能都还没完全记住,一下子把人整晕了。我觉得如果是跟着郭天祥视频走的朋友,到这八成都会跟我差不多的感觉。今天主要补了单片机内部结构的知识,还看了几集浙大高峰老师单片机关于单片机结构和内部机制的视频(CPU机制差点看睡着了,高老师声音太有催眠的力量了~)然后再回过头来看书,画原理图。突然看到一张之前没怎么太在意的图,发现这张图弄明白就全明白了:
把图片编辑一下,便于理解:1.蓝色框里框的实际上就是P3口的6个引脚(还有两个引脚是控制外部存储器,在这没用)。INT0和INT1送入的是外部中断请求。T0,T1送入的是定时/技术溢出中断请求,TX,RX(就是TXD,RXD)送入串行中断请求。2.红框里框的实际上就是特殊寄存器。所有的中断请求都是送到特殊寄存器来处理。外部寄存器处理这些请求用到的工具是绿框里的TCON,IE,IP。3.至于IT0,IT1,IE0,IE1,TF0,TF1等等这些,是TCON,IE,IP所包含的控制位。这些开关的符号,在写程序的时候都是可以给他们赋值的。或0,或1,代表不同的意义和功能。4.最后,在经过IP人为控制的优先级的选择后,分出1组高优先级和1组低优先级的指令集。在这两组内部,在通过自然优先级进行优先级的排序,最后把指令按优先级一条一条送入PC指针。说白了,这张图看明白,还有每个名称对应的意义给搞明白,其实也不难。纠结了我那么久,说起来全是泪。。。
这张结构图也可以作为参考,以便理解。我的理解是这样(不知对不对):中断指令虽然是送入SFR处理,实际上仍旧是依赖中断系统的处理,只不过SFR来控制罢了。而中断请求的提出是由外部中断源、定时器/计数器、还有串行口所提出的。经过一系列的控制后,拒绝一部分中断,然后把被允许的中断送到IP去排序,最后一条条送入PC指针,等待CPU执行。打个比方就好像SFR是厂长,中断系统是工人,定时器、串行口、外部中断源是厂里的家属和外面客户。这些家属和客户给厂长写信提出某些要求,厂长指挥工人们去按照要求的重要性一个个去解决问题。
呵呵,有没有玩过这个东西的?没想到啊~~刚才把贴在芯片上的纸抠掉,居然是51
第五天了,视频跟到第四课一半多。做到数码管组的1-6个数码管依次显示1 2 3 4 5 6。程序跟着视频写下来怎么都不对。每次走到5就后三个数码管一起显示,再往后就彻底乱掉。查了半天也没查出原因。今天太累了,先去睡觉 明天再说~
这两天公司实在是太忙了,每天回到家都要半夜。不过也没有放弃学习,第四课算是跟完了,第五课前半部的例子代码也已经写完,不过却有点小问题,仍然在找。我是这样一个人,一个问题解决不掉,就钻在里面出不来。随着课程的进度,代码越来越复杂,理解起来变得更难,错误也更加隐蔽难查。于是现在的进度开始变得缓慢。老婆看我学的认真也比较支持,说,最近你就在家里学吧,公司有事情再过来。这样也好,能集中精力一鼓作气把剩下的课程跟完,剩下的就是慢慢练习和巩固了。
一直有朋友回帖和发消息希望分享一下创业的心得。说实话,还真是不敢随便聊这个。一是因为自己做的并不好,之前还栽了个大跟头。二是自己做的电脑行业和单片机从业人员创业肯定又有很大不同,隔行如隔山,说的不对被人笑话还在其次,要是误人子弟就罪过大了。不过抵不过朋友们的热情,今天学习上也没什么太多要总结的,就简单聊一下自己这些年的一些心得供大家参考一下,看问题的层次可能比较低,想到哪说到哪也有可能说错。只是抛砖引玉,希望大家给予批评指正。首先从一个公司的成立说起吧。公司成立很简单,没什么特别的要求。就是麻烦点,要多跑几趟。如果懒得跑,花个几千块钱,有专门的代办公司帮你把所有的事情办好。但公司成立了,即将面对的就是怎么生存下去。就算是最小的写字楼,地段稍微好点一个月也要好几千,加上自己和员工的开销,一个月最少最少也得七八千到万把块钱的费用。也就是说你每天一睁开眼,几百块钱就没了。你就得想办法利用你的公司把这钱赚回来。说这些主要是要提醒一些准备创业的朋友,你准备好承受这压力了吗?同时这也说明了,对一个公司来说,利润点非常重要。甭管你有再远大的理想,更别管一些人告诉你要放弃短期利益追逐长期利益。首先你得活下去,如果你连房租和工资都付不出来了,其他都免谈了。所以,最好在你开公司之前,就有一定的客户愿意追随你,这样最为稳妥。当然,对于资金充足,有条件承受风险和压力的朋友或干脆是拉到投资的朋友来说,这都不是事。公司开起来了,也初步运行起来了,接下来就是求发展。很多人都是卡在这里,于是不死不活的熬着。我大概也算是这一种。吃穿是不愁,但受各种原因影响,想发展壮大却是无从入手。之前说的投资失败亏了一百多万就是在这种情况下发生的。辛苦经营了好几年,赚了点钱,想发展,想壮大,却一步踩空。伤心事也不想提,就简单说2点,你打算投资的时候,一是要看你对这个行业有没有充分了解,最好能自己进去做几个月,哪怕是给别人当员工做几个月。二是投入多少资金,一定要在投入之前就做好亏光的准备,然后再想想,自己能不能承受这样的损失。没有人会去投资一个自己没把握的事,但仍然很多人会亏,这就说明有很多事情不是你在计划阶段所能预料到的,是不可控的。所谓谋事在人成事在天,所以一定要做好最坏的打算。那么公司到底应该怎么发展呢?以前我关注的是客户,是产品。我一度认为,只要努力,就会有无穷无尽的客户,有了无穷无尽的客户,就会有更加好的产品资源。然而,事情并非如此理想化,其中影响最大的是大环境。一旦大环境发生变化,小生态就无以为继。比如,08年的时候,我单月的出货量达到将近200万,对于一个刚起步没多久的小公司来说,这是相当不错的成绩。然而以后的发展出乎意料,随着整个行业的不景气,客户不断流失,一部分是因为大家都吃不饱,竞争变的更加激励,客户被别人抢走。还有一部分客户是自己倒闭了的。而且在这种大环境下,开发客户变得异常艰难,甚至即便开发出客户,有很大一部分也不是优质客户,提货量少、拖款甚至跑路,弄的我疲惫不堪。09年一年中几乎每个月都要出去讨债,甚至还打了几场官司。所以,客户和产品是很重要,但在它们之上,还有更为重要的东西。这种东西才是核心竞争力,才是公司和企业发展的根本。而这个东西是什么,我慢慢才有所领悟。起初我认为是资本。资本固然重要,甚至是决定性的。然而对于刚开始创业和准备创业的朋友来说,拥有足以在某一领域能够占据优势的资本,几乎是可望而不可及的。那么还有什么,服务吗?技术吗?所谓服务,也分服务态度和服务内容,服务态度大家都可以做的很好。但服务内容呢,因为一个服务型公司,在创新上所能做的很有限,只要用心,服务的内容也没什么门槛,你能做,别人也能做。那么你的竞争力在哪。除非你不断的开发出新的服务项目,让别人跟着你走,这样你就能够占据一定的优势。这也就引出了我说的核心竞争力:差异化。只有差异化才是公司的核心竞争力,当你做的东西100%别人都能做,那么你面临的竞争将大的不可想象。当你做的东西只有10%的同行才能提供,你会发现一个客户询价询过来,只要是他需要的,就跑不掉了。这也是我现在要学习单片机的原因。因为学会了可以自主开发,可以按照自己调研的市场需要去开发与别人不同的东西。这就是技术的优势,技术可以创造出差异化,而服务很难。资本也可以,但初期很难获取到足够的资本。当然你也可以说:你不用去自己开发啊,你可以请人来开发啊。然而我现在不具备这样的条件了,也许几年前可以,但现在我只能靠自己了。而且,自己学会的东西永远是自己的财富。即便以后有条件了,自己懂也不至于外行领导内行。以此激励朋友们好好学习单片机。
说起来,感觉学到这,最困难的就是写代码了。思路是最重要的,思路要清晰,设计要巧妙。这一点最为困难。目前理解起视频里的代码有的时候都很困难,有时候想的头都要炸掉了。尤其是第五课开始的那个例子, 我会说自己有点眼花缭乱么。思路开始变得不那么清晰,有些细节也开始不太明白。在什么时候什么位置该把变量置0,为什么有些是要置1。希望不是自己太没天赋,而是不熟练的缘故。 不过在第四课学完后,郭天祥的几句话给了我一些鼓舞,他大意是说:“后面没什么东西了,单片机最重要的就是中断系统,定时器和串行口,我们现在基本学完了,后面的很简单。”呵呵
另外交代一下,仿真做数码管动态显示的实验出了不少的问题,比如我这里每次显示到5的时候,后4位就一起显示。另外,只能慢慢的一个个显示,如果调低了延迟,就会出现乱闪的结果,完全实现不了动态显示。综合分析应该是硬件电路的问题。有没有用仿真做成动态数码管的显示实验的??求指导~~看来初学买个实验板还是更加靠谱一点。能推荐一下吗?
另外有个问题很迷惑,定义变量时什么时候使用unsigned int 什么时候使用 unsigned char,我看视频里很多我认为应该定义为Uint的都定义成了Uchar,,这样有什么好处呢?省空间?
继续更新这两天主要在回头分析之前写过的那些程序,因为学完中断和定时后,需要理解的原理少了,而单片机中C语言编程的思路的重要性越发凸显。在分析这些程序的过程中,一方面复习了之前学过的知识,另一方面也对单片机的编程有了进一步的认识。我的体会是:1.在做例程时,必须理解每一条语句的内在含义。单片机的语句都很简单,但是,同样的一条语句,使用的位置不同,却产生了完全不同的意义。2.写程序时,对单片机电路的整体和细节都要有把握。这样才能做到理解并灵活应用。3.得动态地把握电路的变化,每一条代码都会改变单片机电路的状态,思路必须跟的上。编程本来就够抽象了,电路也是抽象的,必须做到把这些抽象在头脑里具体化,逻辑还得连贯。我觉得单片机最难可能也就是这里。比如定义了一个给中断计数的a,到哪一步这个值必须要清零,在某时用这个中断时应该取什么值来判断。又或者经过一连串的键盘抖动检测的while或if嵌套后,一条语句具体应该放在哪个循环内,没搞清楚某时的电路和程序的状态,放错了地方肯定会出错。还有标记位的调用等等 .表达不清楚,总之就是这个意思~~或许这只是我作为新手的困惑,高手运用语句可能就如用自己手脚眼睛一般随心所欲。
第五课开始讲的那个例题感觉非常经典,几乎综合了之前学过的所有东西。所以我着重复习了这个。并给程序加上了注释,以备查阅: /*程序流程:程序初始化时为6个数码管显示765432 ---&通过“定时器1”来让这个数以1/10秒的速度递减至765398, 同时流水灯从上到下流动,使用“定时器0”控制其速度为500毫秒每次。 ----&数码管递减完成后,停止,流水灯停止流动,开始闪烁。 3秒后(定时器0控制)---& 关闭流水灯
数码管显示HELLO*/#include#include
//流水灯要用到_crol_()#define uint unsigned int#define uchar unsigned charuchar code tabledu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76,0x79,0x38,0x3f,0x00};uchar temp,t0,t1,flag,flag1;uint num,speed,bai,shi,sbit duan=P2^6;sbit wei=P2^7;void init();void display(uint,uint,uint,uint,uint,uint);void delay(uint speed); void main(){
//调用初始化子程序
if(flag1!=1)
//调用中断0中定义的flag1,如果标志位flag1不等于1,则继续执行数码管减数到398的子程序,
//如果flag1=1,则执行else{}中显示HELLO的显示子程序。
display(7,6,5,bai,shi,ge);//调用数码管显示子程序(前3位因为不变so直接赋常量)
display(16,17,18,18,19,20);
void init()
//初始化子程序。{
//设定个延时的速度,即扫描显示速度。
//给num赋初值432
//给temp赋初值。
//temp值赋给P1口,即让第一个发光二极管亮
TMOD=0x11;
//给中断0和中断1的TMOD寄存器赋值,确定其工作方式
TH0=()/256;
TL0=()%256;
TH1=()/256;
TL1=()%256; //给中断0和中断1的高8为何低8位赋初值,定时为每50毫秒中断一次。
//此处的理解为:将50000微秒分配到高8位(最大65536)和低8位(最大256)中, 中断即可识别出我们要定时多久。
//打开IE总中断
//打开IE的T0和T1中断
//启动中断T0和中断T1 } void time0() interrupt 1
//中断0{ TH0=()/256; //中断开始时,必须再次初始化高8位和低8位 TL0=()%256;
//定义变量t0自加,即t0为每次中断自加一次,为中断计数。
/*备注:中断中写程序最好不要写太多
一方面难查,另一方面程序执行需要时间,
每条单周期指令大概1微妙,超过中断时间
会影响中断的执行。更加注意不要写延时。*/
if(flag!=1)
//调用中断1中的标志位flag,如果成立,继续执行if{}内语句(流水灯流动),否则执行else{}中语句(流动灯闪烁(调用前已在中断1中停止流动))。
if(t0==10) //如果时间流逝500毫秒,执行IF{}内语句。
temp=_crol_(temp,1);//左移一位 ,即流水灯换下一个点亮。
//再将TEMP赋给P1口
//else内代码为实现流水灯闪烁。
if(t0%4==0)
//T0中断每进入一次为50毫秒,我们让其200毫秒闪烁一次。 所以给T0的条件就是:4的整数倍,表示为t0%4==0, 同理,如果是每50毫秒闪烁,就是t0%1==0,100毫秒:t0%2==0
P1=~P1; //给所有的P1口(所有流水灯)值取反。
//以上2条语句在代码内实际意义为每隔200毫秒对P1口的值取反一次。即实现了流水灯每400毫秒亮灭各一次,达到闪烁的目的。
if(t0==60) //如果t0=60,即闪烁了50毫秒*60=3秒
TR0=0;//关闭T0定时器
P1=0//把P1口关闭。为什么0xff是关闭?
flag1=1;//定义一个标志位flag1,赋值为1,给中断1调用,用于实现HELLO的显示。
void timer1() interrupt 3
//中断1{ TH1=()/256; TL1=()%256; t1++;
//当t1增加至2时,时间流逝100毫秒,即1/10秒
// 对num自减
bai=num/100;
shi=num%100/10;
ge=num%10;
//将num分解为bai,shi,ge,便于table数组单独调用)
if(num==398) //如果num自减至398
//关闭流水灯定时器T0
TH0=()/256;
TL0=()%256;
TR0=1; //打开T0定时器。以上4条语句为将T0定时器还原并重新打开,准备写3秒钟计时。
P1=0 //关闭P1口。即初始化流水灯,等待闪烁。重要,否则会有1个流水灯闪烁很大可能与其他7个不同步。
//关闭数码管定时器T1
flag=1; //当执行至此时,定义标志位flag并赋值,给中断0拿去调用。
} //为何视频中写在P1=0xff前,主函数调用flag仍然可以使P1=0xff起作用?
}} void display(uint aa,uint bb,uint cc,uint bai,uint shi,uint ge)//数码管显示子程序。{
//存疑。为何必须先送段选?
P0=tabledu[aa];
//如果先送位选,数码管的数字会整体右移一位,最后一位跑到最前。
//重要,给P0口送个无显示的空值。无此语句,段选口的送的值保持在锁存端,接着位选一打开又会送给位选,和位选送的值混在一起,导致数码管显示混乱不正常。
delay(speed);
P0=tabledu[bb];
delay(speed);
P0=tabledu[cc];
delay(speed);
P0=tabledu[bai];
delay(speed);
P0=tabledu[shi];
delay(speed);
P0=tabledu[ge];
delay(speed);} void delay(uint speed)
//延时子程序。{ uint x,y; for(x=x&0;x--)
for(y=110;y&0;y--);}
网上找的仿真图好坑的说,就没一个功能都能用的。。好容易找到能正常用动态数码管的,结果矩阵键盘又不能用。又找了几个,终于发现矩阵键盘能用的,一试除了矩阵键盘能用,其他问题一堆 呵呵画仿真图的时候都不测试的啊~~以后有时间得好好学学proteus,争取自己画。
矩阵键盘检测。视频里现场写的代码给弄复杂了,难理解,简化一下以后好多了主要就是那个与操作是不必要的。把按键取出的数与了以后,最后还要再重新从P3口取完整的数。因为如果不重新取P3口完整的值,会导致扫描2 、3、4行时取得同样的值。比如第一行第一个键被按下取的值是0xee,和0xf0与操作后得到0xe0。扫描第2行时,按下第一个键,取得的值是0xed,和0xf0与操作后仍然是0xe0,剩下的也同样。就没法区分了。所以完全没必要做“与”操作,增加了复杂性,还容易出错。第一行直接判断是否为0xfe,第二行直接判断是否为0xfd,以此类推,就可以了。 #include&reg52.h&#define uint unsigned int#define uchar unsigned charsbit duan=P2^6;sbit wei=P2^7;sbit d1=P1^0;uchar temp,uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delay(uint); void main(){wei=1;P0=0xc0;wei=0;duan=1;P0=0x00;duan=0;while(1) {
temp=temp&0xf0;
if(temp!=0xf0) *///这里视频写的“与”操作根本多余的吧,改掉~~。
P3=0 //第一行赋值为0,P3值即为0xfe
if(temp!=0xfe) //如果为真,则执行if{}内代码,如果为假,
//则跳出if{}执行(去检测第2行按键有没有被按下)
//视频里用while循环,感觉用if好点。
//temp=temp&0xf0;
//if(temp!=0xf0)
if(temp!=0xfe)
temp=P3;//取回P3口的值(有可能是按下某件得到的值,必须要取),在swith case语句中进行比较。
switch(temp)
case 0xee:num=0;
case 0xde:num=1;
case 0xbe:num=2;
case 0x7e:num=3; //分别比较几个算好的码,相同则赋给相关的值,并将其值赋给num,以方便显示时调用。
P0=table[num];//打开段选口,让P0口显示数值
//注意,这里,必须放在最里面的if下,否则逻辑出问题。
while(temp!=0xfe)//松手检测。
P3=0 //将第2行赋值为0,P3口的值即为0xfd
if(temp!=0xfd)
//开始扫描第2行有无键按下
temp=temp&0xf0;
if(temp!=0xfd)
switch(temp)
case 0xed:num=4;
case 0xdd:num=5;
case 0xbd:num=6;
case 0x7d:num=7;
P0=table[num];
while(temp!=0xfd)
P3=0 //开始扫描第三行有无键按下
if(temp!=0xfb)
if(temp!=0xfb)
switch(temp)
case 0xeb:num=8;
case 0xdb:num=9;
case 0xbb:num=10;
case 0x7b:num=11;
P0=table[num];
while(temp!=0xfb)
//开始扫描第4行有无键按下
if(temp!=0xf7)
if(temp!=0xf7)
switch(temp)
case 0xe7:num=12;
case 0xd7:num=13;
case 0xb7:num=14;
case 0x77:num=15;
P0=table[num];
while(temp!=0xf7)
temp=0xf7;
} }void delay(uint z) //延迟子程序{ uint x,y; for(x=z;x&0;x--)
for(y=110;y&0;y--);}
帮一个吧友解决了一个自行车里程速度表的编程思路,还是挺有成就感的。 现在开始考虑今后做产品的问题了
登录百度帐号推荐应用

我要回帖

更多关于 吃鸡游戏安装包多大 的文章

 

随机推荐