简易光照反馈系统

简述

这个简易系统由51单片机为主控芯片,制作一个根据光照强度展现不同亮度的照明LED,并在LCD1602上显示目前的光照强度是强或弱。光照强度用三个小灯来表示。亮度为1000则一个灯亮起,1001-2000则两个灯亮起,2001-3500则三个灯亮起。

Keil编写程序,编译出HEX导入到Proteus搭建的电路当中实现功能后,焊接实物电路

问题

刚开始做的时候可能会遇见的问题

1.关于Proteus中仿真电路图的制作

~元器件代码不了解

~不会用辅助工具

~各个元器件之间应该如何进行连接

~如何在仿真电路中导入Keil中编译好的HEX文件

2.Keil编写程序

~TLC2543+LCD1602驱动程序的使用

~如何让LCD1602显示出TLC2543测量得到的值

~端口设置

~编写头文件

3.实物焊接

~虚焊:可能表面上连接到了,但是实际上并没有连接

~短路:可能是不同元器件之间的短路,也可能是相同元器件之间的短路

功能

1:以51单片机为主控芯片,LCD1602的数据接口D0~D7使用P0口

2:模数转换芯片使用TLC2543

3:LCD1602的显示内容有TLC2543上收到的值、LED亮度变化的阈值

4:LCD1602显示的亮度变化的阈值要可以通过按键改变

(ps:亮度的初始化阈值1000,2000这两个个数值(min=0,max=3500)。这里我用了三个按键,k1控制k2和k3加还是减,k2控制第一个阈值,k3控制第二个阈值。每一次加减为500。我设置的第一个阈值在0-1500,第二个阈值在2000-3500;若加减阈值小于或者超出临界值,则当前按键按下无效)

具体操作

仿真电路的搭建

一.软件的下载

二.工程的建立

这里可以找到如何创建工程,同时还有一些其他可以借鉴的搭建电路的方法

三.连接

芯片与单片机连接并不是任意的,需要阅读相关的中文资料,找到对应的功能管脚,与单片机相应的管脚相连

TLC中文资料+LCD1602中文资料

四.元器件

刚开始我使用Proteus是比较困难的,这里可以把要用到的元器件列出来

要连接两个端口,可以点击一个端口,就会跳出一根线,然后将线拉至想要连接的另一个端口,再点击一下就完成了。

(元器件可以设置大小,刚开始找到的可能不太合适,可以双击元件进行设置进行设置)

 

1.CAP 33pF电容 2.CAP-ELEC  4.7uF电容 3.BUTTON 按 4.POT-HG 滑动变阻器

5.RES 电阻 可设置阻值 6.LDR 光敏电阻 7.CRYSTAL  12MHZ 晶振 8.LED-BIBY  普通的LED

9.TLC2543 模数转换芯片 10.LM016L LCD1602显示芯片 11.80C51 主控芯片

 

4.构建好51单片机最小系统

最小系统包括主控芯片、复位电路以及晶振电路

主控芯片:单片机P0端口连接上拉电阻

复位电路:9脚利用BUTTON(按键),CAP-ELEC(电容),RES(电阻)搭建复位电路

起振电路:18,19脚用一个晶振,两个电容

(ps:刚开始使用Proteus时,可以用接线端子整理电路,如图P0端口与上拉电阻的连接就是使用的接线端子)

 

终端模式中的DEFAULT中可以找到

2.将TLC2543+LM016L(LCD1602)连接到51单片机上。同时连接上按键,使得LCD1602显示的亮度变化的阈值(即)可以通过按键改变

TLC2543的连接:AIN0(1脚)连接在光敏电阻和电阻之间(这里可以选择1-12任意一个管脚,具体看怎么让编程和焊接时更加简洁方便),接收变化,并将接收到的值转化为数字。SDO\SDI\_CS\CLK这四个管脚在这可以选择单片机上没有被来连接的管脚,我这里选择的是6、7、8、16四个管脚,编写时要注意定义好端口。通过SDO将数据发送给单片机。

LCD1602的连接:D0~D7管脚连接在单片机P0端口(即32-39管脚),在上拉电阻之前。L RW/RS/E三个管脚连接在26-28三个管脚上。VDD接电源,VSS接地,VEE连接滑动变阻器,滑动变阻器接地(通过改变滑动变阻器的阻值,控制LCD1602的亮度)。

3.仿真

仿真电路搭载好之后,可以将Keil编译好的HEX文件导入到单片机中,如图所示

1.双击单片机编辑元件

2.导入编译好的HEX文件

3.开始进行仿真(左下角的三角形。正方形是停止)

注意:

1.每个芯片都要连接电源接地,在同一个项目之中还要共地;

2.在Proteus中,TLC2543&LCD1602电源管脚和接地管脚都没有显示出来,所以在焊接实物的之后要注意连接

 

实物焊接

如图,实物焊接一定要小心,不要短路,防止发生意外!

此外:在之前也提到芯片要通电才能正常使用,Proteus中有些芯片可能没有显示出来,在实物焊接的时候要注意连接;不然像LCD1602屏幕会很暗;同时,要注意它的哪个管脚接高,哪个管脚接低,接反可能会导致显示屏第二排无法显示出来。管脚的连接可以看之前的数据手册。

代码

1.分为三个文件

main.c+all.c+all.h

  • 芯片端口的定义可以放在main.c中,也可以放在头文件里面
  • 函数可以放在main.c中,也可以放在all.c中,不过这样就要在头文件中进行声明
  • # 表示预编译
  • 头文件一般以 #ifndef 开头,#endif结尾

2.具体代码

main.c

#include "all.h"
/*****全局变量*******/
u16 value;	   //TLC2543获取的值
u16	key=1000;  //第一个阈值
u16 change=2000;  //第二个阈值
int i,j;
long volt;

bit keep;
///******TLC2543**********/
//sbit SDO=P1^5;
//sbit SDI=P1^6;
//sbit _CS=P1^7;
//sbit CLK=P3^6;

/*********灯***********/
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
//定义按键端口
sbit k1 = P1^1;
sbit k2 = P1^2;
sbit k3 = P1^3;

///******LCD1602**********/

//sbit RS = P2^6;
//sbit RW = P2^5;
//sbit EN = P2^7;
//sbit LCD1602_E=P2^7;
//sbit LCD1602_RW=P2^5;
//sbit LCD1602_RS=P2^6;


/*延时函数*/
void delay1(u16 i) {
	while(i--);
}

void delay(uchar n) {
	uchar i;
	for(i=0; i<n; i++) {
		_nop_();
	}
}


/*2543启动函数*/
uint read2543(uchar port) {
	uint ad=0,i;
	CLK=0;
	_CS=0;
	port<<=4;
	for(i=0; i<12; i++) {
		if(SDO) ad|=0x01;
		SDI=(bit)(port&0x80);
		CLK=1;
		delay(3);
		CLK=0;
		delay(3);
		port<<=1;
		ad<<=1;
	}
	_CS=1;
	ad>>=1;
	volt=ad*1.221;
	return(volt);
}

/*按键函数*/
void keypros() {
	if(k1 == 0) {
		keep = 1;//模式加
	} else if(k1 == 1) {
		keep = 0;//模式减
	}
	if((k2 == 0)&&(keep == 0)) {
		key+=500;
	} else if((k2 == 0)&&(keep == 1)) {
		key-=500;
	}
	if((k3 == 0)&&(keep == 0)) {
		change+=500;
	} else if((k3 == 0)&&(keep == 1)) {
		change-=500;
	}
} 

void LED() {
	if(value>change) {
		LED1 = 1;
		LED2 = 1;
		LED3 = 1;
	} else if(key<=value && value<=change) {
		LED1 = 1;
		LED2 = 1;
		LED3 = 0;
	} else if(0<value && value<key){
		LED1 = 1;
		LED2 = 0;
		LED3 = 0;
	} else{
	    LED1 = 0;
		LED2 = 0;
		LED3 = 0;
	}
}

/*阈值范围检测*/
void test() {
	if(change>key)
	{
		if((key>=0)&&(key<=1500))
		{
			key=key;
		}else if(key>=1500){
			key=1500;
		}else{
			key=0;
		}
		
		if(change<3500){
			change=change;
		}else{
			change=3500;
		}
	}
	else
	{
		key=1000;
		change=2000;
	}
}
//void LED(){
//	if(value>2000)
//	{
//		LED1 = 1;
//		LED2 = 1;
//		LED3 = 1;
//	}else if(1000<=value && value<=2000) {
//		LED1 = 1;
//		LED2 = 1;
//		LED3 = 0;
//	} else{
//		LED1 = 0;
//		LED2 = 0;
//		LED3 = 0;
//	}
//}


/*LCD1602显示函数*/
void LCD_Display_AD(void) {

	LcdWriteCom(0x80);

	LcdWriteData('A');
	LcdWriteData('D');
	LcdWriteData(':');

	LcdWriteData((value%10000000/1000000) +'0');//百万
	LcdWriteData((value%1000000/100000) +'0');//十万
	LcdWriteData((value%100000/10000) +'0');//万
	LcdWriteData((value%10000/1000) +'0');//千
	LcdWriteData((value%1000/100) +'0');//百
	LcdWriteData((value%100/10) +'0');//十
	LcdWriteData((value%10) +'0');//个
	
	LcdWriteCom(0x80+0x40);

	LcdWriteData((key%10000/1000) +'0');//千
	LcdWriteData((key%1000/100) +'0');//百
	LcdWriteData((key%100/10) +'0');//十
	LcdWriteData((key%10) +'0');//个
	LcdWriteData(' ');
	LcdWriteData(' ');
	LcdWriteData((change%10000/1000) +'0');//千
	LcdWriteData((change%1000/100) +'0');//百
	LcdWriteData((change%100/10) +'0');//十
	LcdWriteData((change%10) +'0');//个
	
}

void main() {
	LcdInit(); //LCD初始化
	while(1) {
		value = read2543(0000);
		keypros();
		test();
		LED();
		LCD_Display_AD();//调用显示程序
	}
}

all.c

#include "all.h"
void Lcd1602_Delay1ms(uint c) { //误差 0us
	uchar a,b,j;
	for(j=c;j>0; j--) 
	{
		for(b=199; b>0; b--) 
		{
			for(a=1; a>0; a--);
		}
	}

}

void LcdWriteCom(uchar com) { //写入命令
	LCD1602_E = 0; 	//使能
	LCD1602_RS = 0;	//选择发送命令
	LCD1602_RW = 0; //选择写入

	LCD1602_DATAPINS = com;	//放入命令
	Lcd1602_Delay1ms(1);	//等待数据稳定

	LCD1602_E = 1; 	//写入时序
	Lcd1602_Delay1ms(5); 	//保持时间
	LCD1602_E = 0;
}

void LcdWriteData(uchar dat) {		//写入数据
	LCD1602_E = 0;	//使能清零
	LCD1602_RS = 1;	//选择输入数据
	LCD1602_RW = 0;	//选择写入

	LCD1602_DATAPINS = dat; //写入数据
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;   //写入时序
	Lcd1602_Delay1ms(5);   //保持时间
	LCD1602_E = 0;
}

void LcdInit(void) {	  //初始化子程序
	LcdWriteCom(0x38); //开显示
	LcdWriteCom(0x0c);	//开显示不显示光标
	LcdWriteCom(0x06);	//写一个指针加一
	LcdWriteCom(0x01);	//清屏
	LcdWriteCom(0x80); //设置数据指针起点
}

all.h

#ifndef	  __ALL_H_
#define   __ALL_H_


#include<reg52.h>
#include<intrins.h>

#define  LCD1602_DATAPINS    P0

typedef	unsigned int  uint;
typedef	unsigned char uchar;
typedef unsigned int u16;
typedef unsigned char u8;


/******TLC2543**********/ 
sbit _CS=P1^4;
sbit SDO=P1^5;
sbit SDI=P1^6;
sbit CLK=P1^7;

/******LCD1602**********/ 

sbit RS = P2^6;
sbit RW = P2^5;
sbit EN = P2^7;
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;
						 
void LcdWriteCom(uchar com);
void LcdWriteData(uchar dat);
void Lcd1602_Delay1ms(uint c);
void LcdInit(void);

#endif

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值