#include #include #include "pico/stdlib.h" #include "hardware/pio.h" #include "TM1637.h" #include "tm1637out.pio.h" const uint8_t digit_seg[] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111, // 9 }; const uint8_t letter_seg[] = { 0b01110111, // A 0b01111100, // b 0b00111001, // C 0b01011110, // d 0b01111001, // E 0b01110001, // F 0b00111101, // G 0b01110110, // H 0b00000100, // i 0b00001110, // J 0b00000000, // K 0b00111000, // L 0b00000000, // M 0b01010100, // n 0b01011100, // o 0b01110011, // P 0b01100111, // q 0b01010000, // r 0b01101101, // S 0b01111000, // t 0b00011100, // u 0b00000000, // V 0b00000000, // W 0b00000000, // X 0b01101110, // y 0b00000000, // z }; // 先頭のTM1637_tのポインタ static TM1637_t *first = NULL; // 文字コード→セグメントコード uint32_t chr_to_seg(char c) { if(c >= '0' && c <= '9') return digit_seg[c - '0']; if(c >= 'a' && c <= 'z') return letter_seg[c - 'a']; if( c >= 'A' && c <= 'Z') return letter_seg[c - 'A']; if( c == ':' || c == '.') return DOT_SEG; if( c == '-' ) return MINUS_SEG; return 0; } // TM1637を追加する int TM1637_add(TM1637_t *next) { if (first == NULL) { first = next; return 0; } TM1637_t *p = first; while(p->next != NULL) p = p->next; p->next = next; return 0; } TM1637_t *TM1637_init(uint8_t sda_base_pin, uint8_t col, uint8_t cont) { uint8_t colmns, contrast; PIO pio; uint sm, pio_offset; TM1637_t *p; // デフォルト値の設定 if(col <= TM1637_MAX_COL && col > 0) colmns = col; else return NULL; if(cont <= TM1637_MAX_CONTRAST) contrast = cont; else return NULL; if(pio_claim_free_sm_and_add_program(&tm1637out_program, &pio, &sm, &pio_offset)) { // PIO初期化 tm1637out_program_init(pio, sm, pio_offset, sda_base_pin, sda_base_pin+1); // SM起動 pio_sm_set_enabled(pio, sm, true); } else // PIOを確保できなかった return NULL; // ここまでできたら初期化成功と見て構造体を作成する p = (TM1637_t *)malloc(sizeof(TM1637_t)); p->colmns = colmns; p->contrast = contrast; p->pio = pio; p->sm = sm; p->offset = pio_offset; p->next = NULL; p->initialized = true; // 末尾に追加 TM1637_add(p); // TM1637初期化 // データセット(自動アドレスインクリメント) pio_sm_put_blocking(pio, sm, TM1637_AUTOINC | STOP_COND); // アドレス0からカラム数分を0で初期化 pio_sm_put_blocking(pio, sm, TM1637_ADDRSET| 0 ); for(int i = 0; i < colmns; i++) { uint32_t data = 0; if( i == (colmns - 1) ) data = STOP_COND; pio_sm_put_blocking(pio, sm, data); } // コントラスト値で表示オン TM1637_set_contrast(p, contrast); return p; } int TM1637_set_contrast(TM1637_t *p, uint8_t cont) { if(cont <= TM1637_MAX_CONTRAST) p->contrast = cont; else return TM1637_ERR_INVALID_PARAM; pio_sm_put_blocking(p->pio, p->sm, TM1637_DISPON | cont | STOP_COND); return 0; } int TM1637_putchar(TM1637_t *p, char c, bool dot,uint8_t col) { if(col >= p->colmns) return TM1637_ERR_INVALID_PARAM; // 固定アドレスデータセット pio_sm_put_blocking(p->pio, p->sm, TM1637_DATASET | STOP_COND); // アドレス pio_sm_put_blocking(p->pio, p->sm, TM1637_ADDRSET | col); // セグメントデータ pio_sm_put_blocking(p->pio, p->sm, chr_to_seg(c) | (dot ? DOT_SEG : 0) | STOP_COND); return 0; } int TM1637_putstr(TM1637_t *t, char *str) { int col = 0, p = 0; // データセット(自動アドレスインクリメント) pio_sm_put_blocking(t->pio, t->sm, TM1637_AUTOINC | STOP_COND); // アドレス0セット pio_sm_put_blocking(t->pio, t->sm, TM1637_ADDRSET| 0 ); // 文字数分を出力 while(str[col] != '\0') { uint32_t data = chr_to_seg(str[col++]); // ドットマーク if(str[col] == '.' || str[col] == ':') { data |= DOT_SEG; col++; } // 最後はStop Condition if(str[col] == '\0' || ++p >= t->colmns) data |= STOP_COND; pio_sm_put_blocking(t->pio, t->sm, data); // カラム数に達したら終わり if( p >= t->colmns ) break; } return 0; }