注意51系列8位(bit)一个字节,应用汇编语言简洁高效。16位的处理器需要用0000 0000H 表示。16或32位以上,使用操作系统(WinCE、Linux等)更有效,可以利用大量的、底层的、专业化、标准化的面向控制的库函数(如:API等)。高级语言具有对底层硬件的无关性,则可移植性好、可重用性好;高级语言描述控制更接近人的自然语言,可描述性好,表达力好。Linux的代码与模块的开放性、可剪裁性、自我构造等特点使其前景广阔。
1.单个LED灯,单个按键
//C语言的头文件 //这是第一种注释方式;
//预处理命令
#include
#define uchar unsigned char
#define uint unsigned int
//声明变量
sbit LED1_0=P1^0; // #define 头文件中没有定义的I/O,在此由用户定义
sbit LED2_0=P2^0;
//延时子程序 ― 这是一个常用的模块,可视为标准程序段,
void Delayms(uint x)
{
uchar i;
while(x--) //X每循环一次,自动减1,直至X为1,终止循环
{
For (i=0;i<120;i++);
}
}
//主程序
void main()
{
while(1)
{
LED2_0=P2^0;
LED1_0=LED2_0;
Delayms(200); //这里的200就是X的值― Delayms(uint x)― while(x--)
}
}
程序说明:
While(条件语句) 与 for(条件语句) 单独使用所表达的循环,是在句首先执行判断,为真循环,为假转下一句执行。其中语句的括号内为判断条件语句。
Do-while合用,是需要对do的过程再进行一次判断。While(条件语句)为真循环,为假跳转。while(1)表示高电平为真循环do,否则,低电平跳转。由于P1.0 口为高电平结尾,因此,又回到do再循环,无限反复。
#include
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1_0 = 0; //位赋值语句,设 P1.0 口为低电平—置0,点亮 LED
for (a=0; a<500; a++); //这又是一个判断循环
P1_0 = 1; //设 P1.0 口为高电平,熄灭 LED
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
2.多个LED灯,单个按键
对于多个LED灯(LED数 < 8个)来说,在硬件连接方面、软件编写方面均没有大的难点。按照单个LED的连接方式增加便可。控制程序编写基本上也是重复性工作—用COPY简单修改即可。
对于LED数> 8个且不能被8整除的需要用位操作指令。
对于LED数> 8个的情况,需要解决两个方面的问题。一个是硬件的连接方法,一个是控制程序的编写指令—用词方法。硬件方面可以用单个或多个成组的LED多个或总线接口、单个接口扩展等。程序编写则可以使用重复性工作、可以使用字节命令而摒弃位命令,使得程序简洁、可读性好、硬件运行效率高。
对于LED数= 8个或是8的倍数的情况,硬件方面可以用单个或多个成组的LED多个或总线接口、单个接口扩展等。程序编写则可以使用重复性工作、可以使用字节操作指令而摒弃位操作指令,使得程序简洁、可读性好、硬件运行效率高。
#include < reg51.h >
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1_0 = 0; //位赋值语句,设 P1.0 口为低电平—置0,点亮 LED
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
for (a=0; a<500; a++); //这又是一个判断循环
P1_0 = 1; //设 P1.0 口为高电平,熄灭 LED
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
程序说明:
每个口用位赋值指令来开关P1口的各个LED。可以用字节赋值指令一次性的开关8位P1口LED。
P1=0; //P1口8位置低电平,点亮8个LED
P1=1; // P1口8位置低电平,关闭8个LED
对于多灯的情况,可以使用多个数据口来进行系统设计(也可单口扩展),在图2系统的基础上,添加P3口为一个字节形式的输出口。用LED组件的形式显示输出要求。
改造结果如图3所示。
#include
#define uchar unsigned char
#define uint unsigned int
//声明变量
sbit LED1_0=P1^0; sbit LED1_1=P1^1; sbit LED1_2=P1^2; sbit LED1_3=P1^3;// sbit LED1_4=P1^4; sbit LED1_5=P1^0;
sbit LED2_0=P2^0;
//延时子程序
void Delayms(uint x)
{
uchar i;
while(x--)
{
for (i=0;i<120;i++);
}
}
//主程序
void main()
{
{
if(LED2_0!=1)
P3=0xff;
else
P3=0x00;
LED2_0=P2^0;
LED1_0=LED2_0;
LED1_1=LED2_0;
LED1_2=LED2_0;
LED1_3=LED2_0;
Delayms(100);
}
return;
}
程序说明:
上面的单片机系统和C语言控制指令,很容易被更改为多口、多位的单键控制系统。图3为多个LED灯-单个按键的运行结果与C语言。图中对P2.0口采用了双掷开关,实现P2.0口的两种电平状态。
3.LED循环问题(跑马灯、流水灯):
每个口用位赋值指令来开关P1口的各个LED,用位指令赋值顺序开关,实现跑马灯。
先通过单个灯的闪烁来体验C语言描述单口或多口(位)的高低电平变换。
n 无开关单灯闪烁
n 无开关多灯闪烁
n 用循环语句实现跑马灯,需要使用数组—表data。每个字节--8位来表达P1口各个位的电平高低,也就是亮与灭。
#include
#include
#define uchar unsigned char
#define uint unsigned int
//声明变量 7FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH
uchar code LiuSHui[]={0x7F,0xfb,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x7F,0xfb,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
sbit LED2_0=P2^0;
//延时子程序
void Delayms(uint x)
{
uchar t;
while(x--)
{
for (t=0;t<120;t++);
}
}
//主程序
void main()
{
uchar i=0;
{
if(LED2_0!=1)
{
loop:
P3=~LiuSHui[i];
i=(i+1);
Delayms(100);
goto loop;
}
else
P3=0x00;
if(LED2_0=1)
{
P1=0x00;
Delayms(100);
}
else
P1=0xff;
}
return;
}
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;
}
}
51系列-C语言逐级深入练习
5.单个LED灯,单个按键
//C语言的头文件 //这是第一种注释方式;
#include
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1_0 = 0; //位赋值语句,设 P1.0 口为低电平—置0,点亮 LED
for (a=0; a<500; a++); //这又是一个判断循环
P1_0 = 1; //设 P1.0 口为高电平,熄灭 LED
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
程序说明:
While(条件语句) 与 for(条件语句) 单独使用所表达的循环,是在句首先执行判断,为真循环,为假转下一句执行。其中语句的括号内为判断条件语句。
Do-while合用,是需要对do的过程再进行一次判断。While(条件语句)为真循环,为假跳转。while(1)表示高电平为真循环do,否则,低电平跳转。由于P1.0 口为高电平结尾,因此,又回到do再循环,无限反复。
6.多个LED灯,单个按键
#include
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1_0 = 0; //位赋值语句,设 P1.0 口为低电平—置0,点亮 LED
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
for (a=0; a<500; a++); //这又是一个判断循环
P1_0 = 1; //设 P1.0 口为高电平,熄灭 LED
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
程序说明:
每个口用位赋值指令来开关P1口的各个LED。可以用字节赋值指令一次性的开关8位P1口LED。
P1=0; //P1口8位置低电平,点亮8个LED
P1=1; // P1口8位置低电平,关闭8个LED
#include
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1 = 0; //字节赋值语句,设 P1 口为低电平—置0,点亮 8个LED
for (a=0; a<500; a++); //这又是一个判断循环
P = 1; //设 P1 口为高电平,熄灭 LED
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
l LED循环问题(跑马灯):
每个口用位赋值指令来开关P1口的各个LED,用位指令赋值顺序开关,实现跑马灯。
#include
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1_0 = 0; //位赋值语句,设 P1.0 口为低电平—置0,点亮 LED
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
for (a=0; a<500; a++); //这又是一个判断循环
P1_0 = 1; //设 P1.0 口为高电平,熄灭 LED
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.0 口为高电平,熄灭 LED
P1_1 = 1;
P1_2 = 1;
P1_3 = 1;
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
用循环语句实现跑马灯,需要使用数组—表data。每个字节--8位来表达P1口各个位的电平高低,也就是亮与灭。
#include
#include <> //预处理命令
void main(void) //主函数名,必须有一个主函数,void为数据类型
{
unsigned int a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do{ //do-while 组成的循环过程,过程的开始
for (a=0; a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1 = 0; //字节赋值语句,设 P1 口为低电平—置0,点亮 8个LED
for (a=0; a<500; a++); //这又是一个判断循环
P = 1; //设 P1 口为高电平,熄灭 LED
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}