欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

STC89C51单片机初学者指南 - 基础实验教程(第一部分)

最编程 2024-07-28 09:48:44
...

文章目录

  • 前言
  • 1. 点亮第一个LED
    • 1.1 代码
    • 1.2 编译
    • 1.3 程序下载
    • 1.4 结果展示
    • 1.5 常见问题及解决办法
  • 2. LED灯闪烁
    • 2.1 代码
    • 2.2 编译
    • 2.3 程序下载
    • 2.4 结果展示
    • 2.5 常见问题及解决办法
  • 3. LED流水灯
    • 3.1 代码
    • 3.2 编译
    • 3.3 程序下载
    • 3.4 结果展示
    • 3.5 常见问题及解决办法
  • 4. 蜂鸣器
    • 4.1 代码
    • 4.2 编译
    • 4.3 程序下载
    • 4.4 结果展示
    • 4.5 常见问题及解决办法
  • 5. 动态数码管显示
    • 5.1 代码
    • 5.2 编译
    • 5.3 程序下载
    • 5.4 结果展示
    • 5.5 常见问题及解决办法
  • 6. 独立按键
    • 6.1 代码
    • 6.2 编译
    • 6.3 程序下载
    • 6.4 结果展示
    • 6.5 常见问题及解决办法
  • 7. 矩阵按键
    • 7.1 代码
    • 7.2 编译
    • 7.3 程序下载
    • 7.4 结果展示
    • 7.5 常见问题及解决办法
  • 8. 单片机IO扩展--74HC595
    • 8.1 代码
    • 8.2 编译
    • 8.3 程序下载
    • 8.4 结果展示
    • 8.5 常见问题及解决办法
  • 9. LED点阵(点亮一个点)
    • 9.1 代码
    • 9.2 编译
    • 9.3 程序下载
    • 9.4 结果展示
    • 9.5 常见问题及解决办法
  • 10. LED点阵(显示数字)
    • 10.1 代码
    • 10.2 编译
    • 10.3 程序下载
    • 10.4 结果展示
    • 10.5 常见问题及解决办法
  • 11. 直流电机
    • 11.1 代码
    • 11.2 编译
    • 11.3 程序下载
    • 11.4 结果展示
    • 11.5 常见问题及解决办法
  • 12. 外部中断0
    • 12.1 代码
    • 12.2 编译
    • 12.3 程序下载
    • 12.4 结果展示
    • 12.5 常见问题及解决办法
  • 13. 定时器0中断
    • 13.1 代码
    • 13.2 编译
    • 13.3 程序下载
    • 13.4 结果展示
    • 13.5 常见问题及解决办法
  • 14. 串口通信
    • 14.1 代码
    • 14.2 编译
    • 14.3 程序下载
    • 14.4 结果展示
    • 14.5 常见问题及解决办法
  • 15. EEPROM-IIC
    • 15.1 代码
    • 15.2 编译
    • 15.3 程序下载
    • 15.4 结果展示
    • 15.5 常见问题及解决办法
  • 16. DS18B20温度传感器
    • 16.1 代码
    • 16.2 编译
    • 16.3 程序下载
    • 16.4 结果展示
    • 16.5 常见问题及解决办法
  • 17. DS1302时钟
    • 17.1 代码
    • 17.2 编译
    • 17.3 程序下载
    • 17.4 结果展示
    • 17.5 常见问题及解决办法
  • 18. AD模数转换
    • 18.1 代码
    • 18.2 编译
    • 18.3 程序下载
    • 18.4 结果展示
    • 18.5 常见问题及解决办法
  • 19. DA数模转换
    • 19.1 代码
    • 19.2 编译
    • 19.3 程序下载
    • 19.4 结果展示
    • 19.5 常见问题及解决办法
  • 20. LCD1602液晶
    • 20.1 代码
    • 20.2 编译
    • 20.3 程序下载
    • 20.4 结果展示
    • 20.5 常见问题及解决办法

前言

本笔记用于记录STC89C51单片机开发板入门学习,此部分为基础实验例程。开始实验前建议学习《10天学会51单片机-郭天祥》,另外还需要一定的C语言基础。
准备环境:

  1. 笔记本一台;
  2. STC89C51开发板一套(我选用的是普中51-单核-A2开发板,入手价格56元,因为便宜买的);
  3. 串口助手软件STC-ISP(用于程序下,也可用商家自带的程序下载软件);
  4. KeiluVision5软件(用于程序开发,安装和教程自行百度)。

1. 点亮第一个LED

本条所要实现的功能是:点亮D1发光二极管,即让P2.0管脚输出一个低电平。

1.1 代码

/*********************
点亮第一个LED灯实验
实验现象:下载程序后D1指示灯点亮
日期:2020-04-11
作者:lixs
**********************/
#include <reg52.h>

sbit led=P2^0;//将单片机P2.0端口定义为led

void main()
{
		led=0;//p2.0端口设置为低电平
		while(1);//循环语句
		
}

1.2 编译

编译前需要在KeiluVision5软件进行设置:1)options选项;2)output选项;3)勾选create HEX file;4)命名Name of Executable。如下图所示:
编译设置
设置完成后进行编译。如下图所示:
编译结果
编译完成后会生成.hex文件。如下图所示:
生成.hex文件
至此编译工作完成。

1.3 程序下载

编译生成.hex文件后,打开STC-ISP软件,将此.hex文件下载到单片机中。

STC-ISP软件设置。如下图所示:
STC-ISP软件设置
软件设置完成后,开始下载程序:1)点击打开程序文件;2)选择.hex文件;3)点击下载/编程。如下图所示:
程序下载
点击下载程序后会出现:正在检测目标单片机…,此时检查单片机是否上电。如已上电,请关闭电源,重新上电,即可完成程序下载。如下图所示:
检测目标单片机
单片机正常连接后,会完成程序下载,STC-ISP软件会提示程序下载结果。如下图所示:
在这里插入图片描述

1.4 结果展示

点亮第一个LED灯结果展示

1.5 常见问题及解决办法

2. LED灯闪烁

本条所要实现的功能是:让D1发光二极管固定周期闪烁,即让P2.0管脚先输出一个低电平点亮D1,然后固定周期后输出一个高电平熄灭D1。这就需要增加一个延时,我们利用c语言中的循环函数,让CPU不断循环执行即可实现延时功能。

2.1 代码

/*********************
LED灯闪烁实验
实验现象:下载程序后D1指示灯闪烁
日期:2020-04-11
作者:lixs
**********************/
#include <reg52.h>
typedef unsigned int uint16;
sbit led=P2^0;//将单片机P2.0端口定义为led
void delay(uint16 x);

void main()
{
		while(1)
		{
				led=0;//p2.1端口设置为低电平,即点亮D1
				delay(50000);//循环50000次,即大约延时500ms
				led=1;//p2.1端口设置为高电平,即熄灭D1
				delay(50000);//循环50000次,即大约延时500ms
		}
}

void delay(uint16 x)//延时函数,当x=1时,大约延时10us
{
		while(x--);
}

2.2 编译

编译过程同1.2一致。

2.3 程序下载

程序下载过程同1.3一致。

2.4 结果展示

LED闪烁实验

2.5 常见问题及解决办法

问题1:为什么如果将延时函数中的形参x赋值超过65535即LED灯延时间隔即呈现非正常状态?
解决办法:因为x数据类型为unsigned int类型,最大值为65535,因此x会溢出,导致非正常状态出现,x的赋值一定要严格在数据类型的取值范围内,否则不会得到预期结果。

3. LED流水灯

3.1 代码

/*********************
LED流水灯实验
实验现象:下载程序后D1-D8指示灯循环逐个点亮
日期:2020-04-11
作者:lixs
**********************/
#include <reg52.h>
#include <intrins.h>        //左右移函数头文件
#define led P2              //定义P2端口为led,即可用led代替P2端口
typedef unsigned int uint16;//对数据类型进行声明定义
typedef unsigned char uchar8;//对数据类型进行声明定义
uchar8 i;//初始化变量i
void delay(uint16);//声明延时函数


//主函数:实现led灯流水效果(采用<<左移运算符实现)
/*void main()
{
		led=~0x01;
		delay(50000);
		while(1)
		{
			for(i=0;i<8;i++)
			{
					led=~(0x01<<i);//将1左移i位,然后将结果赋值到led中
					delay(50000);//循环50000次,即大约延时500ms
			}
		}
}*/

//主函数:实现led灯流水效果(采用左移函数实现)
void main()
{
		led=~0x01;//0x01取反即为0xFE,也可直接写led=0xFE
		delay(50000);//循环50000次,即大约延时500ms
		while(1)
		{
			for(i=0;i<8;i++)//循环8次,即与D1-D8一一对应
			{
					led=_crol_(led,1);//左移函数,将led的值左移1位,然后将结果赋值到led中
					delay(50000);//循环50000次,即大约延时500ms
			}
		}
}

//延时函数,x=1时,大约延时10us
void delay(uint16 x)
{
		while(x--);
}

3.2 编译

编译过程同1.2一致。

3.3 程序下载

程序下载过程同1.3一致。

3.4 结果展示

LED流水灯实验

3.5 常见问题及解决办法

问题1: 为什么LED流水灯点亮的同时,数码管也会跟着流动点亮?
解决办法:经查看开发板原理图得知,此现象是由于硬件电路导致,非程序影响。


由于工作原因,无法保证定期更新实验例程,还请谅解。以下实验例程会不定期更新,欢迎随时光临指导。

4. 蜂鸣器

4.1 代码

/*********************
蜂鸣器发声实验
实验现象:下载程序后蜂鸣器模块发声
日期:2020-04-11
作者:lixs
**********************/

#include <reg52.h>
sbit buzzer=P1^5;//将单片机P1.5端口定义为buzzer
typedef unsigned int uint16;//对数据类型进行声明定义
void delay(uint16 x);//声明延时函数

void main()
{
		while(1)
		{
			//通过给P1.5端口赋值方式使蜂鸣器发生
			/*buzzer=0;//将P1.5端口置0,即蜂鸣器端输入低电平
			delay(1000);
			buzzer=1;//将P1.5端口置1,即蜂鸣器端输入高电平
			delay(1000);*/
			
			//通过取反方式使蜂鸣器发生
			buzzer=~buzzer;//buzzer刚开始是0x01,然后循环取反,即可达到0/1切换的效果
			delay(100);//循环100次,即大约延时1ms
		}
		
}

void delay(uint16 x)//延时函数,当x=1时,大约延时10us
{
		while(x--);
}

4.2 编译

编译过程同1.2一致。

4.3 程序下载

程序下载过程同1.3一致。

4.4 结果展示

  • 待上传视频

4.5 常见问题及解决办法

5. 动态数码管显示

5.1 代码

/*********************
动态数码管实验
实验现象:下载程序后动态数码管依次显示数字0-7
日期:2020-04-13
作者:lixs
**********************/

#include <reg52.h>
sbit LSA=P2^2;//将单片机P2.2端口定义为LSA
sbit LSB=P2^3;//将单片机P2.3端口定义为LSB
sbit LSC=P2^4;//将单片机P2.4端口定义为LSC
typedef unsigned int uint16;//对数据类型进行声明定义
typedef unsigned char uchar8;//对数据类型进行声明定义
uchar8 code duanxuan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//段选显示0-F的值
void delay(uint16);//声明延时函数
void DigDisplay();//声明数码管显示函数
													
void main()
{
	//发送位选
	while(1)
	{
		DigDisplay();		
	}			
}

void DigDisplay()//位选、段选函数,即选择点亮第几个数码管,并显示数字几
{
	uchar8 i;
	for(i=0;i<8;i++)
	{
		switch(i)
		{
			case(0):LSA=1;LSB=1;LSC=1;break;//显示第0位,即点亮LED8,左1
			case(1):LSA=0;LSB=1;LSC=1;break;//显示第1位,即点亮LED7,左2
			case(2):LSA=1;LSB=0;LSC=1;break;//显示第2位,即点亮LED6,左3
			case(3):LSA=0;LSB=0;LSC=1;break;//显示第3位,即点亮LED5,左4
			case(4):LSA=1;LSB=1;LSC=0;break;//显示第4位,即点亮LED4,左5
			case(5):LSA=0;LSB=1;LSC=0;break;//显示第5位,即点亮LED3,左6
			case(6):LSA=1;LSB=0;LSC=0;break;//显示第6位,即点亮LED2,左7
			case(7):LSA=0;LSB=0;LSC=0;break;//显示第7位,即点亮LED1,左8	
		}
		P0=duanxuan[i];//发送段选,即选择显示数字几
		delay(100);//延时函数,大约延时1ms
		P0=0x00;//消隐
	}
}

void delay(uint16 x)//延时函数,x=1时大约延时10us
{
	while(x--); 
}


5.2 编译

编译过程同1.2一致。

5.3 程序下载

程序下载过程同1.3一致。

5.4 结果展示

  • 待上传视频

5.5 常见问题及解决办法

6. 独立按键

6.1 代码

/*********************
独立按键实验
实验现象:下载程序后按下K1按键可以对D1灯状态取反
日期:2020-04-13
作者:lixs
**********************/

#include <reg52.h>
sbit led=P2^0;//将单片机P2.0端口定义为led
sbit k1=P3^1;//将单片机P3.1端口定义为k1
typedef unsigned int uint16;//对数据类型进行声明定义
typedef unsigned char uchar8;//对数据类型进行声明定义
void delay(uint16);//声明延时函数
void keypros();
													
void main()
{
	led=1;					
	while(1)
	{
		keypros();	
	}			
}

void keypros()			//按键处理函数
{
	if(k1==0)				//检测按键是否按下
	{
		delay(1000);//延时10ms,消除抖动
		if(k1==0)
		{
			led=~led;//led状态取反
		}
		while(!k1);	/*!k1 = !k1==1 = k1==0 检测按键是否松开,
								如k1=0则表示还没松开,保持在当前循环,
								k1=1则表示松开,跳出当前循环等待下次状态变化*/
	}
	
}

void delay(uint16 x)//延时函数,x=1时大约延时10us
{
	while(x--); 
}


6.2 编译

编译过程同1.2一致。

6.3 程序下载

程序下载过程同1.3一致。

6.4 结果展示

  • 待上传视频

6.5 常见问题及解决办法

7. 矩阵按键

7.1 代码

/*********************
矩阵按键实验
实验现象:下载程序后数码管显示0,按下矩阵按键上的按键显示对应的数字
日期:2020-04-13
作者:lixs
**********************/

#include <reg52.h>
#define GPIO_DIG P0//将单片机P0端口定义为GPIO_DIG,即可用GPIO_DIG代替P0
#define GPIO_KEY P1//将单片机P1端口定义为GPIO_KEY,即可用GPIO_DIG代替P1

typedef unsigned int uint16;//对数据类型进行声明定义
typedef unsigned char uchar8;//对数据类型进行声明定义
uchar8 code duanxuan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//段选显示0-F的值
uchar8 KeyValue;
void delay(uint16);//声明延时函数
void KeyDown();
													
void main()
{
		while(1)
		{
			KeyDown();
			GPIO_DIG=duanxuan[KeyValue];
		}			
}

void KeyDown()
{
	char a=0;
	GPIO_KEY=0x0f;
	if(GPIO_KEY!=0x0f)
	{
		delay(1000);
		if(GPIO_KEY != 0x0f)
		{
			GPIO_KEY=0x0f;  
			switch(GPIO_KEY)
			{
				case(0x07):KeyValue=0;break;
				case(0x0b):KeyValue=1;break;
				case(0x0d):KeyValue=2;break;
				case(0x0e):KeyValue=3;break;
			}
			GPIO_KEY=0xf0;
			switch(GPIO_KEY)
			{
				case(0x70):KeyValue=KeyValue;break;
				case(0xb0):KeyValue=KeyValue+4;break;
				case(0xd0):KeyValue=KeyValue+8;break;
				case(0xe0):KeyValue=KeyValue+12;break;
			}
		}
	}
	while((a<50)&&(GPIO_KEY != 0xf0))
	{
		delay(100);
		a++;
	}
}

void delay(uint16 x)//延时函数,x=1时大约延时10us
{
	while(x--); 
}


7.2 编译

编译过程同1.2一致。

7.3 程序下载

程序下载过程同1.3一致。

7.4 结果展示

  • 待上传视频

7.5 常见问题及解决办法

8. 单片机IO扩展–74HC595

8.1 代码

/*********************
点阵LED实验
实验现象:下载程序后,
点阵LED灯从左往右依次点
亮,类似流水灯效果
日期:2020-04-14
作者:lixs
**********************/

#include <reg51.h>
#include <intrins.h>
typedef unsigned int uint16;//对数据类型进行声明定义
typedef unsigned char uchar8;//对数据类型进行声明定义
uchar8 ledNum;
//**定义IO口**//
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
sbit LED=P0^7;


//**声明函数**//
void Hc595SendByte(uchar8 dat);//声明发送数据函数
void delay(uint16);//声明延时函数

													
void main()
{
		LED = 0;
    ledNum = 0x01;//0000 0001
    while(1)
    {
        Hc595SendByte(ledNum);
        ledNum = _crol_(ledNum,1);//0000 0010
        delay(50000);	
    }		
}

void Hc595SendByte(uchar8 dat)//向74H595发送一个字节数据
{
	uchar8 a;
	SRCLK = 1;
  RCLK = 1;

	for (a = 0; a < 8; a++)
	{
			SER = dat >> 7;//将dat中的最高位D7位赋给SER
			dat <<= 1;//左移将dat中的最高位去掉,用D6位取代D7位

			SRCLK = 0;//移位时钟
			_nop_();
			_nop_();
			SRCLK = 1;//移位时钟
	}
	RCLK = 0;//储存寄存器的时钟
	_nop_();//51中的延时指令,延时一个机器周期,大约1us
	_nop_();//51中的延时指令,延时一个机器周期,大约1us
	RCLK = 1;//储存寄存器的时钟,一个上升沿将数据存在存储寄存器内
}


void delay(uint16 x)//延时函数,x=1时大约延时10us
{
	while(x--); 
}


8.2 编译

编译过程同1.2一致。

8.3 程序下载

程序下载过程同1.3一致。

8.4 结果展示

  • 待上传视频

8.5 常见问题及解决办法

9. LED点阵(点亮一个点)

9.1 代码

/*********************
点阵LED实验
实验现象:下载程序后,
点阵LED灯第一个点亮
日期:2020-04-14
作者:lixs
**********************/

#include <reg51.h>
#include <intrins.h>
typedef unsigned int uint16;//对数据类型进行声明定义
typedef unsigned char uchar8;//对数据类型进行声明定义
uchar8 Num;
//**定义IO口**//
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
sbit LED=P0^7;


//**声明函数**//
void Hc595SendByte(uchar8 dat);//声明发送数据函数


													
void main
						

上一篇: 使用AT89C51单片机打造的模拟版贪吃蛇电子游戏

下一篇: 实现在89c51微控制器上的16x16像素点阵显示器