声明:【51单片机学习过程记录】全是我自己学习、实践所记录的过程,我只是菜鸟,所有论点和观点仅代表我个人,不能确定是这个技术的真理。我的目的是学习和有可能成为可以向别人分享的经验,因此有错误我会虚心接受,并认真改正。
这是很很很基础的实践,即对单片机的IO进行操作,看原理图,流水灯部分,要点亮LED,注意两点
1
对应的引脚, 就是连接LED的引脚对应单片机上的引脚位置
2
引脚的电平, 就是当引脚电平是高还是低,才会令led点亮。
例如图中,对应单片机的引脚就是P1.0 ... P1.7, 然后J2 第2引脚接电源VCC,那么要让LED点亮,即电流流通,所以对应引脚应为低电平。
#include <reg52.h>
#include <intrins.h>
//sbit led1=P1^0; // aa
#define uchar unsigned char
void delay() //bb
{
uchar x,y;
for(x=255;x>0;x--)
for(y=255;y>0;y--);
}
void main()
{
uchar i,temp;
temp=0xfe;
while(1) // cc
{
for(i=0;i<8;i++)
{
temp=_crol_(temp,1); //dd
P1=temp;
delay();
}
}
解释下上面程序的几点:
aa
bit 和 sbit的区别(百度文库解释)
bit 和int char之类的差不多,只不过char=8位, bit=1位而已。都是变量,编译器在编译过程中分配地址。除非你指定,否则这个地址是随机的。这个地址是整个可寻址空间,RAM+FLASH+扩展空间。bit只有0和1两种值,意义有点像Windows下VC中的BOOL。
sbit是对应可位寻址空间的一个位,可位寻址区:20H~2FH。一旦用了sbi xxx = REGE^6这样的定义,这个sbit量就确定地址了。sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。
sbit led1=P1^0; 就是把P1口的0位 的地址赋予led1,那么以后操作led1就是对P1的0口操作。P1的地址在头文件可以找到,例如
#ifndef __REG52_H__
#define __REG52_H__
/* BYTE Registers */
sfr P0 = 0x80;
sfr P1 = 0x90; (OK,这里出现了 sfr ,什么鬼,特殊功能寄存器定义,可以继续查看下,这里不继续了。0x90就是P1的地址)
bb
delay()函数,是用于延时,因为如果没有延时,led亮的速度很快,那么没有流水的效果,这里的值我是没有固定是多少时间,只是延时足够让眼睛看到流水效果而已。
cc
这里的程序可以不这样写,我是用了个中间变量temp用于给P1赋值,但其实更方便简洁些,可以直接给P1赋值。
例如 P1=_crol_(P1,1);
dd
对,_crol_ 需要注意下,这个函数是在INTRINS.H这个头文件里面,但是查不到实现内容代码,不过可以百度。
它的作用就是循环左移,就好像单车的链条,移动一圈之后回到原来的位置:
76543210 -----65432107-----54321076-----43210765-----32107654......这里的数字我是举例说明,他们的位置,显示循环左移。
_cror_:当然有循环左移就会有循环右移,还有其他的函数,可以自己查。
总结:
led的操作就是IO操作,基础,不过如果单单是led不同的流动效果、样式进行变化,还是很有意思的,向左流水,右流水,中间流水交叉过去等等。。。
注意的是
1 对应引脚。
2 响应电平。
3 _crol_函数,循环左移,无需用for()循环来控制其操作几次,所以主函数优化可以改成:
void main()
{
P1=_crol_(P1,1);
delay();
}
就可以了。