惠美科技完成超3亿元D轮融资,由钟鼎资本
06-17
1. 8个LED灯交替闪烁,时间间隔为1s 1 /************ ********************** ******************** 2 实验名称:8 个 LED 灯交替闪烁,时间间隔为 1s 3 实验时间:2019 年 12 月 2 日 4 ************************************************* ********/ 5 6 #include 7 8 void 延迟(无符号字符 a); ? 0x00; 16delay(45); 17 18 /*根据原理图,P0置低电平,灯灭*/ 19 P0 = 0xFF; 20delay( 45); 21 } 22 } 23 24 /*延迟1s,有错误。
计算公式大约为 ((((c*2))*b)*a)*/ 25 void delay(unsigned char a) 26 { 27 unsigned char b,c; 28 对于(;a>0;a--) 29 对于(b=;b>0;b--) 30 对于(c=70;c>0;c--); 31 32 } 实验的代码非常简单。
但在实际操作中我们还是遇到了以下问题: 端口P0号不能为小写。
字母 P 必须大写。
给P0赋值时,虽然赋值的是16进制值,但末尾不能加H。
最重要的是延迟问题! 需要注意的是,用C语言是不可能制作出准确的延迟效果的,而且肯定会有一定的误差! ! ! ! 首先我们来了解一下几种单片机的周期知识: 时钟周期:也叫振荡周期,定义为频率的倒数,是单片机中最基本、最小的时间单位。
状态周期:时钟周期的两倍。
机器周期:单片机的基本周期,完成一次基本操作,如取指令、存储器读写等。
由12个时钟周期(6个状态周期)组成。
指令周期:单片机执行一条指令所需的时间,通常为1-4个机器周期。
这里我把晶振的频率设置为和自己的设备一样,都是12MHZ,所以机器周期是1μs。
根据Keil的调试功能可以查看整个程序的时间。
打开Keil的调试功能(菜单栏放大镜中带d的图标),然后在需要的地方设置断点。
如下图所示: 如图所示,断点设置在第15行和第16行。

在图片的左侧,可以找到“sec”项。
此项是执行该步骤所需的时间,然后根据时间差可以计算出延迟时间。
这里可以看到执行到第15行的时间是0.s 执行第16行的时间是0.s,所以执行P0=0x00的时间是2μs,也就是两个机器周期,因为这里采用的是立即寻址,一个周期取值,一个周期执行。
执行第19行的时间是0.s,所以执行代码delay(45)的时间是0.35s,接近1s,所以有错误。
但对于实验结果来说,这就足够了。
最重要的一点是,经过我自己的实验,不同类型的符号需要不同的时间。
比如我使用无符号整形的话,需要的时间是3.7s,所以差别还是很大的。
但总而言之,应该遵循一些简单的原则: 尽量使用无符号数据结构。
尝试使用char类型。
如果还不够就用int,然后用long。
如果可能,不要使用浮点。
使用简洁的代码,因为根据经验,简洁的C代码往往可以生成简洁的目标代码(尽管并非在所有情况下都是如此)。
另外,组装好的延时程序也在这里发布。
同样,我们首先看一下用于实现此目标的代码。
1 /************************************************ *** **************************************** 2 * 实验名称:简单测试LED闪烁 3 * 实验描述:获得8个LED交替亮灭的实验效果 4 ************************ ****** ********************************************** *****/ 5 6 ORG H ;程序从该地址开始运行 7 LJMP MAIN ;跳转到MAIN程序 8 9 ORG H ;MAIN从H 10 MAIN: 11 MOV P0 ,# 00H ;P0 为低电平 LED 灯亮 12 ACALL DELAY ;呼叫延迟子程序 13 MOV P0 ,#0FFH 14 ACALL DELAY 15 AJMP MAIN ;跳跃到主程序 16 17 DELAY: 18 MOV R5,#08H ;传送立即数到寄存器R5 19 F3: 20 MOV R6,#0FAH 21 F2: 22 MOV R7, #0FAH 23 F1: 24 DJNZ R7,F1 ;如果为0,程序向下执行,如果不为0,程序跳转到 25 DJNZ R6,F2 26 DJNZ R5,F3 27 RET 28 29 END 其中 DJNZ 是减一非零传输指令。
有两个参数,第一个是被减数,第二个是传送的地址号。
另外需要注意的是,MOV指令是单周期指令,DJNZ是两周期指令。
下面是延迟分析: 执行MOV指令的时间为0.s 执行第12行时,时间为0.s,所以执行MOV语句的时间P0, #00H 是2μs,也是因为采用立即数寻址。
可以看到延时程序耗时约1s。
计算分析过程: MOV R5,#08H;执行1次,单周期 F3:MOV R6,#0FAH;执行1*8次,单周期 F2:MOV R7,#0FAH;执行1*8*次,单周期F1:DJNZ R7,F1;执行8**次,双循环DJNZ R6,F2;执行*8次,双循环DJNZ R5、F3;执行8次,双循环 ,所以总时间为1****2*8*2*2=μs ,所以用汇编写延时程序显然比C语言更准确当然,这并不完全正确。
还有一个小错误。
应该用定时器来设计准确的延时。
2。
LED 二进制加法显示 1 /**************************************** 2 - --------------------------------- 3 实验名称:LED 二进制加法显示 4 实验时间:/12/2 5 *************************************/ 6 7 #include 8 9 void Delay(unsigned char x); 10 11 void main() 12 { 13 unsigned char n = 0x00; 14 while(1) 15 { 16 P0 = n; 17 延迟(45); 18 n++; 19 } 20 } 21 22 void 延迟(无符号字符 x) 23 { 24 无符号字符 y,z; 25 for(;x>0;x--) 26 for(y=;y>0;y--) 27 for(z=35;z >0;z--); 28 } 3。
LED流水灯设计 1 /******************************************** * 2 ---------------------------------------------- --------- 3 实验名称:流水灯实验 4 实验描述:延迟实现LED灯流水线效果 5 实验时间:/12/2 6 ** ************ *************************/ 7 8 #include 9 #include 10 11 void Delay(unsigned char a); 12 13void main() 14{ 15 16unsigned char x; 17x = 0x01; 18while(1)19{ 20p0 = x; 21 延迟(45); 22x = _crol_(x,1); //Char类型循环向左移动 23 } 24 } 25 26 void Delay(unsigned char a) 27 { 28 unsigned b, c; 29 for( ;a>0;a--) 30 对于(b=76;b>0;b--) 31 对于(c=35;c>0;c --); 32 } intrins.h头文件内部函数说明: _crol_字符循环左移 _cror_字符循环右移 _irol_整数循环左移 _iror_整数右旋转 _lrol_ 长整型左移 _lror_ 长整型右移 _nop_ 无操作(相当于 NOP 指令) _testbit_ 测试并清除位(相当于 JBC 指令) 具体用法: (1) 循环移位用法如上代码 (2) _nop_ 无操作: P()=1; _nop_(); P()=0; 功能: 空命令。
除了占用命令时间之外什么也不做。
(3) _testbit_ 测试和清除位: 功能:生成 JBC 指令。
该函数测试一个位,设置时返回 1,否则返回 0。
如果该位为 1,则将该位重置为 0。
JBC 伪指令用于此目的。
_testbit_只能与可直接寻址的位一起使用;不允许在表达式中使用。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-17
06-18
06-18
06-18
06-17
06-18
06-18
最新文章
使用电子管有哪些注意事项?如何检查电子管之间是否短路?
博通支付1200万美元和解SEC财务欺诈指控
八名运营商高管确认加入虚拟运营商
内蒙古农牧区雷电灾害成因分析及防雷对策
北京联通将5G应用于世园会远程医疗急救
TD-SCDMA最后一轮冲刺测试启动,产业前景更加光明
专访阿里云总裁王健:云计算服务平台梦想成真
USB2.0控制器CY7C68013的接口设计与实现