├── .github └── FUNDING.yml ├── tm1637_config.h ├── LICENSE.TXT ├── tm1637.h ├── README.md └── tm1637.c /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | 4 | github: [nimaltd] 5 | patreon: # Replace with a single Patreon username 6 | open_collective: # Replace with a single Open Collective username 7 | ko_fi: nimaltd 8 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 9 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 10 | otechie: # Replace with a single Otechie username 11 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 12 | -------------------------------------------------------------------------------- /tm1637_config.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @file tm1637.h 4 | * @brief tm1637 7seg driver config 5 | * @author Nima Askari 6 | * @version 3.0.0 7 | * @license See the LICENSE file in the root folder. 8 | * 9 | * @note All my libraries are dual-licensed. 10 | * Please review the licensing terms before using them. 11 | * For any inquiries, feel free to contact me. 12 | * 13 | * @github https://www.github.com/nimaltd 14 | * @linkedin https://www.linkedin.com/in/nimaltd 15 | * @youtube https://www.youtube.com/@nimaltd 16 | * @instagram https://instagram.com/github.nimaltd 17 | * 18 | * Copyright (C) 2025 Nima Askari - NimaLTD. All rights reserved. 19 | */ 20 | 21 | #ifndef _TM1637_CONFIG_H_ 22 | #define _TM1637_CONFIG_H_ 23 | 24 | /*************************************************************************************************/ 25 | /** Includes **/ 26 | /*************************************************************************************************/ 27 | 28 | /* USER CODE BEGIN TM1637_INCLUDES */ 29 | 30 | /* USER CODE END TM1637_INCLUDES */ 31 | 32 | /*************************************************************************************************/ 33 | /** Configurations **/ 34 | /*************************************************************************************************/ 35 | 36 | /* USER CODE BEGIN TM1637_CONFIGURATION */ 37 | 38 | #define TM1637_DELAY 10 39 | #define TM1637_ENABLE_ALFABET 1 40 | 41 | /* USER CODE END TM1637_CONFIGURATION */ 42 | 43 | /*************************************************************************************************/ 44 | /** End of File **/ 45 | /*************************************************************************************************/ 46 | 47 | #endif /* _TM1637_CONFIG_H_ */ 48 | -------------------------------------------------------------------------------- /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | # Software License Terms 2 | 3 | This software is dual-licensed under the **GNU General Public License v2 (GPLv2)** and a **Commercial License**. 4 | 5 | --- 6 | 7 | ## 1. GNU General Public License v2 (GPLv2) 8 | This software is licensed under the GNU General Public License version 2 (GPLv2) **only**, as published by the Free Software Foundation. 9 | 10 | - You may redistribute and/or modify this software under the terms of GPLv2. 11 | - This license is provided **without any warranty**, including but not limited to implied warranties of **MERCHANTABILITY** or **FITNESS FOR A PARTICULAR PURPOSE**. 12 | - See for details. 13 | 14 | --- 15 | 16 | ## 2. Commercial License 17 | 18 | A commercial license is available for entities who wish to use this software **without the restrictions of GPLv2** (e.g., in closed-source or proprietary products). 19 | 20 | ### 2.1 Grant of License 21 | - A valid commercial license removes GPLv2 restrictions and grants the right to use, modify, and distribute the software in proprietary or closed-source products. 22 | - Commercial use of this software **requires obtaining a valid license agreement** from the copyright holder. 23 | 24 | ### 2.2 License Models 25 | - **Single-Product License** – Permits usage in **one specific product**. 26 | - **Company-Wide License** – Permits usage across **all products of the company**. 27 | 28 | ### 2.3 Maintenance & Updates 29 | - The licensor *may*, at its sole discretion, provide updates, bug fixes, or new releases. 30 | - The licensor has **no obligation** to release updates or support on a specific schedule. 31 | 32 | --- 33 | 34 | ## 3. Disclaimer of Warranty 35 | 36 | THIS SOFTWARE IS PROVIDED **"AS IS"** AND WITHOUT ANY WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED, OR STATUTORY. 37 | THIS INCLUDES, BUT IS NOT LIMITED TO, THE IMPLIED WARRANTIES OF **MERCHANTABILITY**, **FITNESS FOR A PARTICULAR PURPOSE**, AND **NON-INFRINGEMENT**. 38 | 39 | --- 40 | 41 | ## 4. Limitation of Liability 42 | 43 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES. 44 | THIS INCLUDES, BUT IS NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, LOSS OF DATA, BUSINESS INTERRUPTION, OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO THE USE OF THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 45 | 46 | --- 47 | 48 | ## 5. Reservation of Rights 49 | 50 | All rights not expressly granted under this license are **reserved by the copyright holder**. 51 | 52 | --- 53 | 54 | 📌 For commercial licensing inquiries, please contact: 55 | **Nima Askari** 56 | ✉️ Email: **nima.askari@gmail.com** 57 | 58 | --- 59 | 60 | © 2025 Nima Askari. All rights reserved. 61 | -------------------------------------------------------------------------------- /tm1637.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @file tm1637.h 4 | * @brief tm1637 7seg driver 5 | * @author Nima Askari 6 | * @version 3.0.0 7 | * @license See the LICENSE file in the root folder. 8 | * 9 | * @note All my libraries are dual-licensed. 10 | * Please review the licensing terms before using them. 11 | * For any inquiries, feel free to contact me. 12 | * 13 | * @github https://www.github.com/nimaltd 14 | * @linkedin https://www.linkedin.com/in/nimaltd 15 | * @youtube https://www.youtube.com/@nimaltd 16 | * @instagram https://instagram.com/github.nimaltd 17 | * 18 | * Copyright (C) 2025 Nima Askari - NimaLTD. All rights reserved. 19 | */ 20 | 21 | #ifndef _TM1637_H_ 22 | #define _TM1637_H_ 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /*************************************************************************************************/ 29 | /** Includes **/ 30 | /*************************************************************************************************/ 31 | 32 | #include 33 | #include 34 | #include 35 | #include "main.h" 36 | 37 | /*************************************************************************************************/ 38 | /** Typedef/Struct/Enum **/ 39 | /*************************************************************************************************/ 40 | 41 | /*************************************************************************************************/ 42 | /* Error values returned by OneWire operations */ 43 | typedef enum 44 | { 45 | TM1637_ERR_NONE = 0, /* No error */ 46 | TM1637_ERR_ERROR, /* Acknowledge error */ 47 | 48 | } tm1637_err_t; 49 | 50 | /*************************************************************************************************/ 51 | /* Main driver handle containing config */ 52 | typedef struct 53 | { 54 | GPIO_TypeDef *gpio_clk; 55 | GPIO_TypeDef *gpio_dat; 56 | uint16_t pin_clk; 57 | uint16_t pin_dat; 58 | uint8_t seg_cnt; 59 | 60 | } tm1637_t; 61 | 62 | /*************************************************************************************************/ 63 | /** API Functions **/ 64 | /*************************************************************************************************/ 65 | 66 | /* Initializes the TM1637 display driver */ 67 | tm1637_err_t tm1637_init(tm1637_t *handle); 68 | 69 | /* Sets the brightness level of the TM1637 display */ 70 | tm1637_err_t tm1637_brightness(tm1637_t *handle, uint8_t brightness_0_8); 71 | 72 | /* Sets the number of 7-segment digits to be used on the TM1637 display */ 73 | void tm1637_seg(tm1637_t *handle, uint8_t seg_1_6); 74 | 75 | /* Displays raw segment data on the TM1637 display */ 76 | tm1637_err_t tm1637_raw(tm1637_t *handle, const uint8_t *data); 77 | 78 | /* Displays raw segment data on the TM1637 display */ 79 | tm1637_err_t tm1637_str(tm1637_t *handle, const char *str); 80 | 81 | /* Displays a formatted string on the TM1637 7-segment display */ 82 | tm1637_err_t tm1637_printf(tm1637_t *handle, const char *format, ...); 83 | 84 | /* Clears the TM1637 display by setting all segments to off */ 85 | tm1637_err_t tm1637_clear(tm1637_t *handle); 86 | 87 | /*************************************************************************************************/ 88 | /** End of File **/ 89 | /*************************************************************************************************/ 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | #endif /* _TM1637_H_ */ 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 💡 TM1637 7-Segment Display Driver for STM32 2 | 3 | A lightweight and efficient **TM1637 display driver** written in **C** for STM32 (HAL-based). 4 | 5 | This library provides an easy way to interface STM32 MCUs with the **TM1637** 7-segment LED display driver — commonly used in digital clocks, voltmeters, and similar projects. 6 | It supports **1–6 digits**, **brightness control**, and **formatted string display**. 7 | 8 | --- 9 | 10 | ## ✨ Features 11 | 12 | - 🔹 Supports **1 to 6 digits** (configurable) 13 | - 🔹 Adjustable **brightness levels (0–8)** 14 | - 🔹 Displays **numbers, characters, and strings** 15 | - 🔹 Supports **formatted printing (`printf`)** 16 | - 🔹 Full **STM32 HAL** compatibility 17 | - 🔹 Simple and portable API design 18 | - 🔹 Example and video tutorial included 19 | 20 | --- 21 | 22 | ## ⚙️ Installation 23 | 24 | You can install in two ways: 25 | 26 | ### 1. Copy files directly 27 | Add these files to your STM32 project: 28 | - `tm1637.h` 29 | - `tm1637.c` 30 | - `tm1637_config.h` 31 | 32 | ### 2. STM32Cube Pack Installer (Recommended) 33 | Available in the official pack repo: 34 | 👉 [STM32-PACK](https://github.com/nimaltd/STM32-PACK) 35 | 36 | --- 37 | 38 | ## 🛠 CubeMX Setup 39 | 40 | 1. **CLK (Clock) Pin** – Configure as **Output Open-Drain** 41 | 2. **DIO (Data I/O) Pin** – Configure as **Output Open-Drain** 42 | 3. No timer or interrupt configuration is needed 43 | 44 | --- 45 | 46 | ### Pin Connections 47 | 48 | | Display Segment | TM1637 Pin | 49 | |----------------|-----------| 50 | | A | SEG1 | 51 | | B | SEG2 | 52 | | C | SEG3 | 53 | | D | SEG4 | 54 | | E | SEG5 | 55 | | F | SEG6 | 56 | | G | SEG7 | 57 | | . (Dot) | SEG8 | 58 | 59 | --- 60 | 61 | ## 🚀 Quick Start 62 | 63 | ### Adjust delay 64 | To ensure latency in 'tm1637_config.h', set it to a large value and then adjust it for faster response. 65 | 66 | ```c 67 | TM1637_DELAY 10 68 | ``` 69 | 70 | 71 | ### Define and Initialize a Display 72 | 73 | ```c 74 | #include "tm1637.h" 75 | 76 | tm1637_t seg = 77 | { 78 | .seg_cnt = 4, // Number of digits 79 | .gpio_clk = GPIOA, // CLK pin port 80 | .gpio_dat = GPIOA, // DIO pin port 81 | .pin_clk = GPIO_PIN_1, // CLK pin number 82 | .pin_data = GPIO_PIN_2, // DIO pin number 83 | }; 84 | 85 | tm1637_init(&seg); 86 | tm1637_str(&seg, "1234"); 87 | ``` 88 | 89 | --- 90 | 91 | ## 🧰 API Overview 92 | 93 | | Function | Description | 94 | |----------|-------------| 95 | | `tm1637_init()` | Initializes the TM1637 display driver | 96 | | `tm1637_brightness()` | Sets brightness level (0–8) | 97 | | `tm1637_seg()` | Configures number of active 7-segment digits | 98 | | `tm1637_raw()` | Displays raw segment data buffer | 99 | | `tm1637_str()` | Displays a string on the display | 100 | | `tm1637_printf()` | Displays formatted text using `printf` style | 101 | | `tm1637_clear()` | Clears all digits (turns off all segments) | 102 | 103 | --- 104 | 105 | ## 🎥 Example & Demo Video ( Previous Version ) 106 | 107 |
108 | 109 | TM1637 Video 110 | 111 |
112 | 113 | --- 114 | 115 | ## 💖 Support 116 | 117 | If you find this project useful, please ⭐ the repo and consider supporting me: 118 | 119 | - [![GitHub](https://img.shields.io/badge/GitHub-Follow-black?style=for-the-badge&logo=github)](https://github.com/NimaLTD) 120 | - [![YouTube](https://img.shields.io/badge/YouTube-Subscribe-red?style=for-the-badge&logo=youtube)](https://youtube.com/@nimaltd) 121 | - [![Instagram](https://img.shields.io/badge/Instagram-Follow-blue?style=for-the-badge&logo=instagram)](https://instagram.com/github.nimaltd) 122 | - [![LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue?style=for-the-badge&logo=linkedin)](https://linkedin.com/in/nimaltd) 123 | - [![Email](https://img.shields.io/badge/Email-Contact-red?style=for-the-badge&logo=gmail)](mailto:nima.askari@gmail.com) 124 | - [![Ko-fi](https://img.shields.io/badge/Ko--fi-Support-orange?style=for-the-badge&logo=ko-fi)](https://ko-fi.com/nimaltd) 125 | 126 | --- 127 | 128 | ## 📜 License 129 | 130 | Licensed under the terms in the [LICENSE](./LICENSE.TXT). 131 | -------------------------------------------------------------------------------- /tm1637.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @file tm1637.c 4 | * @brief tm1637 7seg driver 5 | * @author Nima Askari 6 | * @version 3.0.0 7 | * @license See the LICENSE file in the root folder. 8 | * 9 | * @note All my libraries are dual-licensed. 10 | * Please review the licensing terms before using them. 11 | * For any inquiries, feel free to contact me. 12 | * 13 | * @github https://www.github.com/nimaltd 14 | * @linkedin https://www.linkedin.com/in/nimaltd 15 | * @youtube https://www.youtube.com/@nimaltd 16 | * @instagram https://instagram.com/github.nimaltd 17 | * 18 | * Copyright (C) 2025 Nima Askari - NimaLTD. All rights reserved. 19 | */ 20 | 21 | /*************************************************************************************************/ 22 | /** Includes **/ 23 | /*************************************************************************************************/ 24 | 25 | #include "tm1637.h" 26 | #include "tm1637_config.h" 27 | 28 | /*************************************************************************************************/ 29 | /** Macros and Definitions **/ 30 | /*************************************************************************************************/ 31 | 32 | #define TM1637_COMM1 0x40 33 | #define TM1637_COMM2 0xC0 34 | #define TM1637_COMM3_OFF 0x80 35 | #define TM1637_COMM3_ON 0x88 36 | #define TM1637_SEG_MAX 6 37 | 38 | /*************************************************************************************************/ 39 | /** Private Function prototype **/ 40 | /*************************************************************************************************/ 41 | 42 | /* Delay for generating pulse */ 43 | static void tm1637_delay(void); 44 | 45 | /* Generate Start Signal */ 46 | static void tm1637_start(tm1637_t *handle); 47 | 48 | /* Generate Stop Signal */ 49 | static void tm1637_stop(tm1637_t *handle); 50 | 51 | /* Write data to chip */ 52 | static tm1637_err_t tm1637_write(tm1637_t *handle, uint8_t data); 53 | 54 | /*************************************************************************************************/ 55 | /** Function Implementations **/ 56 | /*************************************************************************************************/ 57 | 58 | /*************************************************************************************************/ 59 | /** 60 | * @brief Initializes the TM1637 display driver. 61 | * @param[in] handle Pointer to the TM1637 handle structure. 62 | * @return tm1637_err_t Error code indicating success or failure. 63 | */ 64 | tm1637_err_t tm1637_init(tm1637_t *handle) 65 | { 66 | tm1637_err_t err; 67 | assert_param(handle != NULL); 68 | assert_param(IS_GPIO_PIN(pin_clk)); 69 | assert_param(IS_GPIO_PIN(pin_dat)); 70 | assert_param(handle->gpio_dat != NULL); 71 | assert_param(handle->gpio_clk != NULL); 72 | 73 | /* Set All pins to high */ 74 | handle->gpio_clk->BSRR = handle->pin_clk; 75 | handle->gpio_dat->BSRR = handle->pin_dat; 76 | 77 | /* Send TM1637_COMM1 */ 78 | tm1637_start(handle); 79 | err = tm1637_write(handle, TM1637_COMM1); 80 | tm1637_stop(handle); 81 | return err; 82 | } 83 | 84 | /*************************************************************************************************/ 85 | /** 86 | * @brief Sets the brightness level of the TM1637 display. 87 | * @param[in] handle Pointer to the TM1637 handle structure. 88 | * @param[in] brightness_0_8 Brightness level (0-8), where 0 turns off the display. 89 | * @return tm1637_err_t Error code indicating success or failure. 90 | */ 91 | tm1637_err_t tm1637_brightness(tm1637_t *handle, uint8_t brightness_0_8) 92 | { 93 | tm1637_err_t err; 94 | assert_param(handle != NULL); 95 | 96 | /* Map brightness */ 97 | uint8_t tmp = brightness_0_8 > 8 ? 8 : brightness_0_8; 98 | tmp = (brightness_0_8 == 0) ? TM1637_COMM3_OFF : TM1637_COMM3_ON; 99 | if (brightness_0_8 > 0) 100 | { 101 | brightness_0_8--; 102 | } 103 | 104 | /* Send Brightness */ 105 | tm1637_start(handle); 106 | err = tm1637_write(handle, tmp | brightness_0_8); 107 | tm1637_stop(handle); 108 | return err; 109 | } 110 | 111 | /*************************************************************************************************/ 112 | /** 113 | * @brief Sets the number of 7-segment digits to be used on the TM1637 display. 114 | * @param[in] handle Pointer to the TM1637 handle structure. 115 | * @param[in] seg_1_6 Number of segments (1-6). Values greater than 6 are capped at 6, and 0 is set to 1. 116 | */ 117 | void tm1637_seg(tm1637_t *handle, uint8_t seg_1_6) 118 | { 119 | assert_param(handle != NULL); 120 | 121 | /* Set segment value */ 122 | handle->seg_cnt = (seg_1_6 > 6) ? 6 : seg_1_6; 123 | handle->seg_cnt = (handle->seg_cnt == 0) ? 1 : handle->seg_cnt; 124 | } 125 | 126 | /*************************************************************************************************/ 127 | /** 128 | * @brief Displays raw segment data on the TM1637 display. 129 | * @param[in] handle Pointer to the TM1637 handle structure. 130 | * @param[in] data Pointer to an array containing raw segment data. 131 | * 132 | * @return tm1637_err_t Error code indicating success or failure. 133 | */ 134 | tm1637_err_t tm1637_raw(tm1637_t *handle, const uint8_t *data) 135 | { 136 | tm1637_err_t err; 137 | assert_param(handle != NULL); 138 | 139 | /* Send TM1637_COMM2 */ 140 | tm1637_start(handle); 141 | err = tm1637_write(handle, TM1637_COMM2); 142 | if (err != TM1637_ERR_NONE) 143 | { 144 | return TM1637_ERR_ERROR; 145 | } 146 | 147 | /* Send all data */ 148 | for (uint8_t i = 0; i < handle->seg_cnt; i++) 149 | { 150 | err = tm1637_write(handle, data[i]); 151 | if (err != TM1637_ERR_NONE) 152 | { 153 | break; 154 | } 155 | } 156 | tm1637_stop(handle); 157 | return err; 158 | } 159 | 160 | /*************************************************************************************************/ 161 | /** 162 | * @brief Displays a string on the TM1637 7-segment display. 163 | * @param[in] handle Pointer to the TM1637 handle structure. 164 | * @param[in] str Pointer to a null-terminated string to display. 165 | * Supports numbers (0-9), letters (if enabled), '-' and '.' for decimal points. 166 | * @return tm1637_err_t Error code indicating success or failure. 167 | */ 168 | tm1637_err_t tm1637_str(tm1637_t *handle, const char *str) 169 | { 170 | uint8_t buff[TM1637_SEG_MAX + 1] = {0}; 171 | char *str_tmp = (char*)str; 172 | assert_param(handle != NULL); 173 | 174 | for (int i = 0; i < handle->seg_cnt; i++) 175 | { 176 | switch (*str_tmp) 177 | { 178 | case '0': 179 | buff[i] = 0x3f; 180 | break; 181 | case '1': 182 | buff[i] = 0x06; 183 | break; 184 | case '2': 185 | buff[i] = 0x5b; 186 | break; 187 | case '3': 188 | buff[i] = 0x4f; 189 | break; 190 | case '4': 191 | buff[i] = 0x66; 192 | break; 193 | case '5': 194 | buff[i] = 0x6d; 195 | break; 196 | case '6': 197 | buff[i] = 0x7d; 198 | break; 199 | case '7': 200 | buff[i] = 0x07; 201 | break; 202 | case '8': 203 | buff[i] = 0x7f; 204 | break; 205 | case '9': 206 | buff[i] = 0x6f; 207 | break; 208 | case '-': 209 | buff[i] = 0x40; 210 | break; 211 | #if (TM1637_ENABLE_ALFABET == 1) 212 | case 'A': 213 | case 'a': 214 | buff[i] = 0x77; 215 | break; 216 | case 'B': 217 | case 'b': 218 | buff[i] = 0x7C; 219 | break; 220 | case 'C': 221 | case 'c': 222 | buff[i] = 0x58; 223 | break; 224 | case 'D': 225 | case 'd': 226 | buff[i] = 0x5E; 227 | break; 228 | case 'E': 229 | case 'e': 230 | buff[i] = 0x79; 231 | break; 232 | case 'F': 233 | case 'f': 234 | buff[i] = 0x71; 235 | break; 236 | case 'G': 237 | case 'g': 238 | buff[i] = 0x6f; 239 | break; 240 | case 'H': 241 | case 'h': 242 | buff[i] = 0x76; 243 | break; 244 | case 'I': 245 | case 'i': 246 | buff[i] = 0x04; 247 | break; 248 | case 'J': 249 | case 'j': 250 | buff[i] = 0x0E; 251 | break; 252 | case 'L': 253 | case 'l': 254 | buff[i] = 0x38; 255 | break; 256 | case 'N': 257 | case 'n': 258 | buff[i] = 0x54; 259 | break; 260 | case 'O': 261 | case 'o': 262 | buff[i] = 0x5C; 263 | break; 264 | case 'P': 265 | case 'p': 266 | buff[i] = 0x73; 267 | break; 268 | case 'Q': 269 | case 'q': 270 | buff[i] = 0x67; 271 | break; 272 | case 'R': 273 | case 'r': 274 | buff[i] = 0x50; 275 | break; 276 | case 'S': 277 | case 's': 278 | buff[i] = 0x6D; 279 | break; 280 | case 'T': 281 | case 't': 282 | buff[i] = 0x78; 283 | break; 284 | case 'U': 285 | case 'u': 286 | buff[i] = 0x1C; 287 | break; 288 | case 'Y': 289 | case 'y': 290 | buff[i] = 0x6E; 291 | break; 292 | #endif 293 | default: 294 | buff[i] = 0; 295 | break; 296 | } 297 | if (*(str_tmp + 1) == '.') 298 | { 299 | buff[i] |= 0x80; 300 | str_tmp++; 301 | } 302 | str_tmp++; 303 | } 304 | 305 | /* Write to tm1637 */ 306 | return tm1637_raw(handle, buff); 307 | } 308 | 309 | /*************************************************************************************************/ 310 | /** 311 | * @brief Displays a formatted string on the TM1637 7-segment display. 312 | * @param[in] handle Pointer to the TM1637 handle structure. 313 | * @param[in] format Format string (printf-style) to display. 314 | * @param[in] ... Additional arguments for the formatted string. 315 | * @return tm1637_err_t Error code indicating success or failure. 316 | */ 317 | tm1637_err_t tm1637_printf(tm1637_t *handle, const char *format, ...) 318 | { 319 | char buff[TM1637_SEG_MAX + 1] = {0}; 320 | assert_param(handle != NULL); 321 | 322 | va_list args; 323 | va_start(args, format); 324 | int chars_written = vsnprintf(buff, sizeof(buff), format, args); 325 | va_end(args); 326 | if (chars_written < 0) 327 | { 328 | return TM1637_ERR_ERROR; 329 | } 330 | return tm1637_str(handle, buff); 331 | } 332 | 333 | /*************************************************************************************************/ 334 | /** 335 | * @brief Clears the TM1637 display by setting all segments to off. 336 | * @param[in] handle Pointer to the TM1637 handle structure. 337 | * @return tm1637_err_t Error code indicating success or failure. 338 | */ 339 | tm1637_err_t tm1637_clear(tm1637_t *handle) 340 | { 341 | const uint8_t buff[TM1637_SEG_MAX] = {0}; 342 | assert_param(handle != NULL); 343 | 344 | /* Write all 0 */ 345 | return tm1637_raw(handle, buff); 346 | } 347 | 348 | /*************************************************************************************************/ 349 | /** Private Function Implementations **/ 350 | /*************************************************************************************************/ 351 | 352 | /*************************************************************************************************/ 353 | /** 354 | * @brief Provides a delay for the TM1637 display operations. 355 | * This function uses a simple loop to generate a delay for controlling the timing 356 | * of the TM1637 display operations. 357 | */ 358 | static void tm1637_delay(void) 359 | { 360 | for (uint32_t i = 0; i < TM1637_DELAY; i++) 361 | { 362 | __NOP(); 363 | } 364 | } 365 | 366 | /*************************************************************************************************/ 367 | /** 368 | * @brief Generates a start condition for the TM1637 communication. 369 | * This function generates a start condition by toggling the clock and data lines. 370 | * The start condition is necessary to begin communication with the TM1637 display. 371 | * @param[in] handle Pointer to the TM1637 handle structure. 372 | */ 373 | static void tm1637_start(tm1637_t *handle) 374 | { 375 | assert_param(handle != NULL); 376 | 377 | /* Raise CLK/DAT high */ 378 | handle->gpio_clk->BSRR = handle->pin_clk; 379 | handle->gpio_dat->BSRR = handle->pin_dat; 380 | tm1637_delay(); 381 | 382 | /* Pull DAT low to start */ 383 | handle->gpio_dat->BSRR = handle->pin_dat << 16; 384 | tm1637_delay(); 385 | } 386 | 387 | /*************************************************************************************************/ 388 | /** 389 | * @brief Generates a stop condition for the TM1637 communication. 390 | * This function generates a stop condition by toggling the data and clock lines. 391 | * The stop condition signals the end of communication with the TM1637 display. 392 | * @param[in] handle Pointer to the TM1637 handle structure. 393 | */ 394 | static void tm1637_stop(tm1637_t *handle) 395 | { 396 | assert_param(handle != NULL); 397 | 398 | /* Pull DAT low */ 399 | handle->gpio_dat->BSRR = handle->pin_dat << 16; 400 | tm1637_delay(); 401 | 402 | /* Raise CLK high */ 403 | handle->gpio_clk->BSRR = handle->pin_clk; 404 | tm1637_delay(); 405 | 406 | /* Release DAT high (STOP) */ 407 | handle->gpio_dat->BSRR = handle->pin_dat; 408 | tm1637_delay(); 409 | } 410 | 411 | /*************************************************************************************************/ 412 | /** 413 | * @brief Writes a byte of data to the TM1637 display. 414 | * This function sends a single byte of data to the TM1637 display, bit by bit, 415 | * through the data and clock lines. It also handles the acknowledgment signal 416 | * from the TM1637 after sending the data. 417 | * @param[in] handle Pointer to the TM1637 handle structure. 418 | * @param[in] data The byte of data to send to the display. 419 | * @return tm1637_err_t Error code indicating success or failure. 420 | */ 421 | static tm1637_err_t tm1637_write(tm1637_t *handle, uint8_t data) 422 | { 423 | uint8_t tmp = data; 424 | assert_param(handle != NULL); 425 | 426 | /* Send each bit (LSB first) */ 427 | for (int i = 0; i < 8; i++) 428 | { 429 | handle->gpio_clk->BSRR = handle->pin_clk << 16; 430 | tm1637_delay(); 431 | handle->gpio_dat->BSRR = (tmp & 0x01) ? handle->pin_dat : (handle->pin_dat << 16); 432 | tm1637_delay(); 433 | handle->gpio_clk->BSRR = handle->pin_clk; 434 | tm1637_delay(); 435 | tmp >>= 1; 436 | } 437 | handle->gpio_clk->BSRR = handle->pin_clk << 16; 438 | handle->gpio_dat->BSRR = handle->pin_dat; 439 | tm1637_delay(); 440 | 441 | /* Generate clock pulse for ACK phase */ 442 | handle->gpio_clk->BSRR = handle->pin_clk; 443 | tm1637_delay(); 444 | tm1637_delay(); 445 | 446 | /* Read ACK bit from TM1637 — data line is released and clock is toggled to sample response */ 447 | tmp = (handle->gpio_dat->IDR & handle->pin_dat) ? 1 : 0; 448 | handle->gpio_dat->BSRR = (tmp == 0) ? (handle->pin_dat << 16) : handle->pin_dat; 449 | tm1637_delay(); 450 | handle->gpio_clk->BSRR = handle->pin_clk << 16; 451 | tm1637_delay(); 452 | return (tm1637_err_t)tmp; 453 | } 454 | 455 | /*************************************************************************************************/ 456 | /** End of File **/ 457 | /*************************************************************************************************/ 458 | --------------------------------------------------------------------------------