#include "hc595.h" /****************** 功 能:定义HC595的功能引脚 备 注:变更引脚,由MX配置完成 *******************/ const T_HC595_PIN hc595 = { .sck_port = HC595_SRCLK_GPIO_Port, .sck_pin = HC595_SRCLK_Pin, // 数据输入时钟线 .data_port = HC595_SER_GPIO_Port, .data_pin = HC595_SER_Pin, // 数据线 .rck_port = HC595_RCLK_GPIO_Port, .rck_pin = HC595_RCLK_Pin, // 输出存储器锁存时钟线 .en_port = HC595_OE_GPIO_Port, .en_pin = HC595_OE_Pin // 芯片使能 }; /****************************** 函数名:hc595Init 功 能:初始化hc595的使能脚(EN),默认工作状态 形 参:pin--hc595引脚结构体 返回值: 备 注:0--器件屏蔽 1--器件工作 *******************************/ void hc595_init(const T_HC595_PIN *pin) { LL_GPIO_ResetOutputPin(pin->en_port, pin->en_pin); LL_GPIO_SetOutputPin(HC595_SRCLR_GPIO_Port, HC595_SRCLR_Pin); } /****************************** 函数名:hc595DeInit 功 能:初始化hc595的使能脚(EN),默认休息状态 形 参:pin--hc595引脚结构体 返回值: 备 注:0--器件屏蔽 1--器件工作 *******************************/ void hc595_deInit(const T_HC595_PIN *pin) { LL_GPIO_SetOutputPin(pin->en_port, pin->en_pin); } /****************************** 函数名:hc595WriteStr 功 能:向hc595输出字符 形 参:pin--引脚结构体 data--数据字节组 length--数据字节长度 返回值: 备 注:1、数据输出方向--高位先进,QH=高八位,QG,高七位,QF,高六位,依次下去。 2、CLK:低电平->高电平 移位寄存器存储一个位 RCK:低电平->高电平 输出移位寄存器中缓存的位。 笔 记:这里用的是三级串联,根据HC595的特性,移位寄存器只能存储8个位, 如果移位寄存器的8个位填满后,再往移位寄存器中塞一个,移位寄存器的最后一个位数据会被挤出去, 这个数据会从引脚9(SQH)发送给下个HC595引脚14(SI)。 *******************************/ void hc595_writeStr(const T_HC595_PIN *pin, uint8_t *data, uint16_t length) { uint16_t i; uint8_t byte; data += length - 1; // 等价于data[length - 1] while (length--) { byte = *data--; // 取数组data[length - 1]赋予byte,然后再--data[length - 1]。 for (i = 0; i < 8; i++) { LL_GPIO_ResetOutputPin(pin->sck_port, pin->sck_pin); // clk = 0 保持缓存区状态 if (byte & 0x80) // 从高位开始发送 { LL_GPIO_SetOutputPin(pin->data_port, pin->data_pin); // data=1 } else { LL_GPIO_ResetOutputPin(pin->data_port, pin->data_pin); // data=0 } byte <<= 1; delay_tick(10); // us LL_GPIO_SetOutputPin(pin->sck_port, pin->sck_pin); // clk = 1 存储数据至缓存区 delay_tick(10); // us } } LL_GPIO_ResetOutputPin(pin->rck_port, pin->rck_pin); delay_tick(10); LL_GPIO_SetOutputPin(pin->rck_port, pin->rck_pin); // 发送缓存区内容 } uint8_t iostate[8] = {0}; void io_output(void) { // 电磁阀1,置0 if ((CoilState[0] & 0x80)) { LL_GPIO_ResetOutputPin(DO1_GPIO_Port, DO1_Pin); iostate[7] = 0; } else { LL_GPIO_SetOutputPin(DO1_GPIO_Port, DO1_Pin); iostate[7] = 1; } // 电磁阀2,置0 if ((CoilState[0] & 0x40)) { LL_GPIO_ResetOutputPin(DO2_GPIO_Port, DO2_Pin); iostate[6] = 0; } else { LL_GPIO_SetOutputPin(DO2_GPIO_Port, DO2_Pin); iostate[6] = 1; } // 电磁阀3,置0 if ((CoilState[0] & 0x20)) { LL_GPIO_ResetOutputPin(DO3_GPIO_Port, DO3_Pin); iostate[5] = 0; } else { LL_GPIO_SetOutputPin(DO3_GPIO_Port, DO3_Pin); iostate[5] = 1; } // 电磁阀4,置0 if ((CoilState[0] & 0x10)) { LL_GPIO_ResetOutputPin(DO4_GPIO_Port, DO4_Pin); iostate[4] = 0; } else { LL_GPIO_SetOutputPin(DO4_GPIO_Port, DO4_Pin); iostate[4] = 1; } // 电磁阀5,置0 if ((CoilState[0] & 0x08)) { LL_GPIO_ResetOutputPin(DO5_GPIO_Port, DO5_Pin); iostate[3] = 0; } else { LL_GPIO_SetOutputPin(DO5_GPIO_Port, DO5_Pin); iostate[3] = 1; } // 指示灯1(绿),置0 if ((CoilState[0] & 0x04)) { LL_GPIO_ResetOutputPin(DO6_GPIO_Port, DO6_Pin); iostate[2] = 0; } else { LL_GPIO_SetOutputPin(DO6_GPIO_Port, DO6_Pin); iostate[2] = 1; } // 指示灯2(黄),置0 if ((CoilState[0] & 0x02)) { LL_GPIO_ResetOutputPin(DO7_GPIO_Port, DO7_Pin); iostate[1] = 0; } else { LL_GPIO_SetOutputPin(DO7_GPIO_Port, DO7_Pin); iostate[1] = 1; } // 指示灯3(红,声光),置0 if ((CoilState[0] & 0x01)) { LL_GPIO_ResetOutputPin(DO8_GPIO_Port, DO8_Pin); iostate[0] = 0; } else { LL_GPIO_SetOutputPin(DO8_GPIO_Port, DO8_Pin); iostate[0] = 1; } // 流量计调零 if (CoilState[1] & 0x01) { flow_state = 0; CoilState[1] &= 0xFE; } // 激光调零 if (CoilState[1] & 0x02) { laser_handle.state = 3; CoilState[1] &= 0xFD; } // 增量编码器调零 if (CoilState[1] & 0x04) { LL_TIM_SetCounter(TIM4, 30000); CoilState[1] &= 0xFB; } // 绝对编码器调零 if (CoilState[1] & 0x08) { // laser_handle.state = LASER_OPEN_STATUS; CoilState[1] &= 0xF7; } }