在我刚学单片机时总是感觉很难理解,今天分析下74HC595串口转并口 IO扩展芯片,一般我们在IO口不够用的情况下才能祭出此神器. 那么我们如何驱动此神器呢? “念咒:天灵灵地灵灵,Q1开”!
产品手册就不贴了,能看到文章的都是为驱动来的. 概念梳理 SI 串行数据输入端 == 相当于上面的水 0或者1 SCK 移位寄存器时钟,上升沿移位 == 相当于上面的内部的活塞 RCK 锁存寄存器时钟,上升沿存储 == 相当于搬走储水罐 驱动编写第一步 放下储水罐 RCK =0;
第二步 把活塞压下去 SCK =0 ;
第三步 水通过出水口压到 储水罐 SI =0 或者 SI = 1;
第四步 把活塞提上去 SCK =1;
循环8次 把储水罐 水装满
第五步 提走储水罐 RCK =1;
是不是形象有属于理解 8 次水相当于8个数据 0或者1 ,对于输出就Q1–Q7电平状态
程序代码#include "drvs.h"
// 74HC595 驱动
//资料 PB05 SI
//大平台 PB08 RCK
//活塞 PB09 SCK
//Q0 运行灯 Q1通讯灯 Q2故障灯 Q3过载灯 Q4 短路灯 Q5报警灯
#define SI_PORT (PortB)
#define SI_PIN (Pin05)
#define RCK_PORT (PortB)
#define RCK_PIN (Pin08)
#define SCK_PORT (PortB)
#define SCK_PIN (Pin09)
#define SI_ON() PORT_SetBits(SI_PORT,SI_PIN) //开1
#define SI_OFF() PORT_ResetBits(SI_PORT,SI_PIN) //关0
#define RCK_ON() PORT_SetBits(RCK_PORT,RCK_PIN) //开1
#define RCK_OFF() PORT_ResetBits(RCK_PORT,RCK_PIN) //关0
#define SCK_ON() PORT_SetBits(SCK_PORT,SCK_PIN) //开1
#define SCK_OFF() PORT_ResetBits(SCK_PORT,SCK_PIN) //关0
void Init_74HC595(void)
{
stc_port_init_t stcPortInit;
/*配置结构初始化*/
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;//输出模式
stcPortInit.enExInt = Enable;//Enable//Disable
stcPortInit.enPullUp = Enable;//enPinDrv
/* BL10 Port/Pin 初始化 */
PORT_Init(SI_PORT, SI_PIN, &stcPortInit);
PORT_Init(RCK_PORT, RCK_PIN, &stcPortInit);
PORT_Init(SCK_PORT, SCK_PIN, &stcPortInit);
SI_OFF();//SI串行数据输入端
RCK_OFF();//RCK 锁存寄存器时钟,上升沿存储
SCK_OFF();//SCK 移位寄存器时钟,上升沿移位
}
//设置74HC595 端口电平
void Set_Show(uint8_t outdata)
{
RCK_OFF();//
uint8_t i;
for(i=0;i<8;i++)
{
SCK_OFF(); //
if(outdata&0x80)
{
SI_ON();//
}
else
{
SI_OFF();//
}
SCK_ON(); //
outdata<<=1;
}
RCK_ON(); //
}
uint8_t temp595=0xFF;//默认高电平灯全关
uint8_t tempces=0xFF;
//74HC595单独控制驱动
typedef enum
{
LED1, //Q0 LED1 运行灯
LED2, //Q1 LED2 通信灯
LED3, //Q2 LED3 故障灯
LED4, //Q3 LED4 过载灯
LED5, //Q4 LED5 短路灯
LED6, //Q5 LED6 报警灯
BUZZ, //Q6 蜂鸣器
BLED, //Q7 背光
LED_ALL, //全部启动
}IO74HC595;
/*
* com 某位端口
* val 电平值
*/
//控制595输出
void Set_IO_input(uint8_t com,uint8_t val)
{
if(com==LED_ALL)
{
if(val==0)//输入关
{
temp595=0xFF;//
}
else
{
temp595=0x00;
}
}
else
{
if(val==0)//输入关
{
temp595|=0x01<<com; //把某位置高电平
}
else //输入开
{
temp595 &= ~(0x01<<com);
}
}
if(tempces!=temp595)//数据变化才发送控制
{
tempces = temp595;
Set_Show(tempces);
}
}
//74HC595测试代码
void CS_74HC595(void)
{
Set_IO_input(LED1,1);//点亮LED1
}
总结
74HC595D 芯片驱动还是很简单很好用,做EMC实验建议和单片机连接的管脚加上拉电阻,可能有静电过不了的风险.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)