注意51系列8位(bit)一个字节,应用汇编语言简洁高效。16位的处理器需要用0000 0000H 表示。16或32位以上,使用操作系统(WinCE、Linux等)更有效,可以利用大量的、底层的、专业化、标准化的面向控制的库函数(如:API等)。高级语言具有对底层硬件的无关性,则可移植性好、可重用性好;高级语言描述控制更接近人的自然语言,可描述性好,表达力好。Linux的代码与模块的开放性、可剪裁性、自我构造等特点使其前景广阔。
1.单个LED灯,单个按键
//C语言的头文件
//预处理命令
#include
#define uchar unsigned char
#define uint unsigned int
//声明变量
//延时子程序 ― 这是一个常用的模块,可视为标准程序段,
程序说明:
While(条件语句) 与 for(条件语句) 单独使用所表达的循环,是在句首先执行判断,为真循环,为假转下一句执行。其中语句的括号内为判断条件语句。
Do-while合用,是需要对do的过程再进行一次判断。While(条件语句)为真循环,为假跳转。while(1)表示高电平为真循环do,否则,低电平跳转。由于P1.0 口为高电平结尾,因此,又回到do再循环,无限反复。
#include
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1_0 = 0;
for (a=0; a<500; a++);
P1_0 = 1;
}
while(1);
}
2.多个LED灯,单个按键
对于多个LED灯(LED数 < 8个)来说,在硬件连接方面、软件编写方面均没有大的难点。按照单个LED的连接方式增加便可。控制程序编写基本上也是重复性工作—用COPY简单修改即可。
对于LED数> 8个且不能被8整除的需要用位操作指令。
对于LED数> 8个的情况,需要解决两个方面的问题。一个是硬件的连接方法,一个是控制程序的编写指令—用词方法。硬件方面可以用单个或多个成组的LED多个或总线接口、单个接口扩展等。程序编写则可以使用重复性工作、可以使用字节命令而摒弃位命令,使得程序简洁、可读性好、硬件运行效率高。
对于LED数= 8个或是8的倍数的情况,硬件方面可以用单个或多个成组的LED多个或总线接口、单个接口扩展等。程序编写则可以使用重复性工作、可以使用字节操作指令而摒弃位操作指令,使得程序简洁、可读性好、硬件运行效率高。
#include < reg51.h >
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1_0 = 0;
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
for (a=0; a<500; a++);
P1_0 = 1;
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
}
while(1);
}
程序说明:
每个口用位赋值指令来开关P1口的各个LED。可以用字节赋值指令一次性的开关8位P1口LED。
P1=0;
P1=1;
对于多灯的情况,可以使用多个数据口来进行系统设计(也可单口扩展),在图2系统的基础上,添加P3口为一个字节形式的输出口。用LED组件的形式显示输出要求。
改造结果如图3所示。
#include
#define uchar unsigned char
#define uint unsigned int
//声明变量
//延时子程序
程序说明:
上面的单片机系统和C语言控制指令,很容易被更改为多口、多位的单键控制系统。图3为多个LED灯-单个按键的运行结果与C语言。图中对P2.0口采用了双掷开关,实现P2.0口的两种电平状态。
3.LED循环问题(跑马灯、流水灯):
每个口用位赋值指令来开关P1口的各个LED,用位指令赋值顺序开关,实现跑马灯。
先通过单个灯的闪烁来体验C语言描述单口或多口(位)的高低电平变换。
n
n
n
#include
#include
#define uchar unsigned char
#define uint unsigned int
//声明变量 7FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH
//延时子程序
4.多数码管
对于多个数码管的情形,需要注意通过控制
#define LEDS 4
#include"reg51.h"
//led T选iffl1号
unsigned char code Select[]={0x01,0x02,0x04,0x08,0x10};//,0x20};
//unsigned char code Select[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,};
unsigned char code LED_CODES[]=
{ 0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,//0-9
0x88,0x83,0xC6,0xA1 ,0x86,0x8E,0xFF,0x0C,0x89,0x7F,0xBF//A,...F,空格,P,H,.,-
};
void main()
{
char i=0;
long int j;
long int n;
while(1)
{
P2=0;
P2=LED_CODES[n];
//P1=1;
P1=Select[i];
for(j=20000;j>0;j--);
i++;
if(i>4) i=0;
n++;
if(n>15) n=0;
}
}
5.单个LED灯,单个按键
//C语言的头文件
#include
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1_0 = 0;
for (a=0; a<500; a++);
P1_0 = 1;
}
while(1);
}
程序说明:
While(条件语句) 与 for(条件语句) 单独使用所表达的循环,是在句首先执行判断,为真循环,为假转下一句执行。其中语句的括号内为判断条件语句。
Do-while合用,是需要对do的过程再进行一次判断。While(条件语句)为真循环,为假跳转。while(1)表示高电平为真循环do,否则,低电平跳转。由于P1.0 口为高电平结尾,因此,又回到do再循环,无限反复。
6.多个LED灯,单个按键
#include
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1_0 = 0;
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
for (a=0; a<500; a++);
P1_0 = 1;
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
}
while(1);
}
程序说明:
每个口用位赋值指令来开关P1口的各个LED。可以用字节赋值指令一次性的开关8位P1口LED。
P1=0;
P1=1;
#include
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1 = 0;
for (a=0; a<500; a++);
P = 1;
}
while(1);
}
l
每个口用位赋值指令来开关P1口的各个LED,用位指令赋值顺序开关,实现跑马灯。
#include
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1_0 = 0;
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
for (a=0; a<500; a++);
P1_0 = 1;
P1_1 = 0;
P1_2 = 1;
P1_3 = 1;
for (a=0; a<500; a++);
P1_0 = 1;
P1_1 = 1;
P1_2 = 0;
P1_3 = 1;
for (a=0; a<500; a++);
P1_0 = 1;
P1_1 = 1;
P1_2 = 1;
P1_3 = 0;
for (a=0; a<500; a++);
P1_0 = 1;
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
}
while(1);
}
用循环语句实现跑马灯,需要使用数组—表data。每个字节--8位来表达P1口各个位的电平高低,也就是亮与灭。
#include
#include <> //预处理命令
void main(void)
{
unsigned int a;
do{
P1 = 0;
for (a=0; a<500; a++);
P = 1;
}
while(1);
}