学东西可不可以一步登天猜一生肖?

在理想与现实中纠结_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
在理想与现实中纠结
阅读已结束,如果下载本文需要使用
想免费下载本文?
你可能喜欢【社建学习单片机日记】希望自己能坚持写下去|我爱单片机 - 数码之家
查看完整版本: [--
&Pages: ( 2 total )
赞助商链接
本来想在百度申请个贴吧的,谁知道都没有音讯了,还有我原来申请的贴吧成了别人的了,这是怎么回事?乱整啊,还是在数码之家这里开个帖子算了。我本人比较笨,学单片机6年了,还没有入门,唉,太菜了。还有就是自己的定力、恒力、心态不行,三天打鱼两天晒网的,还有就是容易转移目标,今天搞这个,明天搞那个,最终一样也没有搞成。还有自己平时需要搞维修赚钱,所以需要抽时间学习,平时也没有什么娱乐活动,就是一个人宅着。现在我就坚持学下去,希望高手不吝赐教,大家互相交流学习,高手不要嫌弃我们问的问题太简单,新手也不要嫌学习艰难,互帮互助,共同提高吧,预祝成功。
赞助商链接
我支持你&&我也是菜鸟 相互讨论学习
赞助商链接
刚开始阶段都是仿别人的程序,把别人的程序改来改去的,使劲折腾,现在发一个闪灯程序,有需要的可以下载玩玩。也有hex格式的文件,大懒蛋可以直接下载查看。#include&reg51.h& #define uchar unsigned char #define uint unsigned int sbit LED=P0^7; //延时 void DelayMS(uint x) {
while(x--) { for(i=0;i&120;i++); } } //主程序 void main() { while(1) { LED=~LED; DelayMS(150); } }
延时大多数用for嵌套的形式,写程序要养成注释的习惯
学了6年,还在研究点亮LED?
哦,我做一下注释和说明哈。这样一个LED闪烁的,随便什么单片机都可以的,比如40脚的89C51/52,20脚的89C2051,8脚的STC15F104灯都可以实验,只是改下程序就可以进行了,我会在注释中说明的,注释不对之处,请指点,谢谢。#include&reg51.h&&&&&&&&& //单片机头文件,必须有的东东#define uchar unsigned char&& //这好像是什么定义#define uint unsigned int&&&&&&&&//跟上面差不多sbit LED=P0^7; /*这是引脚定义,就是P0口第8个脚【32脚】接发光管,这个可以随便的定,看你需要了,比如STC15F104E,只有3.0到3.5,那么这里可以定义为=P3^0&&&&&&*///下面这一段是延时子程序,是主程序的插曲,主程序工作时,动不动就会哼哼几声,放松心情,做事休息两不误。 void DelayMS(uint x) //这句是延时单位毫秒,也有的程序是微妙,微妙写成US{
//这句前面uchar就是程序第二行define uchar unsigned char 定义的简写,i就是第三行的简写。while(x--) { for(i=0;i&120;i++); //for就是如果,上级部门要求i=0,如果不等于0,而是i&120,需要这哥们你要加班啊,做+1工作。} } //主程序下面才是重中之重呢,因为这是主题曲,开工就唱这歌,上面那些只不过是插曲,铺垫。 void main() { while(1) //这个貌似是循环功能的,没有这个的话程序就随机动作了,或者工作一次,就是灯亮一下,也许一次也不工作{ LED=~LED; //这句就是取反的意思吧,假如刚刚是亮的,执行到这句,你给我灭。DelayMS(150); /*这是延时时间,单位是毫秒,150就是150毫秒,0.15秒,想要他闪烁的快,就改小点,比如100,想要闪烁慢,就改大,比如500*/} }
你这注释也太复杂了。#define是定义宏,#define后第一个词代替后面的词
#include&reg51.h&#define uchar unsigned char#define uint unsigned intsbit LED=P0^7;&&//LED接P0.7void DelayMS(uint x)&&//延时子函数{while(x--){for(i=0;i&120;i++);}}void main()&&//主函数{while(1)&& //大循环{LED=~LED;&& //取反LEDDelayMS(150);&& //延时150}}
再来个流水灯,明天再注释,感兴趣的可以注释下。/* 名称:从左到右的流水灯 说明:接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果 */ #include&reg51.h& #include&intrins.h& #define uchar unsigned char #define uint unsigned int //延时 void DelayMS(uint x) {
while(x--) { for(i=0;i&120;i++); } } //主程序 void main() { P0=0 while(1) { P0=_crol_(P0,1); //P0的值向左循环移动 DelayMS(150); } }
先来个支持一下, 学习的路是很漫长的,不能一步登天,尤其编写程序的方法是各施各法条条大路通罗马,只是用不同的技巧和经验令程序精简而有效率,所以必须看多些各方高手的程序来学习,取长补短令自己技巧提高,说多了,一起加油吧。
学单片机入门还算简单,但业余自学条件下想把程序写好真的不容易。51断断续续的玩了两三年了,也DIY了一些好玩的东西,觉得也算是入门了,但前些日子看了下论坛高人YANZEYUAN大侠的程序,被打击的一蹶不振,自己的水平真的连菜鸟中的菜鸟也算不上啊,自惭形秽中&……
支持下楼主,我学单片机也很多年了,也许自己不是做软件的料吧,这些年也只做了些小东西,楼主坚持下去
我擦&& 你这样能走下去么。。。
今天啥也没做,白过了,得忏悔。。。。
学习需要耐心、恒心,要耐得住寂寞,也需要讨论、交流。过程会有些痛苦,但坚持过去就是胜利!给你加油!
我也是学东西没有恒心,老是静不下来。支持楼主的学习计划,帮顶了!
实验led闪烁#include &reg51.h&#include &stdio.h&#define uchar unsigned char#define uint&&unsigned int#define ulong unsigned long sbit led = P3^2; void delay(unsigned int count){ unsigned int i,j; for(i=0;i&i++) for(j=0;j&120;j++);}main(){&&while(1) { delay(500);&&&&led=1; delay(500);&&&&led=0; }}
main()这一行应当换成void main()吧!另外,头部没有声明子函数,编译可能无法通过
发个绿色小软件,STC单片机定时器(1T_12T)初值计算器
发个32led的摇摇棒资料,以后制作STC单片机实现的32LED摇摇棒程序、PCB、线路图。可根据摇动速度自动适应,图像始终保持在画面中间
发一个温度计电路用一片DS18B20构成测温系统,测量的温度精度达到0.1度,测量的温度的范围在-20度到+50度之间,用4位数码管显示出来。[attachment=3041530]注意DS18B20极性不要弄反,否则可能烧坏。DS18B20的外型与常用的三极管一模一样,上图是它的管脚分布。输出接P3.1上。硬件电路图[attachment=3041531]&& DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。DS18B20产品的特点(1)、只要求一个I/O口即可实现通信。(2)、在DS18B20中的每个器件上都有独一无二的序列号。(3)、实际应用中不需要外部任何元器件即可实现测温。(4)、测量温度范围在-55。C到+125。C之间。(5)、数字温度计的分辨率用户可以从9位到12位选择。(6)、内部有温度上、下限告警设置。&& DS18B20详细引脚功能描述1 GND地信号;2 DQ数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源;3 VDD可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。DS18B20的使用方法。由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。C语言源程序:#include&reg52.h&code unsigned char seg7code[11]={0x3f,0x06,0x5b,0x4f,0x66,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //显示段码void Delay(unsigned int tc)&&&& //显示延时程序{while( tc != 0 )
{ &&for(i=0; i&100; i++);&&tc--;}}sbit TMDAT =P3^1; //DS18B20的数据输入/输出脚DQ,根据情况设定//测量到的温度的整数部分unsigned char xiaoshu1;//小数第一位unsigned char xiaoshu2;//小数第二位u//两位小数bit&&fg=1;&&&&&&&&//温度正负标志void dmsec (unsigned int count)&&&&&& //延时部分 {&&
while(count--) {for(i=0;i&115;i++);}
}&&&&&&&& void tmreset (void)&&&&&& //发送复位{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
TMDAT=0;&& for(i=0;i&103;i++);&&
TMDAT = 1; for(i=0;i&4;i++);&&&&&& }&&&&&&&& bit tmrbit (void)&&&&&& //读一位// {&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&& &&&&&&&&&&TMDAT = 0;&&i++;&&&&&& &&TMDAT = 1; &&i++; i++;&&//微量延时&& //&&dat = TMDAT;&&&&
for(i=0;i&8;i++); &&return (dat);&&&&&& }&&&&&&&& unsigned char tmrbyte (void)&&&&&&&&//读一个字节&&{&&&&&&&&&&&&&&&& &&unsigned char i,j,&&&&&&&&dat = 0;&&&&&& &&for (i=1;i&=8;i++)&&&&&&&&{ j = tmrbit();&&dat = (j && 7) | (dat && 1); }&&&&&&&& && return (dat);&& }&&&&&&&& void tmwbyte (unsigned char dat)&&&& //写一个字节{&&&&&&&&&&&&&&&&&&&&&& &&unsigned char j,i;&&&&&&&&&&&&&& &&for (j=1;j&=8;j++)&&&&&&&&{ testb = dat & 0x01;&&&& && dat = dat && 1;&&&&&&&& if (testb)&&&& && {&& TMDAT = 0;&&&&&&&& //写0&&&&&& i++; i++;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&TMDAT = 1;&&&&&&&&for(i=0;i&8;i++); }&&&&&&&&&&&& else&&&&&& &&{&&TMDAT = 0;&&&&&&&& //写0 &&&& for(i=0;i&8;i++); &&TMDAT = 1;&&&& &&&& i++; i++;}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&}&&void tmstart (void)&&&&&& //发送ds1820 开始转换&&{&&tmreset();&&//复位&&&& &&dmsec(1);&&//延时&&&&&&tmwbyte(0xcc);&&//跳过序列号命令&& &&tmwbyte(0x44);&&//发转换命令 44H,&&}&&&&&&&& void tmrtemp (void)&&&&&& //读取温度&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned char a,b; &&tmreset ();&&//复位&&&& &&dmsec (1);&&//延时&&&& &&tmwbyte (0xcc);&&//跳过序列号命令&& &&tmwbyte (0xbe);&&//发送读取命令&&&& &&a = tmrbyte ();&&//读取低位温度&&&&&&b = tmrbyte ();&& //读取高位温度&&&&&&&&&& &&if(b&0x7f)&&&&&&//最高位为1时温度是负&&{a=~a;&& b=~b+1;&&&&&& //补码转换,取反加一&& fg=0;&&&&&&//读取温度为负时fg=0&&&&&& }&&sdata = a/16+b*16;&&&&&&//整数部分&&xiaoshu1 = (a&0x0f)*10/16; //小数第一位&&xiaoshu2 = (a&0x0f)*100/16%10;//小数第二位&&xiaoshu=xiaoshu1*10+xiaoshu2; //小数两位}&&void DS18B20PRO(void)&&&&&&&& {&&tmstart();&&&&&&&&//dmsec(5);&&//如果是不断地读取的话可以不延时 //&&tmrtemp();&&//读取温度,执行完毕温度将存于TMP中 //}&&&&&&&&&& void Led(){ && if(fg==1)&& //温度为正时显示的数据&& {&& P2=P2&0 &&&&P0=seg7code[sdata/10];&&&&&&&&&& //输出十位数&&&&Delay(8); P2=P2|0xf0; P2=P2&0&&&&&&P0=seg7code[sdata%10]|0x80; //输出个位和小数点&&&&Delay(8); P2=P2|0xf0; P2=P2&0 &&&&P0=seg7code[xiaoshu1];&& //输出小数点后第一位&&&&Delay(8); P2=P2|0xf0; P2=P2&0x7f; &&&&P0=seg7code[xiaoshu2];&&&&&& //输出小数点后第二位&&&&Delay(4); P2=P2|0xf0;&& }&& if(fg==0)&&//温度为负时显示的数据&& {&& P2=P2&0 &&&&P0=seg7code[11];&&&&&&&&&& //负号&&&&Delay(8); P2=P2|0xf0; P2=P2&0&&&&&&P0=seg7code[sdata/10]|0x80; //输出十位数&&&&Delay(8); P2=P2|0xf0; P2=P2&0 &&&&P0=seg7code[sdata%10];&& //输出个位和小数点&&&&Delay(8); P2=P2|0xf0; P2=P2&0x7f; &&&&P0=seg7code[xiaoshu1];&&&&&& //输出小数点后第一位&&&&Delay(4); P2=P2|0xf0;&& }}main(){fg=1; while(1) {&&DS18B20PRO();&&Led(); }}
单片机应用中的实用技巧&&&&&& 在单片机的应用中,有许多巧妙的技巧和方法,如果都能熟悉与掌握的话,对于减小系统资源,降低电路成本,提高设计的可靠性都很有帮助,本文为读者们提供一些较为常用的单片机应用中的实用技巧。1、用一个I/O口控制2个单色指示灯。&& 由于单片机中的I/O口通常可设置为三种状态,即输出高电平、输出低电平和输入状态(高阻态)。利用这一点,可以很方便地用一个I/O口实现对2个指示灯的控制。其电路如右图所示。=731) window.open('http://www.dzjs.net/upimg/allimg/25021.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >当要使LED1亮时,I/O口可置为低电平。此时LED2无电流流过,不会亮。当要使LED2亮时,I/O口可置为高电平。此时LED1无电流流过,不会亮。若要LED1、LED2均不亮,可将I/O口置为高阻态,此时发光管被VD1旁路,也不会亮。若要LED1、LED2一起亮,则可以让I/O口在某一固定频率下以50%的占空比进行高低电平不停转换,利用视觉暂留,使人眼感觉两个灯都为亮的状态。2、用一个I/O口控制1个三色指示灯。其电路如右图所示。=731) window.open('http://www.dzjs.net/upimg/allimg/25203.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >当要显示绿灯(LED1)亮时,I/O口可置为低电平。此时红灯(LED2)反向偏置,无电流流过,不会亮。当要显示红灯(LED2)亮时,I/O口可置为高电平。此时绿灯(LED1)反向偏置,无电流流过,不会亮。若要指示灯不亮,可将I/O口置为高阻态,此时两个发光管均无电流流过,也不会亮。若要显示橙灯亮时,此时LED1、LED2要一起亮,则可以让I/O口在某一固定频率下以50%的占空比进行高低电平不停转换,利用视觉暂留,使人眼感觉到显示的是橙灯。待续。。。。
3、一个I/O口读取三种状态。单片机应用中,有时需要让外部用跳线进行选择设置,单片机按跳线的状态来进行相应的控制操作。本例中可用一个I/O口检测出跳线连接的3种状态:高电平,低电平或者悬空(高阻态)。电路如右图所示。=731) window.open('http://www.dzjs.net/upimg/allimg/25253.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >检测低电平状态:I/O口为输入状态,直接读取引脚上的低电平。检查高电平状态:I/O口为输入状态,直接读取引脚上的高电平。 检查高阻状态:I/O口设为输出态,输出高电平。然后设置I/O口为输入态,读取引脚状态,为高电平;再把I/O口设为输出态,输出低电平,读取引脚状态,为低电平。说明为高阻态。4、利用单片机的时钟输出产生高电压。大多数的单片机都会有个时钟输出脚,利用该脚可以产生一个高过VDD的输出电压值,在输出功率不大的场合,很实用。电路如下图所示。在未接负载情况下,最大输出电压可以达到2*VDD-2*Vd。注:Vd为二极管的导通压降。=731) window.open('http://www.dzjs.net/upimg/allimg/25423.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >
5、用一个带A/D的I/O口实现16个键盘输入。&&&&许多单片机带有A/D转换功能,在实际运用中,如果利用其中的一路A/D转换,可以很方便地实现4×4键盘输入。&&&& 如图一所示,由于键盘的纵向电阻R1~R4的阻值为递增状态,其增幅超过横向最大阻值电阻R8,因此当按键从S1至S16按下时,纵向电阻与横向电阻串联的阻值也会相应由低到高增加,如S1按下时串联阻值为11k,S2按下时阻值为13.9k,S5按下时为25k,…,由于每个键按下后的串联阻值均不同,并且依按键的次序呈逐渐增大趋势,经与R9分压后,会在单片机的输入端产生不同的电压值,该电压经过A/D转换后进行相应处理,即可判断出是哪个键按下。=731) window.open('http://www.dzjs.net/upimg/allimg/30807.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >&&&& 在实际应用中,由于阻值与电压为非线性关系,因此在电阻选用及编程时需要注意,同时A/D转换应进行相应的软件处理(如重复检测两次才确认),以消除按键抖动引起的误判断。6、用软件产生PWM实现模拟量输出。在单片机应用中,常需要通过输出模拟量来对外部进行控制,但增加D/A转换芯片不仅需要占用I/O口资源,同时也会使成本增加。下图提供一种通过单片机的定时器中断来用软件的方法产生PWM,并经过滤波与跟随电路产生准确的模拟量输出。=731) window.open('http://www.dzjs.net/upimg/allimg/30932.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >该电路只用单片机的一个I/O脚实现D/A转换功能。其输出的模拟量电压Vout=VDD*D1/(D1+D2)。该输出电压带有纹波,当RC值足够大时,该纹波值几乎为零,可忽略不计。D1与D2可通过单片机内部的定时器中断来准确产生。该模拟量从输出PWM到稳定状态,需要一定的时间,若要缩短达到稳定的时间,可以减小R1和C1的值,但纹波会增大,这在设计时需要注意。7、用2个I/O口实现多按键扫描及键盘唤醒在一些低功耗的单片机应用场合中,常常需要让单片机平时工作于睡眠状态,而在有键盘输入时唤醒单片机以做相应控制。单个按键唤醒单片机容易实现,但多个按键都能唤醒单片机有一定的困难,本文提供一种解决该问题的思路。=731) window.open('http://www.dzjs.net/upimg/allimg/31047.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >其工作过程说明如下:1.&&&&单片机的GP1口具有电平变化唤醒单片机功能,单片机在进入睡眠前将GP1口设置为输入状态,GP2设置为输出高电平状态。2.&&&&当任一键被按下时,GP1口将变为高电平,使单片机唤醒。此时将GP2口设置为输出低电平,短延时,使C1电容放电。3.&&&&将GP1设置为输出高电平,GP2设置为输入状态,定时器开始记时。4.&&&&当GP2由低电平变为高电平的瞬间,记录定时器时间。由于不同的按键按下时,分压器电路改变了RC电路的电压上升速度,因此根据测得的定时器值的大小通过查表法可判断出是哪个键被按下。以上方法只适用于单键判断,当多键同时按下时是无法判断的。该方法需要占用单片机的定时器资源。
8、单片机的自动关机功能及开机按键兼做功能按键。&&&&&&&& 在许多电池供电的应用场合,要求电路平时处于关机状态以节省电能,而当开机键按下后单片机才开始工作,工作完后又能自动关机。下图所示电路即可完成此种功能。在上电后,由于V1处于关断状态,单片机并不耗电,整个电路所消耗电流只有不到10μA。&&&&&&&&当S1按下后,V1导通,78L05获得电源,输出稳定的5V使单片机开始工作,同时单片机的GP0送出高电平,使V2导通,这使V1保持在导通状态,单片机获得持续的电源进行工作,当单片机任务处理完成后,单片机的GP0输出低电平,将V2关断,使V1也处于关断状态,单片机的电源又被关断,电路又恢复到低功耗状态,其消耗电流小于10μA。&&&&&& 在单片机获电工作后,原作为电源开关按键的S1也可以作为功能按键来使用,当S1未按下时,GP1口为高电平,而当S1按下后,GP1变为低电平,因此单片机可以检测该按键,并做相应的功能控制。例如可将S1定义为开关机按键或其它功能按键。=731) window.open('http://www.dzjs.net/upimg/allimg/31208.JPG');" style="max-width:731max-height:7280" onload="if(is_ie6&&this.offsetWidth>731)this.width=731;" >
从第一个led开始闪烁,闪烁5次之后第二个led开始闪烁,也是闪烁5次之后第三个led开始闪烁,以此类推,最后一个led闪烁5次之后又从第一个led开始闪烁。如此循环三次。#include &reg51.h& sbit led1=P2^0;sbit led2=P2^1;sbit led3=P2^2;sbit led4=P2^3;&&&&&&&&&&//闪烁次数&&&&&&&&&&&& void init_t0(void){&&&&&&TMOD=0x01;&&&&&&//用定时/计数器0定时10ms&&&&TH0=()/256;&&&&TL0=()%256;&&&& &&&&EA=1; &&&&ET0=1;&&&&TR0=1;&&&&&&&&//启动定时器0&&&&i=0;}void main(){&&&&&&&&flag=0;&&&&cnt=0;&&&&x=0;&&&&init_t0();&&&&while(1)&&&&{&&&&&&if(flag==12)&&&&&&&& //当然循环次数以及led停留的位置是可以控制的&&&&&&{&&&&&&TR0=0;&&&&&&led4=0;&&&&&&}&&&&&&&&}}void time0_int(void) interrupt 1&&{&&&&&&&&TH0=()/256;&&&&TL0=()%256;&&&&i++;&&&&if(i==30)&&&&&&&&&&&& //计数30次&&&&{ &&&&&&&&i=0;&&&&&&&&cnt++;&&&&&&&&x++;&&&&&&&&switch(flag%4)&&&&&&&&{&&&&&&&&case 0:led1=~led1;if(cnt==10){cnt=0;flag++;}&&&&&&&&&&case 1:led2=~led2;if(cnt==10){cnt=0;flag++;}&&&&&&&&case 2:led3=~led3;if(cnt==10){cnt=0;flag++;}&&&&&&&&case 3:led4=~led4;if(cnt==10){cnt=0;flag++;}&&&&&&&&}&&&&&&&&&&&&}}
大多数51是开漏输出,这种方法行不通。
汇编程序红外线万能学习遥控器使用的单片机是STC15F104单片机,长按进入学习,这样就有3个学习键,电路简单,容易制作,缺点:测试了一下,效果不错,但是还发现个问小题,就是按键发射信号时稍微按久了点就会进入从新学习的状态中,这时已学习的波形也被擦除了。;STC15F104E 3路学习万能遥控器&&;内部振荡11.0592M&&;EPPROM寄存器&&IAP_DATA EQU&&0C2H&&IAP_ADDRH EQU 0C3H&&IAP_ADDRL EQU 0C4H&&IAP_CMD&&EQU&&0C5H&&IAP_TRIG EQU&&0C6H&&IAP_CONTR EQU 0C7H&&;***********************&&;F38_4KHZ EQU 0FF70H ;38.4KHZ 1T MODE (00/2/38400)&&;F38_4KHZ EQU 0FFF4H ;38.4KHZ 12T MODE(00/2/38400/12)&&AUXR EQU 08EH &&INT_CLKO EQU 08FH ;输出时钟使能&&&&K0 BIT P3.0;按键1&&K1 BIT P3.1;按键2&&K2 BIT P3.2;按键3&&LED BIT P3.3;指示灯&&IR BIT&&P3.4;红外接收头T1CLKO BIT P3.5;红外发射管;****************************&&ORG 0&&LJMP STARTORG 0BHLJMP INT_T0;T0中断&&ORG 30H&&START:;初始化&&MOV R0,#20H&&QL:&&MOV @R0,#0;内存清0&&INC R0&&CJNE R0,#80H,QL&&;MOV AUXR,#40H ; 1T &&MOV P3,#0FFH;拉高管脚&&MOV AUXR,#00H ;定时器12T模式&&MOV TMOD,#00H ;定时器16位自动重装;--------------------&&MOV TH1,#0FFH ;38K方波定时T1&&MOV TL1,#0F4H&&SETB TR1&&;MOV INT_CLKO,#02H;发射38K&&;MOV INT_CLKO,#00H;停止发射;-----------------------------MAIN:;主程序CALL KEY0CALL KEY1CALL KEY2JMP MAIN;-----------------------------KEY0:&&JB K0,KEY0OUT&&CALL DELAY20MS;延时消抖&&JB K0,KEY0OUT;-----------------CALL OPEN_T0INT;打开T0中断判断长按;-----------------JBC 0,XUEXI0;长按,跳转到学习功能JNB K0,$-3;短按等待放开;-----------------CLR TR0;关T0CLR ET0;关T0中断CLR EA;发射关中断MOV DPTR,#1000H;第1扇区CALL FFSS;红外发射KEY0OUT:RETXUEXI0:;学习MOV DPTR,#0;第1扇区CALL ERASE;扇区擦除,做好写入准备MOV DPTR,#1;第1扇区第2字节CALL XIEXI;红外接收,存入第1扇区RET;************************KEY1:&&JB K1,KEY1OUT&&CALL DELAY20MS;延时消抖&&JB K1,KEY1OUT;-----------------CALL OPEN_T0INT;打开T0中断判断长按;-----------------JBC 0,XUEXI1;长按跳转到学习JNB K0,$-3;等待放开;-----------------CLR TR0;关T0CLR ET0;关T0中断CLR EA;关中断MOV DPTR,#1200H;第2扇区CALL FFSS;红外发射KEY1OUT:RETXUEXI1:;学习MOV DPTR,#200H;第2扇区CALL PDSQ;读数判断扇区是否为空MOV DPTR,#201H;第2扇区第2字节CALL XIEXI;红外接收,存入第2扇区RET;************************KEY2:&&JB K2,KEY2OUT&&CALL DELAY20MS;延时消抖&&JB K2,KEY2OUT;-----------------CALL OPEN_T0INT;打开T0中断判断长按;-----------------JBC 0,XUEXI2;长按跳转到学习JNB K0,$-3;等待放开;-----------------CLR TR0;关T0CLR ET0;关T0中断CLR EA;关中断MOV DPTR,#1300H;第2扇区CALL FFSS;红外发射KEY2OUT:RETXUEXI2:;学习MOV DPTR,#300H;第2扇区CALL PDSQ;读数判断扇区是否为空MOV DPTR,#301H;第2扇区第301字节CALL XIEXI;红外接收,存入第2扇区RET;***********************PDSQ:;读数判断扇区是否为空,是空就擦除MOV R1,#200;读200个字节ZDKA:;CALL EEPROMRINC DPTRCJNE A,#0FFH,RESA;跳到扇区擦除DJNZ R1,ZDKA;是否读完RETRESA:CALL ERASE;扇区擦除RET;*********************;-----------------------OPEN_T0INT:;打开T0中断CLR 0;清长按标志位MOV 2FH,#0;清计数,每计一次70MSMOV TH0,#0;定时器0初值MOV TL0,#0CLR TF0SETB ET0;开T0中断SETB TR0;开T0SETB EARET;***************************INT_T0:;T0中断,判断长按,长按标志位0置1INC 2FH;中断计数,MOV A,2FHCJNE A,#12,INT_T0OUT;70MS*12=840MSSETB 0;置1CLR TR0CLR ET0CLR EAINT_T0OUT:RETI&&;***************************&&;***************************&&XIEXI:;;红外接收;存入EEPROMW&&PUSH DPL;保护指针&&PUSH DPH&&CLR 2;清判断位&&CLR LED;亮灯&&MOV R1,#0;高电平和低电平总数&&CLR TR0;停止计时X0: JB IR,X0;等待接收头,无信号返回等待&&MOV TH0,#0;;定时器初值归0&&MOV TL0,#0&&SETB TR0;有信号开始计数&&;-------------------&&WAIT0:JBC TF0,XOUT;等待超时;超过70MS退出&&JNB IR,WAIT0;等待高电平到来&&CLR TR0;停止计数,存低电平时长&&;-------------------&&BAOCUN:;存低(高)电平时长&&MOV A,TH0;高位&&CPL A;取反计数值就是定时初值&&CALL EEPROMW;写一字节EEPROMW大约60US&&INC DPTR;下一地址&&MOV A,TL0;低位&&CPL A;取反&&CALL EEPROMW;写一字节EEPROMW大约60US&&;-------------------&&MOV TH0,#0;定时器初值归0&&MOV TL0,#6EH;补偿120US&&SETB TR0;开始计数&&INC DPTR;下一地址&&INC R1;电平个数加1&&CPL 2;取反判断位,初始是0&&JNB 2,WAIT0;是0就跳到等待高电平到来&&;***********************************&&WAIT1:JBC TF0,XOUT;等待超时&&JB IR,WAIT1;是1就等待低电平到来&&CLR TR0;停止计时&&;---------------------------&&JMP BAOCUN;存高电平时长&&XOUT:;退出&&CLR TR0;停止计时&&POP DPH;指针出栈&&POP DPL&&DEC DPL;减1就是第1字节地址;用来保存电平总数&&MOV A,R1;电平总数&&CALL EEPROMW;写入扇区第1个地址&&SETB LED;关灯&&RET&&;***************************&&;***************************&&FFSS:;红外发射&&CLR LED;;开灯&&MOV A,#0;&&MOVC&&A,@A+DPTR&&MOV R1,A;从第1扇区第1地址取出电平总数&&CLR TR0;停止计数&&INC DPTR;下一地址开始为发射数据时长&&FFSS0:&&MOV INT_CLKO,#02H;发射38K红外(A版T1为3.5)&&;***************************&&ZCZ:;读出定时时长装入定时器&&MOV A,#0;&&MOVC A,@A+DPTR&&MOV TH0,A&&INC DPTR;下一地址&&MOV A,#0&&MOVC A,@A+DPTR&&;---------------------&&CLR C;数据修正,10US左右&&ADD A,#10&&MOV TL0,A&&MOV A,#0&&ADDC A,TH0&&MOV TH0,A&&;***************************&&SETB TR0;开始计时&&INC DPTR;下一地址&&JNB TF0,$;等待溢出&&MOV INT_CLKO,#00H;停止发射&&SETB P3.5;熄灭红外管&&CLR TF0;清溢出位&&CLR TR0;停止计数&&;-----------------------&&DJNZ R1, FFSS1;电平数-1是否完毕&&SETB P3.5;熄灭红外管&&SETB LED;;关灯&&RET&&FFSS1:&&MOV A,#0;装入初值&&MOVC A,@A+DPTR&&MOV TH0,A&&INC DPTR;下一地址&&MOV A,#0&&MOVC A,@A+DPTR&&;---------------------&&CLR C;数据修正&&ADD A,#10&&MOV TL0,A&&MOV A,#0&&ADDC A,TH0&&MOV TH0,A&&;***************************&&SETB TR0;开始计数&&INC DPTR;下一地址&&JNB TF0,$;等待溢出&&CLR TF0&&CLR TR0;停止计数&&;-----------------------&&DJNZ R1,FFSS0;电平数-1是否完毕&&;***************************&&MOV INT_CLKO,#00H;停止发射&&SETB P3.5;熄灭红外管&&SETB LED;关灯&&RET&&;******************&&;EPPROM读写&&;******************&&ERASE:;擦除&&MOV IAP_CONTR,#83H;允许IAP/IAP操作&&MOV IAP_CMD,#3&&;扇区擦除&&MOV IAP_ADDRH,DPH ;送高地址&&MOV IAP_ADDRL,DPL ;送低地址&&ACALL IAPXX&&&&&& ;触发&&RET&&;************************&&EEPROMW:;写&&MOV IAP_CONTR,#83H;允许IAP/IAP操作&&MOV IAP_CMD,#2&&;送写命令&&MOV IAP_ADDRH,DPH ;送高地址&&MOV IAP_ADDRL,DPL ;送低地址&&MOV IAP_DATA,A&&&&;A是要写入的数据&&ACALL IAPXX&&&&&& ;触发&&RET&&;************************&&EEPROMR:;读&&MOV IAP_CONTR,#83H;允许IAP/IAP操作&&MOV IAP_CMD,#1&&;送读命令&&MOV IAP_ADDRH,DPH ;送高地址&&MOV IAP_ADDRL,DPL ;送低地址&&ACALL IAPXX&&&&&& ;触发&&MOV A,IAP_DATA&&&&;读出的数据放到A&&RET&&;************************&&IAPXX:;触发&&;CLR EA ;关中断在触发之前&&MOV IAP_TRIG, #5AH;和11F/15F的相同,而与12C2052的不同&&MOV IAP_TRIG, #0A5H ;&&NOP&&NOP&&NOP&&;SETB EA&&RET&&;----------------------&&IAP_DISABLE:;禁止IAP/IAP操作&&MOV IAP_CONTR,#0&&MOV IAP_CMD,#0&&MOV IAP_TRIG,#0&&MOV IAP_ADDRH,#0FFH&&MOV IAP_ADDRL,#0FFH&&RET&&;----------------------&&DELAY20MS: ;延时&&&&&&MOV R7,#0EH&&DL1:&&&&&&MOV R6,#0A8H&&DL0:&&&&&&MOV R5,#16H&&&&&&DJNZ R5,$&&&&&&DJNZ R6,DL0&&&&&&DJNZ R7,DL1&&&&&&RET&&END
第 一步,闪一个灯第二步&&8个流水灯第三步 按钮控制8个流水灯第四步 定时器控制闪一个灯第五步 LED数码管第六步, 定时器+数码管的时钟,或者计时器
写日记很重要,不过实战更重要,如果时间允许,建议还是要多写多实践,还有就是要哦多接触几款单片机,要知道,实际商业化的产品里,STC方案都是被枪毙的,有空的话,上一下其它几款商业主流单片机更合适!
那些商业的单片机不适合业余用,根本不零售。
百度贴吧小贴吧建成,欢迎去玩。
#include&reg51.h& #define uchar unsigned char #define uint unsigned int 这段,你能默写出来吗?
跟我学51单片机搜索结果:跟我学51单片机搜索分类:
共同学习,一起进步!
前面是C怎么又汇编了?我也玩一年了,主要改别人的程序。。。与君共勉之!
【老师要求:不使用延时,而使用定时器来做2个led闪烁,其中一个led闪烁间隔1秒,另一个间隔2秒,(好像是0.5、1秒来着),程序可以自己写,也可以复制网上的】我折腾了好久啊,不会自己写,复制网上的,然后改啊改啊,总是通过不了,中间电脑死机了2回,屏幕键盘不好使了,打不开。只好插上键盘,还得重新开机才行。经过对比网上多个程序,发现亮2个或者多个led,需要开2个或者多个中断才能正常运行。刚开始,试验的程序是开一个定时器中断,我怎么折腾都是亮灭时间一样,只是亮的次序可以改,但是2个灯亮的时间不能分开设置。还有定义管脚的,我还是习惯sbit这样的,所以,又从网上找了程序,重新改,反复的试验,终于。。。。。期间,为了区分亮灭时间的不同(因为我用的是3色发光管,不容易分辨),把一个设置成1秒,另一个改时间设置2、4、8秒,分别试验,可以达到要求了。我这仅仅是改别人的程序,感觉挺难的,但是有收获,没有白熬夜哈。
#include&reg51.h&sbit D1=P3^0; sbit D2=P3^1;unsigned char Countor1;unsigned int Countor2;void main(void){EA=1; ET1=1; TMOD=0x10;TH0=()/256;TL0=()%256;TR1=1;Countor1=0; Countor2=0; while(1) ; }void Time1(void) interrupt 3 using 0{Countor1++; Countor2++; if(Countor1==10) {D1=~D1; Countor1=0; }if(Countor2==20){D2=~D2;Countor2=0;}TH0=()/256;TL0=()%256; }
楼主留言:不能,记不住。第一句可以右键,插入头文件。下功夫不够啊,呵呵
复制别人的程序不难,要学习理解每一句的含义。
【新的作业来了】请按照以下伪代码的思路重写一个代码,自己分析下代码,熟悉一下。U32表示是32 bit的无符号整数,需要自己重新typedef一下的。U32定时器中断函数{重装时钟(这里重装时钟还需要一点时间,需要几个指令周期,所以你把定时器配置成10ms一次中断的话,实际中断的时间会比10ms长一点)cnt++; (考虑一下,这个程序最长能正常工作多长时间)}U32 GetTimer(){U32 tmp;关中断&& (考虑下为什么要关/开中断,而不直接返回cnt)tmp =开中断}delay(U32 n)&&(考虑一下,如果n=2,这个delay能否延时到20ms,实际的延时时间是10~20ms之间){U32 pre = GetTimer()while(GetTimer() - pre & n);}main{初始化定时器和中断,10ms一个中断(考虑一下,可不可以做成1ms中断一次,可不可以做成100us中断一次,把中断时间减少,有何利弊?)while(1){LED1 = !LED1;LED2 = !LED2;Delay(25);LED1 = !LED1Delay(25);}}
[tr=rgb(246, 246, 246)][td]标&& 题日 期2008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008[tr=rgb(243, 241, 230)][td]20082008
初学,记不住关键字,建议使用周立功的开发软件TKSTudio软件,界面基本上跟KEIL是一样的,用KEIL建立好工程后,从TKS导入KEIL工程,用法跟KEIL一模一样,推荐的原因是TKS有非常强大的代码辅助输入功能,就是你只要敲一个字母,以为个字母开头的所有关键字,子函数,变量等,自动提示出来供你选择,就跟VB编程时一样,这样避免了初学者打错字,记不住关键字到处复制粘贴等问题.
我也来学习!一起加油!
从AVR入门咋样?
也没啥,不过51的教材、资料多。
我认为杜老大的注释是写绐单片机手平很菜的人看的(比如我),这些内容是杜老大对语句的理解,我就认为为个很好,而你那样的标准注释是写绐同行或者自己看的!杜老大在写那个的时候,自已也复习了一遍,很好!!
自己写的就是给自己看的,没必要那么复杂,又不是去做教材。
最近在理解595原理,单片机没什么进展,595真值表没有弄懂。
研究595还过早吧,起码要把移位、逻辑运算、循环等搞懂,
查看完整版本: [--
Powered by
Time 0.220644 second(s),query:5 Gzip enabled

我要回帖

更多关于 一步登天 音乐剧 的文章

 

随机推荐