stm32使用74HC595和74HC165
级联 165 和595
十六位输入输出
void main()
{
while(1)
{
SENDVAL595=SENDVAL595|0x0000;
SENDVAL5952=SENDVAL5952|0x00fF;
SENDVAL165_595=SENDVAL165_595|0X0000;//作为输入板
crc16_data7[0]=HC165ReceiveData_Key1();
HC595SendData1(SENDVAL595);
HC595SendData2(SENDVAL5952);
HC165_595SendData1(SENDVAL165_595);
}
}
#include "delay.h"
#include "74HC165.h"
//74HC-595 IO初始化 输入的165的电路板
// A12 D0 Q1 Q3 1号595
//B6 Q2
void LEDHC165_595Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE); //使能PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //A12端口配置Q1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA12
GPIO_ResetBits(GPIOA,GPIO_Pin_12); //PA12 输出低
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //D0端口配置 Q3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //根据设定参数初始化GPIOC0
GPIO_ResetBits(GPIOD,GPIO_Pin_0); //PD0 输出低
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //B6端口配置 Q2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOA0
GPIO_ResetBits(GPIOB,GPIO_Pin_6);
}
#define GPIO_595_PortA GPIOA // 595输出端口
#define GPIO_595_PortB GPIOB // 595输出端口
#define GPIO_595_PortC GPIOC // 595输出端口
#define GPIO_595_PortD GPIOD // 595输出端口
#define HC165_595_Out_RCLK2 GPIO_Pin_12 // 时钟 RCLK Q1 A12
#define HC165_595_Out_SRCLK2 GPIO_Pin_6 // 锁存 SRCLK STCP Q2 B6
#define HC165_595_Out_SER2 GPIO_Pin_0 // 输出数据 SER Q3 D0
u16 SENDVAL165_595 = 0X0000;//595的控制数据
// 0 0 0(饮水机) 0(空开)
/*595数据 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
/*16入出 电气设备1 电气设备2 电气设备3 设备4 设备5 设备6 设备7 设备8 互感4 互感3 饮水机 空开4 空开3 空开2 空开1 */
/*接线 1 2 3 4 5 6 7 8 B7 B6 B5 K4 K3 K2 K1 */
void HC165_595SendData1(u16 SendVal1)//SendVal控制
{
u8 i;
delay_ms(10);
for(i=0;i<16;i++)
{
if(SendVal1&0x8000)//&0x80 4 bir
GPIO_SetBits(GPIO_595_PortD,HC165_595_Out_SER2); // 输出数据 SER Q3 PD0
else
GPIO_ResetBits(GPIO_595_PortD,HC165_595_Out_SER2);
delay_us(20);
GPIO_ResetBits(GPIO_595_PortB,HC165_595_Out_SRCLK2); //移位寄存器时钟输入 SRCLK Q2 PB6
delay_us(20);
SendVal1<<=1;
GPIO_SetBits(GPIO_595_PortB,HC165_595_Out_SRCLK2);
delay_us(20);
}
GPIO_ResetBits(GPIO_595_PortA,HC165_595_Out_RCLK2); //存储寄存器时钟输入 RCLK Q1 PA12
delay_us(20);
GPIO_SetBits(GPIO_595_PortA,HC165_595_Out_RCLK2);
delay_us(20);
}
//初始化PB5和PE5为输出口.并使能这两个口的时钟
//74HC-165 IO初始化
// A11 B7 D1 1号165
//A11 QH 上拉
//B7 S/L 推挽输出 初始化为低
//D1 CLK 推挽输出 初始化为高
void LEDHC165_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD, ENABLE); //使能PE端口时钟
//GPIO A /*PA11上拉输入*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; // A11 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉 QH
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOC0
//GPIO B
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; // B7 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOC0
GPIO_ResetBits(GPIOB,GPIO_Pin_7); //PB7 输出D
//GPIO D
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //D1端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //根据设定参数初始化GPIOD1
GPIO_SetBits(GPIOD,GPIO_Pin_1); //PD1 输出G
}
//函数名称读取 165的数据
uint16_t HC165Data1[16]; //第一个165数据存储的数组
/*165数据 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
/*16入出 检流计2 检流计1 自耦计2 自耦计1 空开4 空开3 空开2 空开1 互感4 互感3 互感2 互感1 开关2 开关1 电源负 电源正 */
/*接线 B10 B9 C6 C5 C4 C3 C2 C1 B8 B7 B6 B5 B4 B3 B2 B1 */
uint16_t HC165ReceiveData_Key1(void) //第一个74HC165数据读取
{
uint8_t i;
uint16_t indata;
HC165_SHLD1=0; //数据输入 S/L
delay_us(1);
HC165_SHLD1=1;
delay_us(1);
indata=0xffff;//4 BIR
for(i=0;i<16;i++)//16
{
indata=indata<<1;
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)==0) //QH输入
indata+=1;
GPIO_SetBits(GPIOD,GPIO_Pin_1); //CLK时钟跳变
delay_us(1);
GPIO_ResetBits(GPIOD,GPIO_Pin_1); //CLK时钟跳变
delay_us(1);
}
indata=(((indata>>8)&0x00ff)|((indata<<8)&0xff00));
return(indata);
}
#if 0
/*595数据 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
/*16入出 电池负 电池正 继电器4 继电器3 继电器2 继电器1 变阻器2 变阻器1 微安计2 微安计1 变流器4 变流器3 变流器2 变流器1 自耦计4 自耦计3 */
/*接线 C22 C21 C20 C19 C18 C17 C16 C15 C14 C13 C12 C11 C10 C9 C8 C7 */
uint16_t HC165ReceiveData_Key2(void) //第二个74HC165数据读取
{
uint8_t i;
uint16_t indata;
HC165_SHLD2=0; //数据输入
delay_us(1);
HC165_SHLD2=1;
delay_us(1);
indata=0xffff;
for(i=0;i<16;i++)
{
indata=indata<<1;
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)==0) //QH输入
indata+=1;
GPIO_SetBits(GPIOA,GPIO_Pin_0); //CLK时钟跳变
delay_us(1);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
delay_us(1);
}
indata=(((indata>>8)&0x00ff)|((indata<<8)&0xff00));
return(indata);
}
/*165数据 7 6 5 4 3 2 1 0 */
/*4入出 空 空 空 空 自耦控制 按钮 指示灯2 指示灯1 */
/*接线 空 空 空 空 自耦控制 按钮 C24 C23 */
uint8_t HC165ReceiveData_Key3(void) //第三个74HC165数据读取
{
uint8_t i;
uint8_t indata;
HC165_SHLD3=0; //数据输入
delay_us(1);
HC165_SHLD3=1;
delay_us(1);
indata=0xff;
for(i=0;i<8;i++)
{
indata=indata<<1;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0) //QH输入
indata+=1;
GPIO_SetBits(GPIOC,GPIO_Pin_0); //CLK时钟跳变
delay_us(1);
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
delay_us(1);
}
return(indata);
}
#endif
void HC165_Data() //165数据处理,将读取的数据分开放在数组中
{
u8 i=0;
for(i=0;i<16;i++)
{
HC165Data1[i]=(HC165ReceiveData_Key1()>>(i))&1;
}
}
#include "74HC595.h"
#include "DELAY.h"
//初始化PB5和PE5为输出口.并使能这两个口的时钟
//74HC-595 IO初始化
// C1 A0 C0 Q1 Q2 Q3 1号595
//C2 A1 C3 2号595
void LED5954HC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //使能PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //C0 C1 C2 C3 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOC0
GPIO_ResetBits(GPIOC,GPIO_Pin_0); //PC0 输出低
GPIO_ResetBits(GPIOC,GPIO_Pin_1); //PC1 输出低
GPIO_ResetBits(GPIOC,GPIO_Pin_2); //PC1 输出低
GPIO_ResetBits(GPIOC,GPIO_Pin_3); //PC1 输出低
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //A0 A1端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA0
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
/************************************************************************
*函数名称:void Write_595(uint64_t dat)
*函数功能:写595
*函数参数:uint64_t dat
*返回值 :无
************************************************************************/
#define GPIO_595_PortA GPIOA // 595输出端口
#define GPIO_595_PortB GPIOB // 595输出端口
#define GPIO_595_PortC GPIOC // 595输出端口
#define GPIO_595_PortD GPIOD // 595输出端口
#define Out_RCLK GPIO_Pin_1 // 时钟 RCLK
#define Out_SRCLK GPIO_Pin_0 // 锁存 SRCLK STCP
#define Out_SER GPIO_Pin_0 // 输出数据 SER
#define Out_RCLK2 GPIO_Pin_2 // 时钟 RCLK Q1 C2
#define Out_SRCLK2 GPIO_Pin_1 // 锁存 SRCLK STCP Q2 A1
#define Out_SER2 GPIO_Pin_3 // 输出数据 SER Q3 C3
u16 SENDVAL595 = 0X0000;//595的控制数据
// 0 0 0(饮水机) 0(空开)
/*595数据 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
/*16入出 电气设备1 电气设备2 电气设备3 设备4 设备5 设备6 设备7 设备8 互感4 互感3 饮水机 空开4 空开3 空开2 空开1 */
/*接线 1 2 3 4 5 6 7 8 B7 B6 B5 K4 K3 K2 K1 */
void HC595SendData1(u16 SendVal1)//SendVal控制
{
u8 i;
for(i=0;i<16;i++)
{
if(SendVal1&0x8000)//&0x80 4 bir
GPIO_SetBits(GPIO_595_PortC,Out_SER); // 输出数据 SER Q3 PC0
else
GPIO_ResetBits(GPIO_595_PortC,Out_SER);
delay_us(20);
GPIO_ResetBits(GPIO_595_PortA,Out_SRCLK); //移位寄存器时钟输入 SRCLK Q2 PA0
delay_us(20);
SendVal1<<=1;
GPIO_SetBits(GPIO_595_PortA,Out_SRCLK);
delay_us(20);
}
GPIO_ResetBits(GPIO_595_PortC,Out_RCLK); //存储寄存器时钟输入 RCLK Q1 PC1
delay_us(20);
GPIO_SetBits(GPIO_595_PortC,Out_RCLK);
delay_us(20);
}
u16 SENDVAL5952= 0X0000;// (2号板) 595的控制数据
//595 16位 2号板
void HC595SendData2(u16 SendVal2)//SendVal控制
{
u8 i;
for(i=0;i<16;i++)
{
if(SendVal2&0x8000)
GPIO_SetBits(GPIO_595_PortC,Out_SER2); // 输出数据 SER Q3 PC3
else
GPIO_ResetBits(GPIO_595_PortC,Out_SER2);
delay_us(20);
GPIO_ResetBits(GPIO_595_PortA,Out_SRCLK2); //移位寄存器时钟输入 SRCLK Q2 PA1
delay_us(20);
SendVal2<<=1;
GPIO_SetBits(GPIO_595_PortA,Out_SRCLK2);
delay_us(20);
}
GPIO_ResetBits(GPIO_595_PortC,Out_RCLK2); //存储寄存器时钟输入 RCLK Q1 PC2
delay_us(20);
GPIO_SetBits(GPIO_595_PortC,Out_RCLK2);
delay_us(20);
}