机智云( esp8266)与74hc595控制16路继电器
说明:使用74hc595编码器增加8266的io口功能,从而只要利用3个io就可以16路的继电器。
简单介绍:
74HC595:
74HC595是一个8位串行输入、并行输出的位移缓存器:并行输出为三态输出。在SCK 的上升沿,串行数据由SDL输入到内部的8位位移缓存器,并由Q7’输出,而并行输出则是在LCK的上升沿将在8位位移缓存器的数据存入到8位并行输出缓存器。当串行数据输入端OE的控制信号为低使能时,并行输出端的输出值等于并行输出缓存器所存储的值。而当OE为高电位,也就是输出关闭时,并行输出端会维持在高阻抗状态。
使用方法:
74595的数据端:
Q0–Q7: 八位并行输出端,可以直接控制数码管的8个段。
Q7’: 级联输出端。将它接下一个595的DS端。
DS: 串行数据输入端,级联的话接上一级的Q7’。
74595的控制端说明:
/MR(10脚): 低电平时将移位寄存器的数据清零。通常接到VCC防止数据清零。
SH_CP(11脚):上升沿时数据寄存器的数据移位。Q0->Q1->Q2–>Q3–>…–>Q7;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。我通常都选微秒级)
ST_CP(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。
/OE(13脚): 高电平时禁止输出(高阻态)。如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。
注1)74164和74595功能相仿,都是8位串行输入转并行输出移位寄存器。74164的驱动电流(25mA)比74595(35mA)的要小,14脚封装,体积也小一些。
2)74595的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以保持不变。这在串行速度慢的场合很有用处,数码管没有闪烁感。
3)595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,如下面的真值表,在正常使用时ST_CP为低电平, /OE为低电平。从DS每输入一位数据,串行输入时钟SH_CP上升沿有效一次,直到八位数据输入完毕,输出时钟ST_CP上升沿有效一次,此时,输入的数据就被送到了输出端。
我们这里使用它的二级电路,运用俩个595产生16路输出,电路如图所示:
机智云:
一个比较成熟的物联网平台,拥有自己的内部协议,只需要在平台生成代码,稍作修改把固件烧到8266中就可以链接上该平台,并且该平台提供手机开源的手机app,用手机配网链接就可以让8266链接上网,该方案比较具有商用性。(可自行去官网详细了解)
8266与74hc595的驱动程序:
/*
- relay16.c
- Created on: 2018年11月2日
-
Author: 小罗
*/
#include “ets_sys.h”
#include “driver/relay16.h”
#include “osapi.h”
#include “eagle_soc.h”
//放在初始化函数里面:void ICACHE_FLASH_ATTR user_init(void)
void ICACHE_FLASH_ATTR hc595Iinit(void) //gpio初始化
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U,FUNC_GPIO14);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U,FUNC_GPIO13);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12);
PIN_PULLUP_EN(PERIPHS_IO_MUX_MTMS_U);//上拉使能
PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U);
PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDI_U);
gpio_output_set(0,0,GPIO_ID_PIN(12)|GPIO_ID_PIN(13)|GPIO_ID_PIN(14),0);
hc595sendbyte(0xffff); //关闭所有继电器
os_printf(“hc595Iinit\r\n”);
}
void hc595sendbyte(unsigned int temp)
{
unsigned char i;
for(i=0;i<16;i++)
{
if((temp<<i) & 0x8000) DS1;
else DS0;
SH0;
os_delay_us(5);
SH1;
}
ST0;
os_delay_us(5);
ST1;
}
/改变某一位为0/1,flag=0/1, position=1-16/
unsigned int bit_set(unsigned int data,unsigned char flag,unsigned char position )
{
if (flag)//置1
{
data |= (1<<position-1);
}
else
{
data &= ~(1<<position-1);
}
return data;
}
//放在int8_t ICACHE_FLASH_ATTR gizwitsEventProcess(eventInfo_t *info, uint8_t data, uint32_t len)使用
//gizwits_product.c
//对网络按了那些按键进行变化
//sta=1/0
void relay(unsigned char sta,unsigned char n)
{
//继电器的开关状态,1开,0关
static unsigned int state=0xffff;//目前的开关状态
switch(n)
{
case 1:
if(sta)state=bit_set(state,1,1);//第一位置1
else state=bit_set(state,0,1);//第一位置0
break;
case 2:
if(sta)state=bit_set(state,1,2);//第x位置1
else state=bit_set(state,0,2);//第x位置0
break;
case 3:
if(sta)state=bit_set(state,1,3);//第x位置1
else state=bit_set(state,0,3);//第x位置0
break;
case 4:
if(sta)state=bit_set(state,1,4);//第x位置1
else state=bit_set(state,0,4);//第x位置0
break;
case 5:
if(sta)state=bit_set(state,1,5);//第x位置1
else state=bit_set(state,0,5);//第x位置0
break;
case 6:
if(sta)state=bit_set(state,1,6);//第x位置1
else state=bit_set(state,0,6);//第x位置0
break;
case 7:
if(sta)state=bit_set(state,1,7);//第x位置1
else state=bit_set(state,0,7);//第x位置0
break;
case 8:
if(sta)state=bit_set(state,1,8);//第x位置1
else state=bit_set(state,0,8);//第x位置0
break;
case 9:
if(sta)state=bit_set(state,1,9);//第x位置1
else state=bit_set(state,0,9);//第x位置0
break;
case 10:
if(sta)state=bit_set(state,1,10);//第x位置1
else state=bit_set(state,0,10);//第x位置0
break;
case 11:
if(sta)state=bit_set(state,1,11);//第x位置1
else state=bit_set(state,0,11);//第x位置0
break;
case 12:
if(sta)state=bit_set(state,1,12);//第x位置1
else state=bit_set(state,0,12);//第x位置0
break;
case 13:
if(sta)state=bit_set(state,1,13);//第x位置1
else state=bit_set(state,0,13);//第x位置0
break;
case 14:
if(sta)state=bit_set(state,1,14);//第x位置1
else state=bit_set(state,0,14);//第x位置0
break;
case 15:
if(sta)state=bit_set(state,1,15);//第x位置1
else state=bit_set(state,0,15);//第x位置0
break;
case 16:
if(sta)state=bit_set(state,1,16);//第x位置1
else state=bit_set(state,0,16);//第x位置0
break;
default:
//断掉所有继电器
//断开继电器
break;
}
hc595sendbyte(state);//发送state的状态
}
/
- relay16.h
- Created on: 2018年11月2日
-
Author: 小罗
/
#ifndef APP_INCLUDE_DRIVER_RELAY16_H_
#define APP_INCLUDE_DRIVER_RELAY16_H_
#include <stdio.h>
#include <c_types.h>
#include <gpio.h>
#include <eagle_soc.h>
#define DS1 GPIO_OUTPUT_SET(GPIO_ID_PIN(14), 1)
#define DS0 GPIO_OUTPUT_SET(GPIO_ID_PIN(14), 0)
#define ST0 GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0)//输出低
#define ST1 GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1)//输出高
#define SH0 GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0)//输出低
#define SH1 GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1)//输出高
void hc595Iinit(void);
void hc595sendbyte(unsigned int temp);
unsigned int bit_set(unsigned int data,unsigned char flag,unsigned char position );
void relay(unsigned char sta,unsigned char n);
#endif / APP_INCLUDE_DRIVER_RELAY16_H_ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
把这俩程序添加到工程文件里就可以了,稍作修改编译
原文链接:https://blog.csdn.net/weixin_43796593/article/details/84639021