extend_io.c 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include <stdio.h>
  2. #include "freertos/FreeRTOS.h"
  3. #include "freertos/task.h"
  4. #include "driver/gpio.h"
  5. #include "extend_io.h"
  6. #include <esp_log.h>
  7. static const char* TAG = "IO";
  8. uint8_t io_status=0;
  9. // 初始化GPIO
  10. void hc595_init() {
  11. gpio_config_t io_conf = {
  12. .pin_bit_mask = (1ULL << DATA_PIN) | (1ULL << CLOCK_PIN) | (1ULL << LATCH_PIN),
  13. .mode = GPIO_MODE_OUTPUT,
  14. .pull_up_en = GPIO_PULLUP_DISABLE,
  15. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  16. .intr_type = GPIO_INTR_DISABLE
  17. };
  18. gpio_config(&io_conf);
  19. // 初始状态置低
  20. gpio_set_level(DATA_PIN, 0);
  21. gpio_set_level(CLOCK_PIN, 0);
  22. gpio_set_level(LATCH_PIN, 0);
  23. }
  24. // 发送数据到74HC595
  25. void hc595_send(uint8_t *data, size_t len) {
  26. // 锁存引脚置低,准备发送数据
  27. gpio_set_level(LATCH_PIN, 0);
  28. for (int bit = 7; bit >= 0; bit--) {
  29. // 设置数据位
  30. gpio_set_level(DATA_PIN, (*data >> bit) & 0x01);
  31. // 产生时钟上升沿
  32. gpio_set_level(CLOCK_PIN, 1);
  33. gpio_set_level(CLOCK_PIN, 0);
  34. }
  35. // 数据发送完成,锁存引脚置高更新输出
  36. gpio_set_level(LATCH_PIN, 1);
  37. // 保持最小脉冲宽度 (可省略)
  38. vTaskDelay(pdMS_TO_TICKS(1));
  39. gpio_set_level(LATCH_PIN, 0);
  40. }
  41. void HC595_Send_Byte(uint8_t byte) {
  42. uint8_t i;
  43. for (i = 0; i < 8; i ++) //一个字节8位,传输8次,一次一位,循环8次,刚好移完8位
  44. {
  45. /**** 步骤1:将数据传到DS引脚 ****/
  46. if( byte & (0x0001<<i) )
  47. HC595_Data_High(); //如果第八位是1,则与 595 DS连接的引脚输出高电平
  48. else //否则输出低电平
  49. HC595_Data_Low();
  50. /*** 步骤2:SHCP每产生一个上升沿,当前的bit就被送入移位寄存器 ***/
  51. HC595_SHCP_Low(); // SHCP拉低
  52. //vTaskDelay(pdMS_TO_TICKS(1)); // 适当延时
  53. HC595_SHCP_High(); // SHCP拉高, SHCP产生上升沿
  54. // vTaskDelay(pdMS_TO_TICKS(1));
  55. //byte <<= 1; // 左移一位,将低位往高位移,通过 if (byte & 0x80)判断低位是否为1
  56. }
  57. }
  58. /**
  59. *74HC595输出锁存 使能
  60. **/
  61. void HC595_CS(void) {
  62. /** 步骤3:STCP产生一个上升沿,移位寄存器的数据移入存储寄存器 **/
  63. HC595_STCP_Low(); // 将STCP拉低
  64. vTaskDelay(pdMS_TO_TICKS(1)); // 适当延时
  65. HC595_STCP_High(); // 再将STCP拉高,STCP即可产生一个上升沿
  66. vTaskDelay(pdMS_TO_TICKS(1));
  67. }
  68. esp_err_t hc595_gpio_write(extend_gpio_num_t gpio_num, uint32_t level) {
  69. if (level==1) {
  70. io_status |= 1 << (7-gpio_num);
  71. // io_status=0x0f;
  72. }else {
  73. io_status &= ~(1 << (7-gpio_num));
  74. // io_status=0x00;
  75. }
  76. HC595_Send_Byte(io_status);
  77. HC595_CS();
  78. return ESP_OK;
  79. }