历史上的今天
今天是:2025年04月15日(星期二)
2020年04月15日 | 51单片机--LED闪烁、流水灯的简单试验
2020-04-15 来源:eefocus
一、LED闪烁
/*****************************************************************
LED闪烁的简单试验 *****************************************************************/
include /*******延时函数**************************************/ // 定义一个演示函数,定时时间大概为一个ms。 void delay(unsigned int i) { unsigned char j; for(i; i > 0; i--) for(j = 100; j > 0; j--); } /**************************************************************************/ main() { while(1) { P2 = 0x00; //置P2口为低电平 led灯点灭 delay(1000); //调用延时程序 led持续灭,保持 P2 = 0xff; //置P2口为高电平 led灯熄亮 delay(1000); // 调用延时程序 led持续亮,保持 //重复以上语句, led灯点亮,保持亮的状态,熄灭,保持熄//灭状态 循环这个4个过程。 } } /* */作用,它是用来注释一段内容的,编译器不对其进行编译,只要在/* */直接的内容都被注释掉。 // 是用来注释其后面的内容,只能注释一行。 #include 打开头文件, #ifndef __REG51_H__ #define __REG51_H__ /* BYTE Register */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0; ……………………………. /* SCON */ sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98; #endif 头文件中定义了51系列单片机的所有功能寄存器,我们直接使用其代号就可以,P0,P1等 如 sfr P0=0x80,意思是把单片机内部地址0x80处的寄存器重新起名字叫P0,以后我们在程序中直接操作P0,就相当于对单片机内部0x80地址处的寄存器进行操作。通俗的讲,也就是说,通过sfr这个关键字,让Keil编译器在单片机与人之间搭建一个桥梁,我们操作P0口,单片机对应就去操作内部0x80的地址。所以我们写程序要在开始处直接包涵单片机的头文件。 sbit SM0 = 0x9F;是定义位操作地址0x9F的,这个地址只代表一个位。我们操作SM0,对应单片机就是操作位地址0x9F。 总结起来sfr与sbit区别 sfr 是定义字节的 8位 sbit 是定义位的 1位 我们在返回主程序: void delay(unsigned int i) { unsigned char j; for(i; i > 0; i--) for(j = 100; j > 0; j--); } 定义一个函数delay();与c语言一样,要用一个函数,先定义,我们可以叫它子函数,可以调用的。 main() // 结构同c语言一样,main()函数开始 { // 大括号。 P2 = 0x00; //置P2口为低电平 从这句开始,你现在控制单片机了,告诉单片机把你的P2口都输出0,如果你不操作P2口了,那么P2口一直保持这个状态,直到你去改变它。 delay(1000); //调用延时程序 调用子函数delay(),告诉单片机去执行delay那个函数,那么P2口一直保持0这状态。 P2 = 0xff; //置P2口为高电平 这时告诉P2口全部输出1,(0xff=1111 1111).转太有0变成1了,对应的灯的输出也由低电平变成高电平了 delay(1000); // 调用延时程序,再进行延时, } 这个程序里执行完了一次又干什么呢, Keil编译器会编译成一直重复执行main()函数里面的代码,整个代码的效果就是: 1)P2输出低电平 2)延时一段时间,目的是P2输出的低电平保持一段时间 3)P2输出高电平 4)延时一段时间,目的是P2输出的高电平保持一段时间 5)重复1)到4)的过程 实际效果就是led一闪一闪 通过更改delay(延时时间t),参数t,可以改变闪烁频率。 实际操作: 打开软件 点击打开文件,打开我们刚刚编译的led.hex文件,下载程序,就会看到led闪烁。 二、流水灯的简单试验 /****************************************************************************** 流水灯 延时实现P2口LED流水灯效果 (用循环移位指令) ******************************************************************************/ #include void delay(unsigned int i) // 延时子程序 { unsigned char j; for(i; i > 0; i--) for(j = 100; j > 0; j--); } main() { unsigned char LED; LED = 0xfe; //0xfe = 1111 1110 此时,led灯的最低一位亮 while(1) { P2 = LED; delay(300); LED = LED << 1; //循环左移1位,点亮下一个LED "<<"为左移位 if(P2 == 0x00 ) {LED = 0xfe; } // 0xfe = 1111 1110 } } 代码注释: void delay(unsigned int i) // 延时子程序 { unsigned int i; //定义一个无符号变量i,16位宽度,最大可表示二进制1111 1111 1111 1111,对应十进制是65535共计65536个数,从0开始。 for(i; i > 0; i--) //传过来的参数进行自减,只要不为0就执行循环里的参数,执行一次减1,直到i变为0,跳出循环 { for(j = 100; j > 0; j--); //i=0开始,判断i是否>0,不是的话,j自动减1,之后再判断i是否>0,直到i<=0,跳出for 循环。整个延时子程序 每次调用都要执行i*100个for 循环。由于c语言编译的结果时间不确定,不是很精确,这里暂不计算时间。 } } unsigned char LED; //定义一个无符号8位变量。 LED = 0xfe; //0xfe = 1111 1110 把刚刚定义的变量赋值 while(1) // 无限循环以下程序 { P2 = LED; // 第一次吧0xfe送给P2口,那么最低位连接的led点亮 delayms(300); //延时,就是上一个语句状态保持一段时间 LED = LED << 1; //循环左移1位,点亮下一个LED "<<"为左移位 if(P2 == 0x00 ) //判断P2的值,是否都为0,如果都为0的话就要重新赋值 {LED = 0xfe; } // 0xfe = 1111 1110 } 以上程序实现led依次亮,循环执行。 以下是我们的硬件电路,led从D11~D18,排阻RP20和RP21。 元器件介绍: 排阻: 一般在排阻上都标有阻值号,其公共端附近也有明显标记。如下下图表示为472,表示47*(10^2)=4700欧姆, 还有的标号如3R0,表示阻值为3欧姆, 4K7表示阻值为4.7kΩ, R002表示阻值为0.002欧姆。 (2)发光二极管。它具有单向导电性,通过5mA左右电流即可发光,电流越大,其亮度越强,但若电流过大,会烧毁二极管,一般我们控制在3 mA-20mA之间。在这里,给发光二极管串联一个电阻的目的就是为了限制通过发光二极管的电流不要太大,因此这个电阻又称为“限流电阻”。当发光二极管发光时,测量它两端电压约为1.7V,这个电压又叫做发光二极管的“导通压降”。图2.2.9和图2.2.10分别为直插式发光二极管和贴片式发光二极管实物图。发光二极管正极又称阳极,负极又称阴极,电流只能从阳极流向阴极。直插式发光二极管长脚为阳极,短脚为阴极。仔细观察贴片式发光二极管正面的一端有彩色标记,通常有标记的一端为阴极。 关于排阻大小的选择:欧姆定律想必大家都清楚,U=IR,当发光二极管正常导通时,其两端电压约为1.7V,发光管的阴极为低电平,即0V,阳极串接一电阻,电阻的另一端为Vcc , 为5V,因此加在电阻两端的电压为5V-1.7V=3.3V,计算穿过电阻的电流,3.3 V/ 1000Ω=3.3mA 即穿过发光管的电流也为3.3mA,若想让发光管再亮一些,我们可以适当减小该电阻。 看我们的原理图,可以知道:LED的正极接在VCC上,只要给了低电平,那么LED就会亮,低电平对应到单片机的逻辑就是0,只要单片机的某一个管脚输出0,那么对应的发光二极管就会亮。
(提前装好驱动)


上一篇:51单片机实现呼吸灯
史海拾趣
|
[Help!]tffs 的 FLASH_BASE_ADRS 怎么确定啊? 44b0x板,FLASH 是 AM29LV160DT 16Mbit/2Mbyte/1Mword 按照 http://www.lwsir.com/ligong/dianzi/200701/17467_3.html 对BSP作了修改。 执行tffsShow -> tffsShow amd29lvMTDIdentify Manufacturer unknown: 0x06 0: **** commu ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 03:41 编辑 有人做过测量交流电压的吗?可以交流交流一下 。带宽太宽了不好测量啊 可以分享你们的经验吗? … 查看全部问答> |
|
现在,我已经有一个比较好的装置来调试传感器融合的算法了。记录了X轴Y轴的加速度值和Z轴的陀螺仪输出。 不得不说,单单用加速度来判断角度真的很难。 当我左右转动电路板的时候,Y轴的加速度值反映了我转动的快慢+ ...… 查看全部问答> |
|
【TI C2000的使用经验】+ 使用Energia开发C2000-LaunchPad应用 使用Energia开发C2000-LaunchPad应用Energia 是一个开源和社区驱动型集成开发环境 (IDE) 与软件框架。Energia 基于接线框架,为微控制器编程提供了直观的编码环境和由易于使用的功能 API 及库构成的可靠框架。Energia 支持多种 TI 处理器,主要包括 ...… 查看全部问答> |
|
我现在使用MSP430F5438A的最小系统板。编译器用的是CCS6.0.1。用CCS做MSP430的硬件仿真,是不是要CCS仿真器,但是某宝上没有支持MSP430的CCS仿真器,求教 怎么解决。还有我用过IAR for MSP430 版本是5.3的,驱动是MSP-FET430UIF-VCP(CO ...… 查看全部问答> |




