程序示例:
#include <STC15F2K60S2.H>
sbit led1 = P0^0;
sbit led2 = P0^1;
sbit led3 = P0^2;
sbit led4 = P0^3;
sbit led5 = P0^4;
sbit led6 = P0^5;
sbit led7 = P0^6;
sbit led8 = P0^7;
void main(void)
{
unsigned int i = 0;
unsigned int ms = 65535;
P2 = 0xA0;P0 = 0X00;P2 = 0X80;P0 = 0XFF;//初始化程序
while(1)
{
led8 = 1;led1 = 0;
for(i = 0;i < ms;i++);
led1 = 1;led2 = 0;
for(i = 0;i < ms;i++);
led2 = 1;led3 = 0;
for(i = 0;i < ms;i++);
led3 = 1;led4 = 0;
for(i = 0;i < ms;i++);
led4 = 1;led5 = 0;
for(i = 0;i < ms;i++);
led5 = 1;led6 = 0;
for(i = 0;i < ms;i++);
led6 = 1;led7 = 0;
for(i = 0;i < ms;i++);
led7 = 1;led8 = 0;
for(i = 0;i < ms;i++);
}
}
程序讲解:
关键字-sbit:
sbit
:不是函数,而是关键字,主要用于嵌入式系统中的单片机编程,如8051系列的C51单片机。
sbit
:用于定义位变量(bit variables)。在8051单片机中,一些I/O端口的寄存器是位寻址寄存器,sbit
被用于声明和操作这些位,所以上面我分别用P0(第0组io口)声明变量led1~8,方便理解。
P0^1
:表示第0组第1个io口,在普通的80c51单片机中用P0_1表示第0组第1个io口,而在我用软件给stc15F系列的单片机进行写入程序时,用P01表示第0组第1个io口,所以碰到不熟悉的芯片可以直接用P0^1表示就不会出错,在程序复杂的时候也可以像我一样采用声明的方式,创建单独的变量(led1~8)
注意
:在单片机编程中,不支持直接在函数内部声明sbit。正确的做法是在全局作用域中声明sbit,否则会出现下图的报错
思路:
思路
:思路就是前一个灯亮完经过一个肉眼可以感觉到的时间间隔然后熄灭,同时亮下一个灯,我这里选择1ms,也就是程序运行65535次耗费的时间,后面学习定时器会更高端且更精确,这只是一个近似值,现在只能用这种笨方法,剩下的就比较简单了。
效果演示:
LED流水灯
采用并口的程序示例:
#include <STC15F2K60S2.H>
unsigned int i = 0;
sfr led = 0X80;
void main(void)
{
P2 = 0xA0;P0 = 0X00;P2 = 0X80;P0 = 0XFF; // 初始化程序,后期讲
led = 0XFE;
for(i = 0;i < 65535;i++);
led = 0XFD;
for(i = 0;i < 65535;i++);
led = 0XFB;
for(i = 0;i < 65535;i++);
led = 0XF7;
for(i = 0;i < 65535;i++);
led = 0XEF;
for(i = 0;i < 65535;i++);
led = 0XDF;
for(i = 0;i < 65535;i++);
led = 0XBF;
for(i = 0;i < 65535;i++);
led = 0X7F;
for(i = 0;i < 65535;i++);
}
好处
就是原本需要进行未定义出led1~8或者需要使用P00 ~ 7,但是现在只需要将第0组寄存器的地址赋给led,然后采用并口的方式对sfr类型的变量led进行赋值就可以实现流水灯,使程序还是简洁了一些,这种方式只有在一些比较复杂的程序上会有比较显著的好处,但是在例如只是点一个灯的简单程序就看不出来。
关键字-sfr:
sfr
是 “Special Function Register” 的缩写,指的是特殊功能寄存器。在嵌入式系统中,特殊功能寄存器用于控制和配置微处理器或微控制器的各种特殊功能,例如输入输出端口、定时器、串口通信等。
这些寄存器通常是硬件相关的,它们的值直接影响单片机的行为。通过对这些寄存器进行读写操作,程序可以配置硬件,控制外设,实现各种功能。
在8051单片机的C51编程中,sfr
关键字用于声明特殊功能寄存器。例如:
sfr P0 = 0x80;
这里声明了一个 sfr
变量 P0
,其地址为 0x80
,代表8051单片机的P0口寄存器。通过对 P0
进行读写操作,可以控制和读取P0口的状态。这个sfr类型的变量应该类似*P,而P是保存了某个地址的指针变量,寄存器也属于存储器的一种,这个0X80就是这个存储器的地址。
sfr与sbit的区别:
在8051单片机的C语言编程中,sfr
和 sbit
是两个关键字,用于声明特殊功能寄存器和位变量。它们的主要区别在于声明的对象不同。
-
sfr(Special Function Register):
sfr
用于声明特殊功能寄存器,这些寄存器用于配置和控制单片机的特殊功能,如I/O端口、定时器、串口等。- 通过
sfr
关键字,可以创建一个C语言变量,其地址对应特殊功能寄存器的地址,从而可以对这些寄存器进行读写操作。
sfr P0 = 0x80; // 声明P0口的特殊功能寄存器
-
sbit(Bit Variable):
sbit
用于声明位变量,通常用于表示某个特殊功能寄存器的某一位。- 通过
sbit
关键字,可以创建一个C语言位变量,它实际上是对特殊功能寄存器的某一位进行命名,方便在程序中引用这个位。
sbit myBit = P0^0; // 声明P0口的第0位,并命名为myBit
总的来说,sfr
用于声明整个特殊功能寄存器,而 sbit
用于声明寄存器中的某一位。这两者通常结合使用,通过 sbit
声明特定位变量,然后使用 sfr
访问整个寄存器。
常用的8位二进制与2位十六进制的转换表:
下面是从二进制 0000 0000
到 1111 1111
的二进制到十六进制的转换表:
二进制 | 十六进制 |
---|---|
0000 0000 | 0x00 |
0000 0001 | 0x01 |
0000 0010 | 0x02 |
0000 0011 | 0x03 |
0000 0100 | 0x04 |
0000 0101 | 0x05 |
0000 0110 | 0x06 |
0000 0111 | 0x07 |
0000 1000 | 0x08 |
0000 1001 | 0x09 |
0000 1010 | 0x0A |
0000 1011 | 0x0B |
0000 1100 | 0x0C |
0000 1101 | 0x0D |
0000 1110 | 0x0E |
0000 1111 | 0x0F |
0001 0000 | 0x10 |
0001 0001 | 0x11 |
0001 0010 | 0x12 |
0001 0011 | 0x13 |
0001 0000 | 0x14 |
1111 1101 | 0xFD |
1111 1110 | 0xFE |
1111 1111 | 0xFF |
还是下次讲方法吧,这样也不方便记,太多了 |
程序运行效果演示:
采用并口的方式写的流水灯
总感觉同样是运行65535次,但是采用并口的似乎比采用单独一位点灯的程序灯闪的慢一点