电脑串口控制单片机驱动继电器的例子
详解一个电脑串口控制单片机驱动继电器的例子(全部源代码)
开源详解(看完如觉得不错,请顶一下哦!)声明:软件版权归作者完全所有。
未经作者授权,请勿在任何第三方杂志、报刊、网站转载或发表,本程序仅供学习研究用,您可以自由拷贝、散发本程序,但不能用于商业目的。
很多网上认识的朋友,提到这个话题,在此用此例给热爱单片机的朋友!---一个简单的串口控制继电器的例子(全部源代码)-- 马工2006-5-8 20:00下面的文章详细的说明了如何在PC端编制控制程序,并且通过串口输出数据来控制单片机硬件,单片机外围连接了若干继电器,达到控制继电器开关的作用。
要说的是,有很多的方法可以实现上述的功能,下面的方法只是其中的一种,并且出于便于大家学习阅读的目的,很多代码并没有进行优化,而是将其展开编写,在你理解后,你完全可以在此基础上修改、优化代码,使之更优化和精简,并符合你的其他要求。
如果你读完这篇文章,觉得给你带来了帮助,我非常高兴。
如果你无法理解,你应该再看一下其他更基础的书籍、文章。
我想应该分成二个部分来讲(单片机部分、PC程序部分),并且希望能写得较为详细,把基础的讲述清楚。
1、单片机部分电路图:此主题相关图片如下:单片机源代码(asm格式):;--------------------------------------------------;--------------------------------------------------;设置串行口波特率9600;串行口设置MODE1,SM1=0,REN=1,SMOD=1;晶振11.0592,定时设置为0FDH;常用端口设置参数;FD 9600;FA 4800;F4 2400;E8 1200;--------------------------------------------------;*********************************************************** ORG 00HJMP STARTORG 23HJMP UARTORG 30HSTART: MOV SP,#70HMOV SCON,#50HMOV TMOD,#00100001B ;TIM1在模式2 TIM0在模式1MOV TH1,#0F4H ;设置定时时间SETB TR1 ;启动定时器1SETB ES ;允许串口中断SETB EA ;允许总中断MOV P0,#0 ;P0、P2输出低电平MOV P2,#0JMP $ ;等待状态;*****************************************;串行口中断;*****************************************UART: PUSH ACCPUSH PSWCLR ES ;关闭串行口中断MOV TH0,#HIGH(65536-65536)MOV TL0,#LOW(65536-65536)SETB TR0 ;开定时器0MOV 30H,#00 ;同步位MOV 31H,#00 ;数据1MOV 32H,#00 ;数据2MOV 33H,#00 ;结束位MOV R0,#30HREC:jbc tf0,FS ;接收时间是否超时?是则执行FSJNB RI,REC ;接收数据CLR RIMOV A,SBUFMOV @R0,AINC R0JMP RECFS: CLR TR0 ;关定时器0;********************************CALL FUN ;解码并控制继电器SETB ES ;开串行口中断POP PSWPOP ACCRETI ;中断子程序返回;**************************************** ;解码并控制继电器;下面的程序可以更简洁,但为了方便,展开来编制;**************************************** FUN: MOV A,#0AH ;判断第1字节即同步位CJNE A,30H,ERRMOV A,#0DH ;判断第4字节即结束位CJNE A,33H,ERR;****************************************;第2字节即数据位1,代表继电器J1-8;第3字节即数据位2,代表继电器J9-16;**************************************** MOV A,31HMOV P0,AMOV A,32HMOV P2,ARET;**************************************; 数据错误处理;************************************** ERR:MOV 30H,#00 ;同步位MOV 31H,#00 ;数据1MOV 32H,#00 ;数据2MOV 33H,#00 ;结束位RETEND ;程序结束;--------------------------------------------------;--------------------------------------------------单片机源代码(asm格式)+电路图下载:点击浏览该文件电路图说明:这个电路非常典型,串行口(也称RS232)接口集成电路MAX232与单片机AT89S51引脚P3.0(RXD)\P3.1(TXD)连接,构成与主机的通讯接口电路。
PC控制单片机继电器开关程序
sbit k6= P2^5;
sbit k7= P2^6;
sbit k8= P2^7;
bit n;
void keyboard()
{
n=key1;
while(8)
{
if(n!=key1)
{
delay1(10);
if(n!=key1)
case 0xFD: K2=1;delay(k);SBUF = dat;dat=0xee;write=1;break; // 第二路关
case 0xFC: K3=1;delay(k);SBUF = dat;dat=0xee;write=1;break; // 第三路关
case 0xFB: K4=1;delay(k);SBUF = dat;dat=0xee;write=1;break; // 第四路关
case 0x04: K4=0;delay(k);SBUF = dat;dat=0xee;write=1;break; // 第四路开
case 0x05: K5=0;delay(k);SBUF = dat;dat=0xee;write=1;break; // 第五路开
case 0x06: K6=0;delay(k);SBUF = dat;dat=0xee;write=1;break; // 第六路开
{
k1=~k1;
n=key1;
}
}
unsigned char x24c08_read(unsigned char address)
{
unsigned char i;
start(); writex(0xa0);
clock(); writex(address);
51单片机串口控制继电器
51单片机串口控制继电器
实验室有个项目,用到报警功能。
比如当温度或应力过高或者过低的时候启动报警器,通过给串口发送一个命令来控制继电器。
不巧去年被我正负极接反烧了,最近开始搞单片机,哥苦心经营,利用实验室单片机学习板给搞定了,程序如下:
#include;
#define uchar unsigned char
sbit JDQ=P3^7; //继电器接P3.7
sbit FMQ=P3^6;
sbit LED=P0^0;
sbit LEDra=P0^1;
sbit LEDar=P0^2;
uchar dat[4];
int i=0;
void Delay(unsigned int ii) //1mS
{
unsigned int jj;
for(;ii>;0;ii--)
for(jj=0;jj;=4)i=0;else;
}
EA=1;
}
main() //串口方式1发送时的定时信号,也就是移位脉冲,由定时器1产生。
不是定时器0。
{
init_serialcom();
Delay(10);
while(1);
}
第一次独立写的,程序粗糙了点,但是完美运行。
发送:E5A1 104E,继电器闭合
E5A1 114D,继电器断开
这里控制用到了四个字节,所以在中断程序里面我定义了一个数组,最后判断这四个字节是否都正确。
如果一个字节的话更简单。
下一步要用无线控制,等哥哥好消息吧。
单片机控制继电器的原理
单片机控制继电器的原理
单片机控制继电器的原理是通过单片机的IO口输出电平信号
来控制继电器的开关动作。
继电器是一种电磁开关,具有较大的电流和电压容量,可以实现对高功率设备的控制。
单片机通常通过GPIO(General Purpose Input Output)口来控
制继电器。
GPIO口可以通过配置寄存器来设置为输出模式。
在输出模式下,单片机可以将数字电平信号输出到GPIO口,
即可以控制高电平或低电平。
在控制继电器时,可以通过GPIO口输出高电平或低电平信号。
在某些型号的继电器中,高电平可以表示继电器的闭合状态,低电平表示继电器的断开状态;而在另一些型号的继电器中,情况恰好相反。
因此,在使用具体型号继电器时,需要根据其规格书来确定高低电平的含义。
当单片机的GPIO口输出电平与继电器的工作电平匹配时,继
电器将打开或关闭。
通过这种方式,单片机可以控制继电器的状态,从而控制与继电器相连的电路的通断。
需要注意的是,单片机的GPIO口一般只能提供较小的电流,
因此在连接继电器时,通常需要使用电流放大器或者继电器驱动电路来增加电流的驱动能力,以确保继电器可靠地工作。
此外,为了保护单片机的IO口,通常还会在继电器与单片机之
间加入保护电路,如继电器的阻抗匹配电路、电流限制电路等,以防止继电器产生的电压、电流冲击对单片机造成损坏。
单片机驱动继电器仿真实验(按键控制)
sbit ks=P2^5; //定义开始按键连接 P 口
main()
{
while(1)
{ if(ks==0) { lamp=0;
//如果开始按键按下 //点亮灯泡
} if(tz==0) { lamp=1;
//如果停止按键按下 //熄灭灯泡
}
}
}
在上述 4 个程序段中我们发现,在程序的开头都进行了位定义。这种编程方 法的一个优点是程序通用性强。读者可以直接把程序复制到自己的系统中,只修 改程序开头的定义行的几个地址即可。
。由于普通按键的原理决定,普通按键都具有抖动的特点,也就是说,当按键 的静触头和动触痛接触瞬间,会产生抖动现象,简单说就是瞬间接通,又瞬间断 开的现象。这种现象会对原理图 1 所示的程序造成影响,产生按键按下后,有时 有效,有时没有效的现象。因此在进行实物制作的时候,原理图 1 对应的程序需 要添加软件防抖或者增加硬件防抖电路。而对于原理图 2 所对应的程序,则不需 要考虑按键抖动。
图 1 所示原理图驱动程序
汇编语言代码如下:
LAMP BIT P2.0 //根据原理图定义灯泡 AJ BIT P2.7 //根据原理图定义按键
ORG 0H
JMP MAIN
ORG 30H
MAIN:
JB AJ,$ JNB AJ,$
//等待按键松开
CPL LAMP
JMP MAIN
END 注意:程序一定要与原理图对应,上述汇编语言程序的前两行,是根据原理图定
ORG 0H
MAIN
ORG 30H
MAIN:
JB KS,$
CLR LAMP
JB TZ,$
SETB LAMP
JMP MAIN
END C 语言代码如下:
单片机控制继电器实现开关状态显示
单片机控制继电器实现开关状态显示单片机是一种集成电路,其中包含了处理器、存储器、定时器和I/O 端口等多种功能模块。
通过编写程序,可以控制单片机的各种功能,从而实现各种应用需求。
继电器是一种电器元件,可将小电流控制大电流的开关,常用于电力系统中。
在实际应用中,我们经常需要通过单片机来控制继电器的开关状态,并且需要实时显示继电器的状态。
下面将介绍如何利用单片机来实现这一功能。
首先,我们需要选择适合的单片机芯片。
常见的单片机芯片有51系列、AVR系列、STM32系列等。
在此我们以51系列的STC89C52为例进行说明。
这是一种常见的8位单片机,具有较强的功能和性价比。
接下来,我们需要连接继电器和单片机。
将单片机的IO口和继电器的控制端连接,通过控制IO口的高低电平信号来控制继电器的开关。
同时,我们还需要将继电器的状态通过LED等方式进行实时显示。
接下来,我们需要编写单片机的程序来实现控制继电器和显示继电器状态的功能。
我们可以使用C语言或者汇编语言来编写程序。
以下是一个示例的C语言程序:```c#include <reg52.h>sbit relay = P1^0; // 继电器IO口sbit led = P1^1; // LED IO口void delay(unsigned int ms) // 延时函数while (ms--)unsigned char i, j;for (i = 0; i < 10; i++)for (j = 0; j < 110; j++);}}void mainunsigned char switchStatus = 0; // 开关状态变量,0表示关闭,1表示打开while (1)if (switchStatus == 0) // 如果开关状态为关闭,则打开继电器并点亮LEDrelay = 1; // 继电器吸合led = 1; // LED点亮switchStatus = 1; // 更新开关状态为打开}else // 如果开关状态为打开,则关闭继电器并熄灭LEDrelay = 0; // 继电器断开led = 0; // LED熄灭switchStatus = 0; // 更新开关状态为关闭}delay(1000); // 延时1秒}```以上程序的逻辑很简单,当开关状态为关闭时,继电器吸合并点亮LED;当开关状态为打开时,继电器断开并熄灭LED。
串口控制1-30路继电器模块板
PC智能控制盒软件说明
工具栏:
1.系统-------退出
2.设置
(1)设置参数(见图1)串口COM1-COM15可选择
(2)通讯测试(备用)
(3)设备名称(见图2)设置后(见图3)
(4)地址码配置(见图4)设置后(见图5)
3.帮助
(1)说明
(2)关于
(图1)
(图2)
(图3)
第25路:第25路控制00011001
第26路:第26路控制00011010
第27路:第27路控制00011011
第28路:第28路控制00011100
第29路:第29路控制00011101
第30路:第30路控制00011110
第31路:全开/全关00011111
第32路:测试键00100000
工作状态:(图6)
第24路控制关P2.7=0
第25路控制关P3.2=0
第26路控制关P3.3=0
第27路控制关P3.4=0
第28路控制关P3.5=0
第29路控制关P3.6=0
第30路控制关P3.7=0
全开/全关关P1 P0 P2 0
测试键关P1-P3循环每个脚位循环指示
第12路控制关P0.3=0
第13路控制关P0.4=0
第14路控制关P0.5=0
第15路控制关P0.6=0
第16路控制关P0.7=0
第17路控制关P2.0=0
第18路控制关P2.1=0
第19路控制关P2.2=0
第20路控制关P2.3=0
第21路控制关P2.4=0
第22路控制关P2.5=0
第23路控制关P2.6=0
(图4)
(图5)
32路继电器串口控制板
32路继电器串口控制板“32路继电器串口控制板”是本站继“多功能16路继电器控制板”后的一款全新产品。
我们对控制路数与功能进行扩充,改进了使用方便性,提高了硬件接口的兼容性,增加了系统控制盒的扩展功能。
“多功能16路继电器控制板”使用RS232接口或USB接口(我们提供的USB专用电缆,该附件为另购附件)进行通信,同时也可以使用RS485总线进行远距离传输,确保可以在任何PC机或笔记本电脑上方便使用,以及工业级远程控制应用。
产品外观图“32路继电器串口控制板”,可以利用PC电脑实现一些电器设备智能化控制的功能,成本低,使用方便,具有一定的实用性,使广大用户都能够用得起它。
我们可以用它来控制各种电器的开关状态,当您把相连的连线都接好后,只需要在电脑前动动鼠标,就可以控制各路电器的开关状态了,同时软件可以实时监控各路电器的当前工作状态。
您可以在自己家的电脑前来控制,也可以安装我们提供的远程控制软件通过Internet来进行远程的家电控制,不管在哪里,只要你所在的地方有Internet网络,你就可以轻松控制家中的电器设备。
硬件资源说明:赠送VB上位机软件源码,我们提供了RS232通信和RS485通信的VB完整工程例子。
32路串口继电器版本,继电器电流更大,芯片改为贴片设计,改进了MCU端电源,并且增强了端口保护,性能提升,品质更好。
32路继电器串口控制板,是针对一些无需输入检测,只需要输出的客户而设计的新产品。
STC单片机速度快稳定可靠,特别在一些工业场合可靠性要求较高的场合,应用广泛。
是当前应用最广的单片机MCU之一。
串口继电器板应用非常广泛:可用于网吧计算机管理、各种场合灯光控制(比如台球室灯光控制、舞台灯光控制、家庭灯光控制等)、电机控制、生产控制等等。
通过485网络支持可达到1.2Km的长距离远程控制。
参数介绍:尺寸27.2cm×11.7cm主要特点:1、16路高度可靠隔离的250V 10A的继电器输出,每个继电器为一个开关,分别为公共点、常开点。
RS485或RS232串口modbus继电器电脑控制开关量输入输出工业IO模块
Dim ReturnData(1) As Byte
CRC16Lo = &HFF
CRC16Hi = &HFF
CL = &H1
CH = &HA0
Length = IIf(Length < 1, UBound(Data) - Offset, Length - 1) 'Update 2007-03-15
For I = Offset To Offset + Length CRC16Lo = CRC16Lo Xor Data(I) '每一个数据与 CRC 寄存器进行异或
联系电话:15998902545 QQ:910887181
附: CRC16 直接计算法 Basic 函数
Public Function CRC16(Data() As Byte, Optional ByVal Offset As Integer = 0, Optional ByVal Length As Integer
0D 0E 0F
H
H
H
H
H
H
H
H
H
H
2.控制继电器输出. 2.1 一次控制单个继电器动作(假定模块为 0x01)
开第一路 0x01,0x05,0x00,0x10,0xFF,0x00,0x8D,0xFF 开第二路 0x01,0x05,0x00,0x11,0xFF,0x00,0xDC,0x3F 开第三路 0x01,0x05,0x00,0x12,0xFF,0x00,0x2C,0x3F 开第四路 0x01,0x05,0x00,0x13,0xFF,0x00,0x7D,0xFF, 关第一路 0x01,0x05,0x00,0x10,0x00,0x00,0xCC,0x0F 关第二路 0x01,0x05,0x00,0x11,0x00,0x00,0x9D,0xCF 关第三路 0x01,0x05,0x00,0x12,0x00,0x00,0x6D,0xCF 关第四路 0x01,0x05,0x00,0x13,0x00,0x00,0x3C,0x0F
实例讲解 单片机控制继电器原理
实例讲解单片机控制继电器原理
单片机是一个弱电器件,一般情况下它们大都工作在5V甚至更低.驱动电流在mA级以下.而要把它用于一些大功率场合,比如控制电动机,显然是不行的.所以,就要有一个环节来衔接,这个环节就是所谓的功率驱动.继电器驱动就是一个典型的、简单的功率驱动环节。
首先看看继电器的驱动
这是典型的继电器驱动电路图,这样的图在网络上随处可以搜到,并且标准教科书上一般也是这样的电路图
为什么要明白这个图的原理?
单片机是一个弱电器件,一般情况下它们大都工作在5V甚至更低.驱动电流在mA级以下.而要把它用于一些大功率场合,比如控制电动机,显然是不行的. 所以,就要有一个环节来衔接,这个环节就是所谓的功率驱动.继电器驱动就是一个典型的、简单的功率驱动环节.在这里,继电器驱动含有两个意思:一是对继电器进行驱动,因为继电器本身对于单片机来说就是一个功率器件;还有就是继电器去驱动其他负载,比如继电器可以驱动中间继电器,可以直接驱动接触器,所以, 继电器驱动就是单片机与其他大功率负载接口.这个很重要,因为,一直让我们的电气工程师(我指的是那些没有学习过相应的电子技术的)感到迷惑不解的是:一个小小的芯片,怎么会有如此强大的威力来控制像电动机这样强大的东西?
怎么样理解这个电路图?
要理解这个电路,其实也比较容易.那么请您按照我的思路来,应该没有问题:
首先的,里面的三极管很重要.三极管是电子电路里很重要的一个元件.怎。
发一个用串口命令单片机控制开关输出的小程序
******
- 功能描述:51 单片机的串口发送 0d 0a ,即回车换行
- 隶属模块:STC51 串口操作
- 函数属性:外部,使用户使用
- 参数说明:无
- 返回说明:无
- 注:此函数就是发送 0d 0a 这两个字节,在“超级终端”上会有回车换行的效果
********************************************************************
********************************************************************
******/
void Com_init()
{
/******************设定定时器*********************/
TMOD = 0x20;
//设定定时器的工作方式(方式 2)
//允许串口接收外部传来的数据
/******************设定中断**********************/
ES = 1;
//允许串口收到数据后产生中断通知我们
EA = 1;
//因为总中断开关是控制所有中断的,所以要把它打开
TR1 = 1;
//启动定时器,串口就开始工作喽!
}
/********************************************************************
* 功能 : 串口发送一个字符串
* 输入 : s:指向字符串数组的指针
* 输出 : 无
********************************************************************
单片机控制继电器驱动原理实例详解
单片机控制继电器驱动原理实例详解继电器驱动电路由3部分组成:单片机控制电路、继电器控制电路和继电器负载电路。
首先介绍单片机控制电路。
单片机通常有多个GPIO口,其中一个GPIO口可以配置为输出模式,通过该GPIO口的控制信号控制继电器的开关。
在单片机控制电路中,需要使用电平转换电路将单片机的控制信号转换为继电器驱动电路可接受的电平。
通常使用晶体管来实现电平转换,例如通过NPN型晶体管的基极接单片机的GPIO口,发射极接电源正极,而集电极接继电器控制电路。
接下来介绍继电器控制电路。
继电器控制电路是通过驱动电路来控制继电器的线圈电流,从而实现开关的操作。
一般使用光耦隔离器将单片机控制电路和继电器控制电路隔离,以提高系统的稳定性和可靠性。
光耦隔离器的输入端连接单片机的控制信号,输出端连接到继电器控制电路。
当单片机的控制信号发生变化时,光耦隔离器的阻止电流就会发生变化,从而改变继电器的线圈电流,实现继电器的开关操作。
此外,还需要使用电阻、二极管等元件来保护光耦隔离器和继电器控制电路。
最后介绍继电器负载电路。
继电器负载电路是通过继电器的常开(NO)和常闭(NC)触点来控制外部负载的通断。
当继电器吸合时,常开触点闭合,通断负载电路;当继电器断开时,常闭触点闭合,通断负载电路。
通常将外部负载电源的正极接继电器的公共端口(COM),负极接继电器的常开或常闭触点之一综上所述,单片机控制继电器驱动的原理可以概括为:通过单片机的控制信号,经过电平转换和光耦隔离器的电路转换,控制继电器的线圈电流,从而实现继电器的开关操作,最终控制外部负载的通断。
例如,我们可以通过单片机控制继电器驱动电路来实现远程控制家庭电器。
将继电器的负载电路与家庭电器相连,通过单片机控制继电器的开关状态来控制家庭电器的通断。
我们可以使用无线通信模块,将单片机控制信号通过无线信号发送给控制终端,从而实现远程控制家庭电器的功能。
总结起来,单片机控制继电器驱动的原理是通过电平转换和光耦隔离器的电路转换,实现对继电器的控制,从而实现对外部负载的通断控制。
C51单片机和电脑串口通信电路图
C51单片机和电脑串口通信电路图与源码51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通讯。
进行串行通讯时要满足一定的条件,比如电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。
我们采用了三线制连接串口,也就是说和电脑的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。
这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接.串口通讯的硬件电路如上图所示在制作电路前我们先来看看要用的MAX232,这里我们不去具体讨论它,只要知道它是TTL和RS232电平相互转换的芯片和基本的引脚接线功能就行了。
通常我会用两个小功率晶体管加少量的电路去替换MAX232,可以省一点,效果也不错,下图就是MAX232的基本接线图。
按图7-3加上MAX232就可以了。
这大热天的拿烙铁焊焊,还真的是热气迫人来呀:P串口座用DB9的母头,这样就可以用买来的PC串口延长线进行和电脑相连接,也可以直接接到电脑com口上。
为了能够在电脑端看到单片机发出的数据,我们必须借助一个WINDOWS软件进行观察,这里我们利用一个免费的电脑串口调试软件。
本串口软件在本网站可以找到软件界面如上图,我们先要设置一下串口通讯的参数,将波特率调整为4800,勾选十六进制显示。
串口选择为COM1,当然将网站提供的51单片机实验板的串口也要和电脑的COM1连接,将烧写有以下程序的单片机插入单片机实验板的万能插座中,并接通51单片机实验板的电源。
#include <reg51。
h〉#define BUFFERLEGTH 10//-—---———-—-——————--——-----—--——--——------—-—--—-—--—--——-———-—--—void UART_init();//串口初始化函数void COM_send(void);//串口发送函数char str[20];char j;//——-----————---——-—--—--—-—-—-———-———-—-——-—--—-—-——————--———-—--———void main(void){unsigned char i;UART_init();j=0; //初始化串口for(i = 0;i < 10 ;i++){COM_send(); //首先发送一次数据作为测试用};while(1);}//-——-——-——---------———-——-—-—-——--—---—---—--—-—--——---—---—--//——-——--——--—-—-—--———————---—-——-——-———-—-----——--—---——————-—-—-—-—————-—--—-—---—--———-——---——-- // 函数名称:UART_init()串口初始化函数// 函数功能: 在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s// 串口接收中断允许,发送中断禁止//—-——--—-----———---—-——-—-——————-————-—-————---——-———————--———-———----—-—--—---——-—---—-————-———---void UART_init(){//初始化串行口和波特率发生器SCON =0x50; //选择串口工作方式1,打开接收允许TMOD =0x20; //定时器1工作在方式2,定时器0工作在方式1TH1 =0xfA; //实现波特率9600(系统时钟11。
电脑串口控制单片机驱动继电器的例子
电路图说明:这个电路非常典型,串行口(也称RS232)接口集成电路MAX232与单片机AT89S51引脚P3.0(RXD)\P3.1(TXD)连接,构成与主机的通讯接口电路。
AT89S51引脚P0、P2口连接达林顿管阵列驱动IC uln2803,通过它控制继电器动作。
相关基础知识简要说明:1、串行口(也称RS232接口)是用途最广的一种通讯接口,一般电脑主机上都有这个接口,缺点是传输距离短,市场上也有很多USB-RS232 转换接口卖。
**常用的通讯接口还有RS485、RS422、LPT打印接口、CAN总线接口、网卡接口等等,与RS232比较接近的通讯接口是RS485,它的通讯距离较远,广泛用于工业控制。
2、串行口(也称RS232)接口集成电路MAX232,接口芯片种类繁多,MAX232只是其中的一种,可以说是串行接口集成电路的代表型号,图纸上一般都标MAX232,但实际使用时,可以选用更多兼容的芯片,其中一个理由,兼容芯片更便宜。
3、达林顿管阵列驱动IC uln2803,TTL输入(0-5v),可以同时驱动8个继电器,内部不仅封装了达林顿管阵列,并且含有钳位二极管,连接继电器时,不需要再连接保护二极管,使用非常方便,因而用途广泛。
相同功能的芯片有ULN2003,只是它只有7个输出口。
内部电路如图所示:发送图片到手机,此主题相关图片如下:接口IC ULN2083内部有反相缓冲器(参见技术手册),简单来说,输入高电平,输出为低电平;输入低电平,则输出高电平。
如图所示:发送图片到手机,此主题相关图片如下:ULN2803数据手册下载:注:一般单片机输入、输出电流有限,无法驱动继电器等大电流外围部件,因此需要有驱动电路,常用的是三极管驱动(如2SD8050)和IC 驱动(如ULN2803)。
上拉电阻的问题:1、51单片机的P0口内部没有上拉电阻,其他P1、P2、P3口内部也只是弱上拉,为了在高电平输出时得到较高的输出电流,提高驱动能力,有必要在P0口与+5v间连接上拉电阻(通常取值在1k-4.7k 左右)。
单片机串口控制继电器的C源程序
51单片机串口控制继电器的C源程序2009-09-29 23:13计算机通过软件来控制单片机继电器。
操作:计算机使用串口调试助手,当然,可以自己编写控制软件(上位机软件)。
单片机P1.1口连上继电器C源程序为:#include <reg52.h>sbit RELAY = P1^1; //定义继电器:接P1^1void delay(unsigned int cnt){while(--cnt);}main(){TMOD=0x20; //TH1=0xfd;TL1=0xfd;SM0=0;SM1=1;REN=1; //控制RITR1=1;/*以上为定时器设置和波特率设置,这样的话,通过串口调试助手发送数据(随意数据)通过改变RI(串口接收标志来实现继电器的吸合与打开 */while(1){if(RI==1){RI=0;delay(500);RELAY=!RELAY; //如果吸合则打开,如果己打开则吸合。
}}}以上在AT89s52+Keil上编译调试运行OK。
/****************************************************************************//* 电子日历,有时间显示、闹铃、日期、秒表及键盘设置功能*//* 功能键A: 设置位数字+1 闹钟模式下为闹钟开关秒表模式下为记时开关*/ /* 功能键B: 设置位数字-1 闹钟模式下为闹钟开关*//* 功能键C:设置模式及设置位选择秒表模式下为清零键*//* 功能键D:在四种工作模式下切换设置闹钟开关*//****************************************************************************/#include#include/***************这里设置程序初始化时显示的时间****************/#define SET_HOUR 12 /*设置初始化小时*/#define SET_MINUTE 00 /*设置初始化分钟*/#define SET_SECOND 00 /*设置初始化秒数*//*************************系统地址****************************/#define BASE_PORT 0x8000 /*选通基地址*/#define KEY_LINE BASE_PORT+1 /*键盘行线地址*/#define KEY_COLUMN BASE_PORT+2 /*键盘列线地址*/#define LED_SEG BASE_PORT+4 /*数码管段选地址*/#define LED_BIT BASE_PORT+2 /*数码管位选地址*/#define LED_ON(x) XBYTE[LED_BIT]=(0x01<<x) style="line-height: 25px; "> #define LED_OFF XBYTE[LED_SEG]=0x00 /*LED显示空*/</x) >/**************在设置模式下对秒分时的宏定义*****************/#define SECOND 0 /*对应数码管右边两位*/#define MINUTE 1 /*对应数码管中间两位*/#define HOUR 2 /*对应数码管左边两位*//********************定义四种工作模式***********************/#define CLOCK clockstr /*时钟模式*/#define ALART alartstr /*闹钟模式*/#define DATE datestr /*日期模式*/#define TIMER timerstr /*秒表模式*//****************以下是所有子函数的声明*********************/void sys_init(void); /*系统的初始化程序*/void display(void); /*动态刷新一次数码管子程序*/void clockplus(void); /*时间加1S的子程序*/void update_clockstr(void); /*更新时间显示编码*/void update_alartstr(void); /*更新闹钟时间的显示编码*/void update_datestr(void); /*更新日期显示编码*/void update_timerstr(void); /*更新秒表时间的显示编码*/void deley(int); /*延时子程序*/void update_dispbuf(unsigned char *); /*更新显示缓冲区*/unsigned char getkeycode(void); /*获取键值子程序*/void keyprocess(unsigned char); /*键值处理子程序*/unsigned char getmonthdays(unsigned int,unsigned char);/*计算某月的天数子程序*/ /*功能键功能子函数*/void Akey(void); /*当前设置位+1 开关闹钟开关秒表*/void Bkey(void); /*当前设置位-1 开关闹钟*/void Ckey(void); /*设置位选择秒表清零*/void Dkey(void); /*切换四种工作模式*//**********************全局变量声明部分*********************/unsigned char led[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};/*从0~9的LED编码*/unsigned char ledchar[3]={0x5c,0x54,0x71};/*o n f*///unsigned char key[24]={ /* 键值代码数组对应键位:*/// 0x70,0x71,0x72,0x73,0x74,0x75, /* 7 8 9 A TRACE RESET*/// 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5, /* 4 5 6 B STEP MON */// 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5, /* 1 2 3 C HERE LAST */// 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5}; /* 0 F E D EXEC NEXT */struct{ /*时间结构体变量*/unsigned char s;unsigned char m;unsigned char h;}clock={SET_SECOND,SET_MINUTE,SET_HOUR};struct{ /*闹铃时间结构体变量*/unsigned char m;unsigned char h;}alart={SET_MINUTE,SET_HOUR};struct{ /*日期结构体变量*/unsigned int year;unsigned char month;unsigned char day;}date={6,1,1};struct{ /*秒表时间结构体变量*/unsigned char ms;unsigned char s;unsigned char m;}timer={0,0,0};unsigned char dispbuf[6]; /*显示缓冲区数组*/unsigned char clockstr[6]; /*时间显示的数码管编码数组*/unsigned char alartstr[6]; /*闹钟显示的数码管编码数组*/unsigned char datestr[6]; /*日期显示的数码管编码数组*/unsigned char timerstr[6]; /*秒表显示的数码管编码数组*/ unsigned int itime=0,idot; /*定时器0中断计数*/unsigned char itime1=0; /*定时器1中断计数*/sbit P3_1=P3^1; /*外接蜂鸣器的管脚*/bdata bit IsSet=0; /*设置模式标志位0:正常走时1:设置模式*/bdata bit Alart_EN=0; /*闹铃功能允许位0:禁止闹铃1:允许闹铃*/bdata bit IsBeep=0; /*响铃标志位0:未响铃1:正在响铃*/unsigned char SetSelect=0; /*在设置模式IsSet=1时,正在被设置的位,对应上面的宏*/unsigned char *CurrentMode; /*标志当前正设置的功能,如CurrentMode=CLOCK或CurrentMode=ALART等*/void timerplus(void);/**************************函数部分*************************/void main(void){sys_init();while(1){XBYTE[KEY_COLUMN,0x00]; /*给键盘列线赋全零扫描码,判断是否有键按下*/while((XBYTE[KEY_LINE]&0x0f)==0x0f) /*检测是否有键按下,无则一直进行LED 的刷新显示*/{if(Alart_EN&&(clock.h==alart.h)&&(clock.m==alart.m)) {IsBeep=1;}else{ IsBeep=0;P3_1=0;}display();}keyprocess(getkeycode()); /*有键按下时得到键值,并送入键值处理程序*/display(); /*可要可不要*/}}void sys_init(void){TMOD=0x22; /*定时器0和1都设置为工作方式2,基准定时250×2=500us=0.5ms*/ TH0=6; /*定时器0中断服务用来产生1秒时钟定时及闹钟蜂鸣器蜂鸣脉冲*/TL0=6; /*定时器1中断服务留给秒表使用,产生1/100秒定时*/ TH1=6;TL1=6;ET0=1;ET1=1;EA=1;TR0=1;update_clockstr(); /*初始化时钟显示编码数组*/update_alartstr(); /*初始化闹钟显示编码数组*/update_datestr(); /*初始化日期显示编码数组*/update_timerstr(); /*初始化秒表显示编码数组*/update_dispbuf(clockstr);/*初始化显示缓冲数组*/CurrentMode=CLOCK; /*默认的显示摸式为时钟*/P3_1=0; /*蜂鸣器接线引脚复位*/}void timer0(void) interrupt 1 using 1 /*定时器0中断服务器,用来产生1秒定时*/ {itime++;if(itime==1000){if(IsSet) /*在设置模式下,对正在设置的位闪烁显示*/{dispbuf[SetSelect*2]=0; /*对正在设置的位所对应的显示缓冲区元素赋0,使LED灭*/dispbuf[SetSelect*2+1]=0;}if(IsBeep) P3_1=!P3_1; /*闹钟模式时,产生峰鸣器响脉冲*/if(CurrentMode==CLOCK){dispbuf[2]=dispbuf[2]&0x7f;dispbuf[4]=dispbuf[4]&0x7f;}}if(itime==2000) /*两千次计数为1S 2000×0.5ms=1s*/{itime=0; /*定时1s时间到,软计数清零*/clockplus(); /*时间结构体变量秒数加1 */update_clockstr(); /* 更新时间显示编码数组*/if(CurrentMode!=TIMER) update_dispbuf(CurrentMode); /* 用时间编码数组更新显示缓冲区*/}}void timer1(void) interrupt 3 using 2 /*定时器1中断服务器,用来产生1/100秒定时*/{idot++;if(++itime1==20) /*20*0.5ms=10ms*/{itime1=0;timerplus();update_timerstr();if(CurrentMode==TIMER){update_dispbuf(timerstr);dispbuf[2]=dispbuf[2]&0x7f; /*关闭小数点的显示*/dispbuf[4]=dispbuf[4]&0x7f;if(idot<1000) /*闪烁显示小数点*/{dispbuf[2]=dispbuf[2]|0x80;dispbuf[4]=dispbuf[4]|0x80;}else{dispbuf[2]=dispbuf[2]&0x7f;dispbuf[4]=dispbuf[4]&0x7f;}}}if(idot==2000) idot=0;}/*功能模块子函数*/void clockplus(void) /*时间加1s判断分,时子函数*/{if(++clock.s==60) /*秒位判断*/{clock.s=0;if(++clock.m==60) /*分位判断*/{clock.m=0;if(++clock.h==24) /*时位判断*/{clock.h=0;if(++date.day==(getmonthdays(date.year,date.month)+1)){date.day=1;if(++date.month==13) date.month=1;}}}}}void timerplus() /*秒表1/100秒位加1,判断秒、分子程序*/ {if(++timer.ms==100){timer.ms=0;if(++timer.s==60){timer.s=0;if(++timer.m==60){timer.m=0;}}}}void update_clockstr(void) /*更新时钟显示代码数组clockstr*/{clockstr[0]=led[clock.s%10]; /*给元素0赋相应数码管显示编码,编码序号是秒数的个位*/clockstr[1]=led[(int)(clock.s/10)]; /*给元素1赋相应数码管显示编码,编码序号是秒数的十位*/clockstr[2]=led[clock.m%10]; /*以下类推*/clockstr[3]=led[(int)(clock.m/10)];clockstr[4]=led[clock.h%10];clockstr[5]=led[(int)(clock.h/10)];}void update_alartstr(void) /*更新闹钟显示代码数组alartstr*/{ /*右边两位显示on:闹钟开启of:闹钟关闭*/if(Alart_EN) alartstr[0]=ledchar[1];/*显示字母n*/else alartstr[0]=ledchar[2]; /*显示字母f*/alartstr[1]=ledchar[0]; /*显示字母o*/alartstr[2]=led[alart.m%10];alartstr[3]=led[(int)(alart.m/10)];alartstr[4]=led[alart.h%10];alartstr[5]=led[(int)(alart.h/10)];}void update_datestr(void) /*更新日期显示代码数组datestr*/datestr[0]=led[date.day%10];datestr[1]=led[(int)(date.day/10)];datestr[2]=led[date.month%10];datestr[3]=led[(int)(date.month/10)];datestr[4]=led[date.year%10];datestr[5]=led[(int)(date.year/10)];}void update_timerstr(void) /*更新秒表显示代码数组timerstr*/ {timerstr[0]=led[timer.ms%10];timerstr[1]=led[(int)(timer.ms/10)];timerstr[2]=led[timer.s%10];timerstr[3]=led[(int)(timer.s/10)];timerstr[4]=led[timer.m%10];timerstr[5]=led[(int)(timer.m/10)];}void display(void) /*刷新显示六位LED一次*/{unsigned char i;for(i=0;i<6;i++){LED_ON(i); /*选通相应位*/XBYTE[LED_SEG]=dispbuf[i]; /*写显示段码*/deley(50); /*延时显示*/LED_OFF; /*写LED全灭段码*/}void update_dispbuf(unsigned char *str) /*更新显示缓冲区子函数,参数为要用来更新缓冲区的源字符数组的首地址*/{dispbuf[0]=str[0]; /*将要更新的源字符数组内容COPY至dispbuf数组,用作显示缓冲区*/dispbuf[1]=str[1];dispbuf[2]=str[2]|0x80; /*默认把时位和分位后面的小数点显示出来,根据需要再取舍*/dispbuf[3]=str[3];dispbuf[4]=str[4]|0x80;dispbuf[5]=str[5];}void deley(int i) /*延时子函数*/{while(i--);}unsigned char getkeycode(void) /*键盘扫描子程序,返回获得的键码*/{unsigned char keycode; /*键码变量,一开始存行码*/unsigned char scancode=0x20; /*列扫描码*/unsigned char icolumn=0; /*键的列号*/display(); /*用刷新数码管显示的时间去抖*/XBYTE[KEY_COLUMN]=0x00;keycode=XBYTE[KEY_LINE]&0x0f; /*从行端口读入四位行码*/while((scancode&0x3f)!=0) /*取scancode的低六位,只要没变为全0,则执行循环*/XBYTE[KEY_COLUMN]=(~scancode)&0x3f; /*给列赋扫描码,第一次为011111*/ if((XBYTE[KEY_LINE]&0x0f)==keycode) break; /*检测按键所在的列跳出循环*/ scancode=scancode>>1; /*列扫描码右移一位*/icolumn++; /*列号加1*/}keycode=keycode<<4; /*把行码移到高四位*/keycode=keycode|icolumn; /*由行码和列码组成键码*///等待按键放开XBYTE[KEY_COLUMN]=0x00;while((XBYTE[KEY_LINE]&0x0f)!=0x0f) display();return keycode;}void keyprocess(unsigned char keycode) /*键值处理函数*/{switch (keycode){case 0x73: Akey();break;case 0xB3: Bkey();break;case 0xD3: Ckey();break;case 0xE3: Dkey();break;default: break;update_dispbuf(CurrentMode);}unsigned char getmonthdays(unsigned int year,unsigned char month)/*得到某月的天数*/{unsigned char days;switch (month){case 4:case 6:case 9:case 11:days=30;break;case 2: if(year%4==0) days=29;else days=28;break;default:days=31;break;}return days;}/*功能键子函数部分*/void Akey(void) /*对当前设置位进行加一操作,如果设置秒位,则给秒位清零*/{if(CurrentMode==TIMER) /*秒表模式下启闭走时*/{ TR1=!TR1;return;}if(!IsSet) return; /*如果不是设置模式退出*/switch (SetSelect){case SECOND:if(CurrentMode==CLOCK){clock.s=0; /*如果当前被设置位是秒位,则清零秒位*/ update_clockstr();}if(CurrentMode==ALART){Alart_EN=!Alart_EN;update_alartstr();}if(CurrentMode==DATE){if(++date.day==(getmonthdays(date.year,date.month)+1)) date.day=1;update_datestr();}if(CurrentMode==TIMER){TR1=!TR1;}break;case MINUTE:if(CurrentMode==CLOCK){if(++clock.m==60) clock.m=0; /*如果当前被设置分位,则分位加1*/ update_clockstr();}if(CurrentMode==ALART){if(++alart.m==60) alart.m=0;update_alartstr();}if(CurrentMode==DATE){if(++date.month==13) date.month=1;update_datestr();}break;case HOUR: if(CurrentMode==CLOCK){if(++clock.h==24) clock.h=0; /*如果当前被设置时位,则时位加1*/ update_clockstr();}if(CurrentMode==ALART){if(++alart.h==24) alart.h=0;update_alartstr();if(CurrentMode==DATE){if(++date.year==100) date.year=0;update_datestr();}break;default: break;}update_dispbuf(CurrentMode);}void Bkey(void) /*对当前设置位进行减一操作,如果设置秒分,则给秒位清零,类比Akey()函数*/{if(!IsSet) return;switch (SetSelect){case SECOND:if(CurrentMode==CLOCK){clock.s=0;update_clockstr();}if(CurrentMode==ALART){Alart_EN=!Alart_EN;update_alartstr();if(CurrentMode==DATE){if(--date.day==0x00)date.day=getmonthdays(date.year,date.month);update_datestr();}break;case MINUTE:if(CurrentMode==CLOCK){if(--clock.m==0xff) clock.m=59;update_clockstr();}if(CurrentMode==ALART){if(--alart.m==0xff) alart.m=59;update_alartstr();}if(CurrentMode==DATE){if(--date.month==0x00) date.month=12;update_datestr();}break;case HOUR: if(CurrentMode==CLOCK){if(--clock.h==0xff) clock.h=23;update_clockstr();}if(CurrentMode==ALART){if(--alart.h==0xff) alart.h=23;update_alartstr();}if(CurrentMode==DATE){if(--date.year==0xffff) date.year=99;update_datestr();}break;default: break;}update_dispbuf(CurrentMode);}void Ckey(void) /*正常走时模式和设置模式的切换*/{if(CurrentMode==TIMER){TR1=0; /*初始化定时器1设置,停止秒表记时*/ TH1=6;TL1=6;timer.ms=0; /*初始化秒表数组*/timer.m=0;update_timerstr();}else{if(IsSet==0) /*在非秒表模式下,第一次按下C键进入设置模式,设置时位*/{IsSet=1; /*置位标志位,进入设置模式*/SetSelect=HOUR;return;} /*第二次按C键设置分位,第三次按键设置秒位,第四次按键完成退出设置*/if(SetSelect==0) /*按到第四次,即设置完秒位后,将标志位IsSet置0,完成设置*/{IsSet=0; /*复位标志位,进入正常走时模式*/return;}if(SetSelect>0) SetSelect--; /*设置位的标志变量SetSelect=0:时位1:分位2:秒位*/}}void Dkey(void) /*工作状态切换:时钟、闹钟、日期、秒表*/{if(CurrentMode==CLOCK) /*切换至闹钟,同时开关闹钟*/{ CurrentMode=ALART;Alart_EN=!Alart_EN;update_alartstr();}if(CurrentMode==ALART) /*切换至日期*/{ CurrentMode=DATE;return;}if(CurrentMode==DATE) /*切换至秒表,同时关闭设置模式*/ {CurrentMode=TIMER;IsSet=0;return;}if(CurrentMode==TIMER) /*切换至时钟*/{CurrentMode=CLOCK;return;}}。
NRF无线串口模块IO与继电器的连接方法
1、控制指令查看使用手册的IO 控制指令表格。
例如上面端口1的控制指令为:
A1FD 010001
(代表端口1输出低电平,继电器关闭)A1FD 010101(代表端口1输出高电平,继电器打开)
如结合本店的语音模块使用,只需要将语音模块TF 卡中的“飞音云电子......ini ”配置文件中的5个指令替换为所要控制的无线指令即可,识别到相关语句后即会输出相关指令
从而达到控制效果。
如有多个继电器,采用
类似方法往下接。
一共
26个口。
1、控制指令查看使用手册的IO 控制指令表格。
例如上面端口1的控制指令为:
A1FD 010001
(代表端口1输出低电平,继电器关闭)A1FD 010101(代表端口1输出高电平,继电器打开)
如结合本店的语音模块使用,只需要将语音模块TF 卡中的“飞音云电子......ini ”配置文件中的5个指令替换为所要控制的无线指令即可,识别到相关语句后即会输出相关指令
从而达到控制效果。
如有多个继电
器,采用类似
方法往下接。
一共26个口。
三、串口无线与5路继电器的连接示意图
1、控制指令查看使用手册的IO 控制指令表格。
例如上面端口1的控制指令为:
A1A510105B
(代表继电器1导通)A1A511115B (代表继电器1断开)
如结合本店的语音模块使用,只需要将语音模块TF 卡中的“飞音云电子......ini ”配置文件中的5个指令替换为所要控制的无线指令即可,识别到相关语句后即会输出相关指令
从而达到控制效果。
单片机直接驱动继电器
长见识了,原来单片机可以直接驱动继电器——
最近见识一产品,看到电路板上一堆继电器居然是由一个芯片(已打磨)直接控制的,后经验证该芯片为AT89C2051,顿时晕倒。
唉,以前驱动继电器还隔离、两路电源、光耦三极管电阻电容一大堆,敢情都是浪费啊!看看人家的产品........我不知道是该笑自己太胆小,还是佩服人家胆子太大!
现将电路贴出(注:所控制的电器不会有两个以上同时工作,只会有一个工作,也就是说继电器永远不会有两个以上同时吸合),请兄弟们点评。
我的电脑串口控制继电器,终于成功了!
我的电脑串口控制继电器,终于成功了!电脑串口控制继电器,顾名思义:就是利用电脑的串口对继电器进行吸和,断开的控制。
进而利用继电器的常开或者常闭触点去控制各种用电器,设备的开与关。
它分为上位机和下位机。
上位机就是,电脑用来控制和利用串口与下位机通信的专用软件。
这种软件通常用VB 编写。
下位机就是,利用单片机以及它外围的一些电路(电源电路,串口通信电路,继电器驱动电路,等等)共同构成了下位机。
也就是说,上位机是软件,下位机是硬件。
我做的这个电脑串口控制继电器,主控芯片是AVR 的单片机,型号为ATtiny2313。
此外还有,74LS373,ULN2003,MAX232。
这个东西我用了一个多星期的时间才把它给完全搞好。
期间经历了很多次失败,但每一次失败我都去总结经验,教训。
经过了大量的试验,看了很多资料,最后,我终于成功了!其中的滋味,只有自己才知道。
下位机控制板做的很小,集成了9 个芯片,还有其它的一些电子元器件。
整个板子做的很紧凑,但很整齐。
一共24 路继电器控制。
共需要4 块板子,每一路为6 个继电器。
我只做了一路,因为没有那么多的继电器和相关的电子元件。
不成功的主要原因有以下三点:第一,熔丝位没有设置好。
正确的熔丝位是E4,CB,FF。
这一点,是花了我最长的时间和最多金钱的地方。
AVR 的熔丝位设置问题,简直对于一个初学者来说,就是一场恶梦!搞不好,芯片会永远的锁死,没有专门的设备是无法进行修复的,有的连修复也不能修复了。
熔丝低位的设置如果是设置错误了,还可以解救,解救办法网上有很多,在这就不多说了。
但是,如果是熔丝高位设置错了,那就可能没有办法了,最起码,对于向我们这样的电子爱好者,是没有任何办法的,只能认倒霉了。
但是,熔。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电路图说明:
这个电路非常典型,串行口(也称RS232)接口集成电路MAX232与单片机AT89S51引脚P3.0(RXD)\P 3.1(TXD)连接,构成与主机的通讯接口电路。
AT89S51引脚P0、P2口连接达林顿管阵列驱动IC uln2
803,通过它控制继电器动作。
相关基础知识简要说明:
1、串行口(也称RS232接口)是用途最广的一种通讯接口,一般电脑主机上都有这个接口,
缺点是传输距离短,市场上也有很多USB-RS232 转换接口卖。
**常用的通讯接口还有RS485、RS422、LPT打印接口、CAN总线接口、网卡接口等等,与RS232比较接近的通讯接口是RS485,它的通讯距离较远,广泛用于工业控制。
2、串行口(也称RS232)接口集成电路MAX232,接口芯片种类繁多,MAX232只是其中的一种,可以说是串行接口集成电路的代表型号,图纸上一般都标MAX232,但实际使用时,可以选用更多兼容
的芯片,其中一个理由,兼容芯片更便宜。
3、达林顿管阵列驱动IC uln2803,TTL输入(0-5v),可以同时驱动8个继电器,内部不仅封装了达林顿管阵列,并且含有钳位二极管,连接继电器时,不需要再连接保护二极管,使用非常方便,因而用途广泛。
相同功能的芯片有ULN2003,只是它只有7个输出口。
内部电路如图所示:
发送图片到手机,此主题相关图片如下:
接口IC ULN2083内部有反相缓冲器(参见技术手册),简单来说,输入高电平,输出为低电平;输入低电平,则输出高电平。
如图所示:
发送图片到手机,此主题相关图片如下:
ULN2803数据手册下载:
注:一般单片机输入、输出电流有限,无法驱动继电器等大电流外围部件,因此需要有驱动电路,常用的是三极管驱动(如2SD8050)和IC 驱动(如ULN2803)。
上拉电阻的问题:
1、51单片机的P0口内部没有上拉电阻,其他P1、P
2、P3口内部也只是弱上拉,为了在高电平输出时得到较高的输出电流,提高驱动能力,有必要在P0口与+5v间连接上拉电阻(通常取值在1k-4.7k左右)。
见AT89C51数据手册第4页。
此主题相关图片如下:
AT89C51数据手册下载:
点击浏览该文件
51源程序详解:
源程序主要分三个部分:初始化程序、串口中断程序、协议解析或叫解码程
序。
初始化程序:
初始化是单片机通电后首先执行的一部分程序,主要是对单片机中的寄存器做一些必要的设置(即写
入值):
1、设置串口波特率为9600 串行口设置MODE1,SM1=0,REN=1,SMOD=1
2、由于电路上晶振采用11.0592M(最常用),定时器1设置初值为0FDH
;常用串口波特率对应初值(11.0592M晶振)
;FD 9600
;FA 4800
;F4 2400
;E8 1200
3、启动定时器1、允许串口中断、允许总中断
相关代码:
MOV SCON,#50H
MOV TMOD,#00100001B ;TIM1在模式2 TIM0在模式1
MOV TH1,#0F4H ;设置定时时间
SETB TR1 ;启动定时器1
SETB ES ;允许串口中断
SETB EA ;允许总中断
需要注意:
1、波特率越高,通讯速度越快,但也更容易出错,一般来说,通讯距离短时,可以用较高的波特率,通讯
距离长时,选用较低的波特率可使通讯更为可靠。
2、硬件电路采用不同的晶振,波特率设置时初值是不同的,初值可由公式()取得,通过计算你会发现有些晶振(如10M、12M)计算结果有余数,实质上就是波特率有误差,最终结果就是用了这个晶振的电路,在通讯时会出现无法通讯、时好时坏、误动作等等情况(很多朋友都是这个问题)。
因此,一般我们在用到串口的单片机电路中,如无特殊需要,晶振都选用最常用的,如11.0592
M。
3、提高波特率的方法有二种:将SM1设为1;或是换一个频率更高的晶振。
由于接口IC ULN2083输入输出的反相特性,即输入为高电平,输出为低电平;输入为低电平,则输出为高电平。
同时51单片机上电复位后,其引脚为高电平,这样会引起连接在P0、P2口的继电器全部得电吸合的情况,应此,初始化程序中应对端口作如下设置:
相关代码:
MOV P0,#0 ;P0、P2输出低电平
MOV P2,#0
由于本例中单片机在初始化后没有其它事情做,我们就让它没事歇着。
相关代码:
JMP $ ;自循环(等待状态)的
串口中断程序:
串口接收数据流程图
发送图片到手机,此主题相关图片如下:
串口接收定长或不定长数据的原理:
如何定义通讯协议:
待续。
发送图片到手机,此主题相关图片如下:
发送图片到手机,此主题相关图片如下:
发送图片到手机,此主题相关图片如下:
发送图片到手机,此主题相关图片如下:
发送图片到手机,此主题相关图片如下:。