Proteus软件初学笔记

@[toc]

Proteus软件初学

一、常用元器件

二、学习视频

Proteus使用教程可以查看该视频链接,我觉得讲的挺好的:www.bilibili.com/video/BV1Y7...

Keil5 结合Proteus 的使用可以看一下该视频: www.bilibili.com/video/BV1H7...

三、Project

1、晶振电路和复位电路

时钟电路

  • 芯片:AYM89C51

  • 晶振:CRY,12M

  • 电容:CAP,22pf

  • 作用:晶振电路是给单片机提供时钟信号的。晶振电路产生单片机必须要用到的时钟频率,单片机发送的所有指令都是建立在这个基础上的

  • 晶振的时钟频率越高,单片机的运行速度越快。它是一条条的从ROM中获取指令,然后再去执行。单片机每访问一次存储的时间叫做机器周期,机器周期又被分为12个时钟周期
    复位电路:上电复位,按键复位

  • 电阻:RES

  • 作用:利用它把电路恢复到起始状态,像计算器的清零按钮的作用一样,以便回到原始状态,重新进行计算。

2、LED流水灯的实现

2.1、LED原理

LED,选带ACTIVE的,可以看得到元器件的可视化,是亮还是灭 电流方向:P ----> N 如果是硅,0.7V,如果是锗,0.3V

2.2、供阳极接法和供阴极接法

==供阳极接法==:将所有LED的P极接一起,此时N极需要接低电平,低电平亮,高电平灭,==低电平有效== ==供阴极接法==:将所有LED的N极接一起,此时P极需要接高电平,==高电平有效== 单片机可以吸入的电流为20mA,所以阳极接法需要有电阻(电阻阻值不得小于250)才能与单片机相连

2.3、呼吸灯实现闪烁的代码

c 复制代码
#include"reg51.h"
// sbit 表示对位进行控制 
sbit LED0 = P2^0;
/*
 * 延时函数 
 * 延时函数`delay()`的本质:通过空语句占用程序的时间,从而达到延时的效果
*/
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void main()
{
	while(1)
	{
		LED0 = 0;//亮
		delay(5);//加入延时函数
		LED0 = 1;//灭
		delay(5);//加入延时函数
	}
}

2.4、呼吸灯实现代码(供阳极和供阴极接法)

c 复制代码
#include"reg51.h"
// sbit 表示对位进行控制 
sbit LED0 = P2^0;
/*
 * 延时函数 
*/
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

/*
 * 实现流水灯效果
*/
void led()
{
	int i=0;
	for(i=0;i<8;i++)
	{
		/*
		* 因为是低电平亮,所以进行取反操作,
		* 因为实现流水灯操作,所以进行移位操作
		* P2 为供阳极接法
		* P1 为供阴极接法
		*/
		P2=~(0x01<<i);//~0000 0001 ->0000 0010 -> 0000 0100	
		P1=(0x01<<i);//~0000 0001 ->0000 0010 -> 0000 0100		
		delay(50);
	}
}

void main()
{
	while(1)
	{
		led();
	}
}

2.5、通用流水灯的操作

将输出的数据用数组进行表示,用 for循环将其遍历出来 代码如下:

c 复制代码
#include"reg51.h"
// 轮流滚动的小灯数据
unsigned char leddat[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void led()
{
	int i=0;
	for(i=0;i<8;i++)
	{
		P2=~leddat[i];
		delay(100);
	}
}

void main()
{
	// 保证程序能够不断运行
	while(1)
	{
		led();
	}
}

2.6、实现花式流水灯效果

c 复制代码
#include"reg51.h"
unsigned char leddat[50]={
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x81,0x82,
0x84,0x88,0x90,0xA0,0xC0,0xC1,0xC2,0xC4,0xC8,0xD0,
0xE0,0xE1,0xE2,0xE4,0xE8,0xF0,0xF1,0xF2,0xF4,0xF8,	
0xF9,0xFA,0xFC,0xFD,0xFE,0xFF,0xFF,0x00,0xFF,0x00
};

/*延迟函数 */
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void led()
{
	int i=0;
	for(i=0;i<50;i++)
	{
		P2 = ~leddat[i];
		delay(100);
	}
}

void main()
{
	while(1)
	{
		led();
	}
}

3、数码管

3.1、数码管的结构和原理

3.2、数码管上显示字母和数字

  • dp:是小数点位置

3.3、LED数码管的静态显示和动态显示

1、静态显示方式

2、特点

  1. 公共端直接接地(供阴极)或接电源(供阳极)
  2. 每个数码的段选线与一组 I/O 接口线相连
  3. 每个数码管一直显示

3、实现效果 :从0--9反复变化的电路图

以阴极接法为例

4、代码

c 复制代码
#include"reg51.h"
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};// 供阴0--9



/*
 * 延迟函数
*/
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

/*
 * 显示函数
*/
void seg()
{
	//P2 = 0x3F;//0011 1111
	int i =0;
	for(i=0;i<10;i++)
	{
		P2 = s[i];
		delay(300);
	}
}

void main()
{
	while(1)
	{
		seg();
	}
}

==注意:供阳极接法同上,需要更换的是数码管,接法以及代码中的取反==

3.4、LED数码管的动态显示

1、原理

  • 特点
  1. 从下到上依次为:a,b,c,d,e,f,,g,db
  2. 所有数码管的段选线与一组 I/O 接口线并连在一起
  3. 每个数码管的公共端由一根 I/O 线控制
  4. 显示为逐个显示

2、实现效果

3、代码

c 复制代码
#include"reg51.h"
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};// 供阴0--9
unsigned char str[]={0x76,0x79,0x38,0x38,0x3F};// HELLO
unsigned char wei[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//显示不同的位
// 若将显示器1-8直接与单片机10-17连接,显示不同的位使用以下这种
// unsigned char wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};


/*
 * 延迟函数
*/
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

/*
 * 显示函数
*/
void seg()
{
	//P2 = 0x3F;//0011 1111
	int i =0;
	for(i=0;i<5;i++)
	{
		P3=wei[i];
		P2 = str[i];//0011 1111
		delay(5);
	}
}

void main()
{
	while(1)
	{
		seg();
	}
}

4、按键

4.1、键盘的基本原理

4.2、抖动的消除

抖动大概10ms~20ms

4.3、键盘的分类

4.4、矩阵键盘键位的识别

4.5、实现效果

代码

c 复制代码
#include"reg51.h"
sbit key0=P1^0;
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};// 供阴0--9
unsigned char num=0,flag=0;

void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}
// 按键操作
void key()
{
//	if(key0==0)
//	{
//		num++;
//	}
		if(key0==0&&flag==0)
	{
		flag=1;
	}
	if(flag==1&&key0==1)
	{
		num++;
		flag=0;
	}
}

// 数码管操作,利用标志位消除抖动
void seg()
{
	P2=s[num];
	if(num==10)
	{
		num=0;
	}

}

void main()
{
	while(1)
	{
		key();
		seg();
	}
	
}

5、定时器

5.1、定时/计数器的方式和控制寄存器

6、中断

6.1、中断简介

6.2、中断允许控制

标识中带T的表示与定时器有关

6.3、优先权控制

6.4、各中断服务程序的入口编号

6.5、外部中断

外部中断,低电平,下降沿触发。

6.6、电路图

6.7、代码

实现防抖动操作,按一下键盘num值加一次

c 复制代码
#include"reg51.h"
sbit ex=P3^2;
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x7D,0x07,0x7F,0x6F};//供阴极0-9
unsigned char num=0;

void initex()
{
	IT0=1;//设置边沿触发
	EX0=1;//打开外部中断
	EA=1;//进行使能,开启总中断
	ex=1;设置为下降沿
	
}
void display()
{
	P2=s[num];
	if(num===10)
	{
		num=0;
	}
}

void main()
{
	initex();
	while(1)
	{
		display();
	}
}

7、串行口通信

以下各位为0时表示可以接受,1表示接收完成

7.1、串行口 控制寄存器SCON

控制串行口的通信方式,串口的区别在于波特率不同,一般方式1用的比较多

7.2、电源控制寄存器PCON

7.3、方式1的工作方式

8、模拟89C51与上位机之间的通信

8.1、电路图

8.2、代码

c 复制代码
#include"reg51.h"
unsigned char recdat=0,flag=0;

void initscon()
{
	// 串行口控制寄存器
	SCON=0x50;// 0101 0000
	// 配置波特率,由定时器T1产生,参数为:(是1否0与外部中断有关系,选择定时器0还是计数器1的模式,模式0-13位,01-16位,10-8位)
	TMOD=0x20;// 0010 0000
	// 配置初值
	TH1=256-3;
	TL1=256-3;
	ES=1;// 串口中断
	EA=1;//开启总中断
	TR1=1;//打开定时器1

}

// 发送数据
void senddat()
{
	SBUF=recdat;
	while(!T1);
	T1=0;
	
}

void main()
{
	// 初始化串口
	initscon();
	while(1)
	{
		//发送数据,通过中断发送 
		//接收数据,接收返回来的数据
		if(flag==1)
		{
			senddat();
			flag=0;
		}
	}
}

// 串口中断服务函数
// 0是外部中断,1是定时器0的中断,2是外部中断1,3是定时器中断1,4是串口中断
void scon_isr() interrupt 4
{
	// SBUF表示缓存
	recdat=SBUF;
}

9、LCD1602的应用

9.1、LCD1602概述

LCD1602是2*16字符型液晶显示模块

9.2、常用指令码

9.3、读写时序图

9.4、电路图一

AT89C51和LM016L

9.5、代码一

c 复制代码
#include"reg51.h"
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
unsigned char str[]={"count:"};
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void writedat(unsigned char dat)
{
	RS=1;
	RW=0;
	E=0;
	P2=dat;
	delay(5);
	E=1; 
	E=0;
}


void writecom(unsigned char com)
{
	RS=0;
	RW=0;
	E=0;
	P2=com;
	delay(5);
	E=1; 
	E=0;
}


void initlcd()
{
	// 写入命令
	writecom(0x38);
	writecom(0x0c);
	writecom(0x06);
	writecom(0x01);
	
}



// 显示函数
void display()
{
	unsigned int i=0;
	writecom(0x80);
	delay(5);
//	writedat('A');
//	delay(5);
//	writedat('B');
//	delay(5);
	while(str[i]!='\0')
	{
		writedat(str[i]);
		delay(5);
		i++;
	}
	writedat(0x36);
	delay(5);
}

void main()
{
	initlcd();
	while(1)
	{
		display();
	}
}

9.6、电路图二

9.7、代码二

c 复制代码
#include"reg51.h"
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
unsigned char count=0;
unsigned int hour=0,min=0,sec=0;
unsigned char str1[]={"clock"};
// 数字转字符用
unsigned char str[]={"0123456789"};	
	
void delay(unsigned int n)
{
	unsigned int i=0,j=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<120;j++);
	}
}

void writedat(unsigned char dat)
{
	RS=1;
	RW=0;
	E=0;
	P2=dat;
	delay(5);
	E=1; 
	E=0;
}


void writecom(unsigned char com)
{
	RS=0;
	RW=0;
	E=0;
	P2=com;
	delay(5);
	E=1; 
	E=0;
}


void initlcd()
{
	// 写入命令
	writecom(0x38);
	writecom(0x0c);
	writecom(0x06);
	writecom(0x01);
	
}



// 显示函数
void display()
{
	unsigned char i=0;
	unsigned char temp0=0,temp1=0,temp2=0,temp3=0,temp4=0,temp5=0;
	temp0=hour/10;
	temp1=hour%10;
	temp2=min/10;
	temp3=min%10;
	temp4=sec/10;
	temp5=sec%10;
	writecom(0x80);
	delay(5);
	while(str1[i]!='\0')
	{
		writedat(str1[i]);
		delay(5);
		i++;
	}
	writecom(0x80+0x40+4);//控制在中间显示
	writedat(str[temp0]);
	delay(5);
	writedat(str[temp1]);
	delay(5);
	writedat(':');
	delay(5);
	writedat(str[temp2]);
	delay(5);
	writedat(str[temp3]);
	delay(5);
	writedat(':');
	delay(5);
	writedat(str[temp4]);
	delay(5);
	writedat(str[temp5]);
	delay(5);
}
/*定时器*/
void inittimer()
{
	TMOD=0x01;// 选择定时器模式为16位
	TH0=(65536-50000)/256;//50ms
	TL0=(65536-50000)%256;
	ET0=1;//中断
	EA=1;//打开中断
	TR0=1;//开启定时器0
}
	

void main()
{
	initlcd();
	inittimer();
	while(1)
	{
		display();
	}
}

//定时器中断函数
void timer0_isr() interrupt 1
{
	TH0=(65536-50000)/256;//50ms
	TL0=(65536-50000)%256;
	count++;
	if(count==20)//1s
	{
		sec=sec+1;
		count=0;
	}
	if(sec==60)
	{
		min=min+1;
		sec=0;
	}
	if(min==60)
	{
		hour=hour+1;
		min=0;
	}
	if(hour==24)
	{
		hour=0;
	}
}

9.8、实现电子时钟

10、点阵

10.1、电路图

10.2、代码

实现0

11、DA转换原理及简易波形发生器的实现

12、外部中断

12.1、电路图

12.2、代码

外部中断实现按键:添加外部中断,当按下按键,触发外部中断,低电平,小灯亮,再次按下,小灯电平值取反(或使用下降沿触发,当按下时灯亮,抬起时灯灭)

c 复制代码
// 变量定义
uchar key_num; // 键值
// 函数声明
void Delay_function(uint x); //延时函数
void Key_function(void); //按键函数
void Monitor_function(void); // 监测函数
void Display_function(void); // 显示函数
void Manage_function(void); // 处理函数
void Int0_Init(void); // 外部中断0初始化函数
void Int1_Init(void); // 外部中断1初始化函数
// 主函数
void main()
{
	Int0_Init(); //外部中断0初始化
	Int1_Init(); //外部中断1初始化
  	while(1)
	{
		Key_function(void);//按键函数
		Monitor_function(void);// 监测函数
		Display_function(void);// 显示函数
		Manage_function(void);// 处理函数
	}
}
//延时函数
void Delay_function(uint x);
{
	uint m,n;
	for(m=x;m>0;m--)
	for(n=110;n>0;n--);
}
//按键函数
void Key_function(void)


// 监测函数
void Monitor_function(void)
{

}
// 显示函数 
void Display_function(void)
{

}
// 处理函数 
void Manage_function(void)
{

}
// 外部中断0初始化函数
void Int0_Init(void)
{
	EA=1;// 打开总中断
	EX0=1;// 允许外部中断0触发中断
	IT0=1;// 设置外部中断触发方式,方式为下降沿触发
}
// 外部中断1初始化函数
void Int1_Init(void)
{
	EA=1;// 打开总中断
	EX0=1;// 允许外部中断1触发中断
	IT0=1;// 设置外部中断触发方式,方式为低电平触发
}
// 外部中断0中断服务函数
void Int0_IRQHandler(void) interrupt 0
{
	LED = ~LED;
}
// 外部中断01中断服务函数
void Int1_IRQHandler(void) interrupt 2
{
	LED = ~LED;
}

13、单片机串口

#include<reg51.h> // 去系统默认的路径查找头文件,不推荐使用 #include"reg51.h" // 先去用户自定义的路径查找,再去系统默认的路径查找,推荐使用

延时函数delay()的本质:通过空语句占用程序的时间,从而达到延时的效果

相关推荐
WZF-Sang21 小时前
Linux—进程学习-01
linux·服务器·数据库·学习·操作系统·vim·进程
Goboy1 天前
0帧起步:3分钟打造个人博客,让技术成长与职业发展齐头并进
程序员·开源·操作系统
结衣结衣.2 天前
【Linux】Linux管道揭秘:匿名管道如何连接进程世界
linux·运维·c语言·数据库·操作系统
OpenAnolis小助手2 天前
龙蜥副理事长张东:加速推进 AI+OS 深度融合,打造最 AI 的服务器操作系统
ai·开源·操作系统·龙蜥社区·服务器操作系统·anolis os
小蜗的房子3 天前
SQL Server 2022安装要求(硬件、软件、操作系统等)
运维·windows·sql·学习·microsoft·sqlserver·操作系统
邂逅岁月4 天前
【多线程奇妙屋】 Java 的 Thread类必会小技巧,教你如何用多种方式快速创建线程,学并发编程必备(实践篇)
java·开发语言·操作系统·线程·进程·并发编程·javaee
CXDNW6 天前
【系统面试篇】进程和线程类(1)(笔记)——区别、通讯方式、同步、互斥、死锁
笔记·操作系统·线程·进程·互斥·死锁
Anemone_6 天前
MIT 6.S081 Lab3
操作系统
掘了7 天前
持久化内存 | Persistent Memory
c++·架构·操作系统
结衣结衣.8 天前
【Linux】掌握库的艺术:我的动静态库封装之旅
linux·运维·服务器·c语言·操作系统·