作者:新纪元 | 更新时间:2016-04-03 | 浏览量:3404
我们都知道ESP8266外围管脚资源非常有限,但是本人的项目需要通过ESP8266控制15路继电器,如果直接采用脚对脚方式 那不可能完成的。故此 采用两级74HC595通过三根数据线外扩16路IO
具体电路网上一大把,我就不浪费时间(主要我是直接手动焊接,并没有具体画电路图)。管脚配置如下:
GPIO10 RCK
GPIO12 CLK
GPIO13 DAT
因为本人使用软件模拟方式,并没有采用esp硬件SPI资源。然而通过使用官方提供的API进行通信时,通过示波器实测 CLK时钟只有不到500KHz(没话说),所以控制io方面直接采用控制寄存器的方式了 具体如下:
#define GPIO_OUT_W1TS 0x60000304 /*寄存器地址*/ #define GPIO_OUT_W1TC 0x60000308 /*寄存器地址*/ /*eagle_soc.h文件中实现*/ //#define ETS_UNCACHED_ADDR(addr) (addr) //#define READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) //#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val) #define CLK_595_SET \ WRITE_PERI_REG(GPIO_OUT_W1TS,READ_PERI_REG(GPIO_OUT_W1TS) | ((uint32)1 << 12)) #define CLK_595_RESET \ WRITE_PERI_REG(GPIO_OUT_W1TC,READ_PERI_REG(GPIO_OUT_W1TC) | ((uint32)1 << 12)) #define DAT_595_SET \ WRITE_PERI_REG(GPIO_OUT_W1TS,READ_PERI_REG(GPIO_OUT_W1TS) | ((uint32)1 << 13)) #define DAT_595_RESET \ WRITE_PERI_REG(GPIO_OUT_W1TC,READ_PERI_REG(GPIO_OUT_W1TC) | ((uint32)1 << 13))
部分代码如下:
void ICACHE_FLASH_ATTR writeOneByte(unsigned char dat){ unsigned int tmp; for(tmp = 8; tmp; tmp--){ CLK_595_RESET; if(dat & 0x80){ DAT_595_SET; }else{ DAT_595_RESET; } CLK_595_SET; dat <<= 1; } //CLK_595_RESET; }
其实很简单,稍微懂点单片机的都知道!!只是芯片不同驱动IO的方式不同罢了!如上代码时钟速度也仅仅达到1.1MHz左右(实测),如果想通过外扩IO方式实现一些速度要求较高的通信,建议还是放弃吧!但对于 比如我只是控制继电器这种 外扩IO就是一种很明智的选择了 通过两级595就可以达到外扩16路IO了(三级3*8 = 24 。。。),另外我的GPIO12 GPIO13是跟Nokia5110屏幕公用的(通过片选选着)让各位大神见笑了