51单片机:实现八位流水灯的Protues和Keil使用技巧

目录

一、Proteus部分

1、保存项目

2、烧录程序

二、keil部分

1、创建项目

2、参考程序 (共阳极接法)

(一)位操法

(二)数组总线法

(三)移位运算符法

 (四)循环左、右移位函数法


一、Proteus部分

1、保存项目

(一)【文件】\rightarrow保存设计

  (二)某盘\rightarrowProteus(双击)\rightarrow空白处右键\rightarrow新建文件夹\rightarrow 重命名“项目” 

 (三)双击项目\rightarrow文件名输入“1.流水灯” \rightarrow保存

 (四)点击元件模式(左侧黄色运放按钮)\rightarrow点击“P”

 (五)输入关键字\rightarrow选中器件\rightarrow确定

流水灯所需器件列表

关键字 元件名称 型号 数量(个)
AT89C51 单片机 AT89C51 1
CRYSTAL 晶体振荡器 12MHZ 1
LED-RED 发光二极管 红色 8
CAP 电容 22pF 2
CAP-ELEC 电解电容 10uF 1
RES 电阻 1kΩ 9
RES 电阻 10kΩ 1
BUTTON 复位按键 1

(六)放置元器件

先单击元件的关键字\rightarrow在原理图编辑窗口的合适位置再次单击即可

 双击元器件的值即可修改

放置VCC

 电路原理图如图所示

2、烧录程序

双击单片机\rightarrow点击Program File后面的文件夹标志\rightarrow上传.hex文件\rightarrow确定

 若仿真时出现Cannot open 'C:\User\XXX\AppDate\Local\Temp\LISA4823.SDF'

步骤:右键“此电脑”–>属性–>高级系统配置–>环境变量–>将“用户变量”和“系统变量”中TEMP与TMP的变量值改为%SystemRoot%\TEMP。

二、keil部分

1、创建项目

(一)新建一个文件夹保存项目

(二)双击"keil"\rightarrow“项目”\rightarrow“新uVision项目”

(三)将文件命名为项目名

(四)选择单片机型号

(五)单击“是(Y)”

(六)新建Text

(七)保存

(八)命名“.c”文件

(九)双击“Source Group 1”

(十)添加“.c”文件

(十一)生成.hex文件

 点击“输出”\rightarrow勾选“创建HEX文件”

(十二)编译

编译无错误如下图所示

2、参考程序 (共阳极接法)

(一)位操法

缺点:代码冗长

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit L1=P1^0;//将P1^0赋值给变量L1
sbit L2=P1^1;
sbit L3=P1^2;
sbit L4=P1^3;
sbit L5=P1^4;
sbit L6=P1^5;
sbit L7=P1^6;
sbit L8=P1^7;

void delay(uint n)//延时函数(n)ms
{
	uchar i;
	uint j;
	for(j=0;j<n;j++)
	for(i=0;i<123;i++);
}

void flash1()//LED1亮0.5s后熄灭
{
	L1=0;//LED1亮
	delay(500);
	L1=1;//LED1灭
}

void flash2()
{
	L2=0;
	delay(500);
	L2=1;
}

void flash3()
{
	L3=0;
	delay(500);
	L3=1;
}

void flash4()
{
	L4=0;
	delay(500);
	L4=1;
}

void flash5()
{
	L5=0;
	delay(500);
	L5=1;
}

void flash6()
{
	L6=0;
	delay(500);
	L6=1;
}

void flash7()
{
	L7=0;
	delay(500);
	L7=1;
}

void flash8()
{
	L8=0;
	delay(500);
	L8=1;
}

void main (void)
{
	while(1)
	{
		flash1();
		flash2();
		flash3();
		flash4();
		flash5();
		flash6();
		flash7();
		flash8();
		
		flash8();
		flash7();
		flash6();
		flash5();
		flash4();
		flash3();
		flash2();
		flash1();
	}
}

(二)数组总线法

二进制对应表

P1^7 P1^6 P1^5 P1^4 P1^3 P1^2 P1^1 P1^0

想让对应引脚的LED亮,只需将二进制数对应位置取0即可。

数组取值

现象 二进制表示 十六进制表示
LED1亮 1111 1110 0xfe
LED2亮 1111 1101 0xfd
LED3亮 1111 1011 0xfb
LED4亮 1111 0111 0xf7
LED5亮 1110 1111 0xef
LED6亮 1101 1111 0xdf
LED7亮 1011 1111 0xbf
LED8亮 0111 1111 0x7f

优点:代码简短

缺点:点亮数据编写比较麻烦,且容易出错

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//前8个数据为左移点亮数据,后8个数据为右移点亮数据

void delay(uint n)
{
	uchar i;
	uint j;
	for(j=0;j<n;j++)
	for(i=0;i<123;i++);
}

void main (void)
{
	uchar i;
	while(1)
	{
		for(i=0;i<16;i++)
		{
			P1=tab[i];
			delay(500);
		}
	}
}

(三)移位运算符法

左移代码分析

i temp P1=~temp

LED情况

temp=temp<<1

(高位丢弃,低位补0)

0

0x01

0000 0001

1111 1110

0xfe

LED1亮

0000 0010

0x02

1

0x02

0000 0010

1111 1101

0xfd

LED2亮

0000 0100

0x04

2

0x04

0000 0100

1111 1011

0xfb

LED3亮

0000 1000

0x08

3

0x08

0000 1000

1111 0111

0xf7

LED4亮

0001 0000

0x10

4

0x10

0001 0000

1110 1111

0xef

LED5亮

0010 0000

0x20

5

0x20

0010 0000

1101 1111

0xdf

LED6亮

0100 0000

0x40

6

0x40

0100 0000

1011 1111

0xbf

LED7亮

1000 0000

0x80

7

0x80

1000 0000

0111 1111

0x7f

LED8亮

0000 0000

0x00

右移代码分析

i temp P1=~temp LED情况

temp=temp>>1

(低位丢弃,高位补0)

0

0x80

1000 0000

0111 1111

0x7f

LED8亮

0100 0000

0x40

1

0x40

0100 0000

1011 1111

0xbf

LED7亮

0010 0000

0x20

2

0x20

0010 0000

1101 1111

0xdf

LED6亮

0001 0000

0x10

3

0x10

0001 0000

1110 1111

0xef

LED5亮

0000 1000

0x08

4

0x08

0000 1000

1111 0111

0xf7

LED4亮

0000 0100

0x04

5

0x04

0000 0100

1111 1011

0xfb

LED3亮

0000 0010

0x02

6

0x02

0000 0010

1111 1101

0xfd

LED2亮

0000 0001

0x01

7

0x01

0000 0001

1111 1110

0xfe

LED1亮

0000 0000

0x00

优点:代码简短

缺点:移位运算符分析麻烦

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

void delay(uint n)
{
	uchar i;
	uint j;
	for(j=0;j<n;j++)
	for(i=0;i<123;i++);
}

void main (void)
{
	uchar i,temp;
	while(1)
	{
		temp=0x01;
		for(i=0;i<8;i++)//左移循环
		{
			P1=~temp;//取反
			delay(500);
			temp=temp<<1;//左移一位
		}
		temp=0x80;
		for(i=0;i<8;i++)//右移循环
		{
			P1=~temp;//取反
			delay(500);
			temp=temp>>1;//右移移位
		}
	}
}

 (四)循环左、右移位函数法

左移函数分析

temp P1=temp temp=_crol_(temp,1)(高位补低位)
0xfe

1111 1110

LED1亮

1111 1101
0xfd

1111 1101

LED2亮

1111 1011
0xfb

1111 1011

LED3亮

1111 0111
0xf7

1111 0111

LED4亮

1110 1111
0xef

1110 1111

LED5亮

1101 1111
0xdf

1101 1111

LED6亮

1011 1111
0xbf

1011 1111

LED7亮

0111 1111
0x7f

0111 1111

LED8亮

1111 1110

右移函数分析

temp P1=temp temp=_cror_(temp,1)(低位补高位)
0x7f

0111 1111

LED8亮

1011 1111
0xbf

1011 1111

LED7亮

1101 1111
0xdf

1101 1111

LED6亮

1110 1111
0xef

1110 1111

LED5亮

1111 0111
0xf7

1111 0111

LED4亮

1111 1011
0xfb

1111 1011

LED3亮

1111 1101
0xfd

1111 1101

LED2亮

1111 1110
0xfe

1111 1110

LED1亮

0111 1111

优点:代码简短

缺点:移位函数分析麻烦

#include <reg52.h>
#include <intrins.h>//包含移位函数的头文件
#define uchar unsigned char
#define uint unsigned int

void delay(uint n)
{
	uchar i;
	uint j;
	for(j=0;j<n;j++)
	for(i=0;i<123;i++);
}

void main (void)
{
	uchar i,temp;
	while(1)
	{
		temp=0xfe;
		for(i=0;i<8;i++)//左移位循环
		{
			P1=temp;
			delay(500);
			temp=_crol_(temp,1);
		}
		temp=0x7f;
		for(i=0;i<8;i++)//右移位循环
		{
			P1=temp;
			delay(500);
			temp=_cror_(temp,1);
		}
	}
}

物联沃分享整理
物联沃-IOTWORD物联网 » 51单片机:实现八位流水灯的Protues和Keil使用技巧

发表评论