Tauno Erik
Published © GPL3+

Stopwatch with ATtiny13 and TM1637 LED Module

A simple stopwatch.

IntermediateFull instructions provided1.5 hours3,238
Stopwatch with ATtiny13 and TM1637 LED Module

Things used in this project

Hardware components

Attiny13
×1
TM1637 LED module
×1
Push Button
×2
Wire
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

TM1637_Timer.ino

Arduino
/*
 * ATtiny timer with TM1637 display
 * Tauno Erik
 * 18.02.2018
 * 
 */
 
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include "tm1637.c" 


int main(void)
{
  
  uint8_t    i = 0; // Display 1 num right to left
  uint8_t   ii = 0; // Display 2 num right to left
  uint8_t  iii = 0; // Display 3 num right to left
  uint8_t iiii = 0; // Display 4 num right to left

  PORTB |= (1 << PB4); // enable start/stop button

  TM1637_init(); 

  while (1)
  {
    
  int BUTTON = PINB;
  
  if(!(BUTTON&0b00010000)){
    /*When Button is ON */
      
    // Display 1 num right to left
    TM1637_display_digit(TM1637_SET_ADR_03H,i % 0b00001010);
      
    // Display 2 num right to left
    if(i > 9 && ii==0){
      ii = i-9;
      TM1637_display_digit(TM1637_SET_ADR_02H, ii % 0b00001010);
      i = 0;
    }else if(i > 9 && ii > 0){
      ii++;
      TM1637_display_digit(TM1637_SET_ADR_02H, ii % 0b00001010);
      i = 0;
    }
      
    // Display 3 num right to left
    if(ii > 9 && iii==0){
      iii = ii-9;
      TM1637_display_digit(TM1637_SET_ADR_01H, iii % 0b00001010);
      ii = 0;
    }else if(ii > 9 && iii > 0){
      iii++;
      TM1637_display_digit(TM1637_SET_ADR_01H, iii % 0b00001010);
      ii = 0;
    }
      
    // Display 1 num right to left
    if(iii > 9 && iiii==0){
      iiii = iii-9;
      TM1637_display_digit(TM1637_SET_ADR_00H, iiii % 0b00001010);
      ii = 0;
    }else if(iii > 9 && iiii > 0){    
      TM1637_display_digit(TM1637_SET_ADR_00H, iiii % 0b00001010);
      iiii++;
      iii = 0;
    }

    _delay_ms(90);//
    i++;
    
  }else{
  /*When Button is OFF */ 
  }
    
  
  }//while loop end
}//main end

tm1637.h

C/C++
/**
 * Copyright (c) 2017, ukasz Marcin Podkalicki <lpodkalicki@gmail.com>
 * 
 * This is ATtiny13/25/45/85 library for 4-Digit LED Display based on TM1637 chip.
 *
 * Features:
 * - display digits
 * - display colon
 * - display raw segments
 * - display on/off
 * - brightness control 
 *
 * References:
 * - library: https://github.com/lpodkalicki/attiny-tm1637-library
 * - documentation: https://github.com/lpodkalicki/attiny-tm1637-library/README.md
 * - TM1637 datasheet: https://github.com/lpodkalicki/attiny-tm1637-library/blob/master/docs/TM1637_V2.4_EN.pdf
 */

#ifndef	_ATTINY_TM1637_H_
#define	_ATTINY_TM1637_H_

#include <stdint.h>
#include <stdbool.h>

// Main Settings
#define	TM1637_DIO_PIN			PB0
#define	TM1637_CLK_PIN			PB1
#define	TM1637_DELAY_US			(50)
#define	TM1637_DEFAULT_BRIGHTNESS	(7)

// TM1637 commands
#define	TM1637_CMD_SET_DATA		0x40
#define	TM1637_CMD_SET_ADDR		0xC0
#define	TM1637_CMD_SET_DSIPLAY		0x80

// TM1637 data settings (use bitwise OR to contruct complete command)
#define	TM1637_SET_DATA_WRITE		0x00 // write data to the display register
#define	TM1637_SET_DATA_READ		0x02 // read the key scan data
#define	TM1637_SET_DATA_A_ADDR		0x00 // automatic address increment
#define	TM1637_SET_DATA_F_ADDR		0x04 // fixed address
#define	TM1637_SET_DATA_M_NORM		0x00 // normal mode
#define	TM1637_SET_DATA_M_TEST		0x10 // test mode

// TM1637 address settings (use bitwise OR to contruct complete command)
#define	TM1637_SET_ADR_00H		0x00 // address 00
#define	TM1637_SET_ADR_01H		0x01 // address 01
#define	TM1637_SET_ADR_02H		0x02 // address 02
#define	TM1637_SET_ADR_03H		0x03 // address 03

// TM1637 display control command set (use bitwise OR to consruct complete command)
#define	TM1637_SET_DISPLAY_OFF		0x00 // off
#define	TM1637_SET_DISPLAY_ON		0x08 // on


/**
 * Initialize TM1637 display driver.
 * Clock pin (TM1637_CLK_PIN) and data pin (TM1637_DIO_PIN) 
 * are defined at the top of this file.
 */
void TM1637_init(void);

/**
 * Display digits ('0'..'9') at positions (0x00..0x03)
 */
void TM1637_display_digit(const uint8_t addr, const uint8_t digit);

/**
 * Display raw segments at positions (0x00..0x03)
 * 
 *      bits:                 hex:
 *        -- 0 --               -- 01 --
 *       |       |             |        |
 *       5       1            20        02
 *       |       |             |        |
 *        -- 6 --               -- 40 --
 *       |       |             |        |
 *       4       2            10        04
 *       |       |             |        |
 *        -- 3 --               -- 08 --
 *
 * Example segment configurations:
 * - for character 'H', segments=0b01110110
 * - for character '-', segments=0b01000000
 * - etc.
 */
void TM1637_display_segments(const uint8_t addr, const uint8_t segments);

/**
 * Display colon on/off.
 */
void TM1637_display_colon(bool value);

/**
 * Clear all display segments (including colon).
 */
void TM1637_clear(void);

/**
 * Set display brightness.
 * Min brightness: 0
 * Max brightness: 7
 */
void TM1637_set_brightness(const uint8_t brightness);

/**
 * Turn display on/off.
 */
void TM1637_enable(const bool value);

#endif	/* !_ATTINY_TM1637_H_ */

tm1637.c

C/C++
/**
 * Copyright (c) 2017, ukasz Marcin Podkalicki <lpodkalicki@gmail.com>
 * 
 * This is ATtiny13/25/45/85 library for 4-Digit LED Display based on TM1637 chip.
 *
 * Features:
 * - display digits
 * - display colon
 * - display raw segments
 * - display on/off
 * - brightness control
 *
 * References:
 * - library: https://github.com/lpodkalicki/attiny-tm1637-library
 * - documentation: https://github.com/lpodkalicki/attiny-tm1637-library/README.md
 * - TM1637 datasheet: https://github.com/lpodkalicki/attiny-tm1637-library/blob/master/docs/TM1637_V2.4_EN.pdf
 */

#include <avr/io.h>
#include <util/delay.h>
#include "tm1637.h"

#define	TM1637_DIO_HIGH()		(PORTB |= _BV(TM1637_DIO_PIN))
#define	TM1637_DIO_LOW()		(PORTB &= ~_BV(TM1637_DIO_PIN))
#define	TM1637_DIO_OUTPUT()		(DDRB |= _BV(TM1637_DIO_PIN))
#define	TM1637_DIO_INPUT()		(DDRB &= ~_BV(TM1637_DIO_PIN))
#define	TM1637_DIO_READ() 		(((PINB & _BV(TM1637_DIO_PIN)) > 0) ? 1 : 0)
#define	TM1637_CLK_HIGH()		(PORTB |= _BV(TM1637_CLK_PIN))
#define	TM1637_CLK_LOW()		(PORTB &= ~_BV(TM1637_CLK_PIN))

#define	TM1637_FLAG_ENABLED		(1 << 0)
#define	TM1637_FLAG_SHOWCOLON		(1 << 1)


static void TM1637_configure(void);
static void TM1637_cmd(uint8_t value);
static void TM1637_start(void);
static void TM1637_stop(void);
static uint8_t TM1637_write_byte(uint8_t value);

static const uint8_t _digit2segments[] =
{
	0x3F, // 0
	0x06, // 1
	0x5B, // 2
	0x4F, // 3
	0x66, // 4
	0x6D, // 5
	0x7D, // 6
	0x07, // 7
	0x7F, // 8
	0x6F  // 9
};

static uint8_t _brightness = TM1637_DEFAULT_BRIGHTNESS;
static uint8_t _digit = 0xff;
static uint8_t _flags = 0x00;

void
TM1637_init(void)
{

	DDRB |= (_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
	PORTB &= ~(_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
	_flags |= TM1637_FLAG_ENABLED;
	TM1637_clear();
}

void
TM1637_display_digit(const uint8_t addr, const uint8_t digit)
{
	uint8_t segments = digit < 10 ? _digit2segments[digit] : 0x00;

	if (addr == TM1637_SET_ADR_01H) {
		_digit = digit;
		if (_flags & TM1637_FLAG_SHOWCOLON) {
			segments |= 0x80;
		}
	}

	TM1637_display_segments(addr, segments);
}

void
TM1637_display_segments(const uint8_t addr, const uint8_t segments)
{

	TM1637_cmd(TM1637_CMD_SET_DATA | TM1637_SET_DATA_F_ADDR);
	TM1637_start();
	TM1637_write_byte(TM1637_CMD_SET_ADDR | addr);
	TM1637_write_byte(segments);
	TM1637_stop();	
	TM1637_configure();	
}

void
TM1637_display_colon(bool value)
{

	if (value) {
		_flags |= TM1637_FLAG_SHOWCOLON;
	} else {
		_flags &= ~TM1637_FLAG_SHOWCOLON;
	}
	TM1637_display_digit(TM1637_SET_ADR_01H, _digit);
}

void
TM1637_clear(void)
{	

	TM1637_display_colon(false);
	TM1637_display_segments(TM1637_SET_ADR_00H, 0x00);
	TM1637_display_segments(TM1637_SET_ADR_01H, 0x00);
	TM1637_display_segments(TM1637_SET_ADR_02H, 0x00);
	TM1637_display_segments(TM1637_SET_ADR_03H, 0x00);
}

void
TM1637_set_brightness(const uint8_t brightness)
{

	_brightness = brightness & 0x07;
	TM1637_configure();
}

void
TM1637_enable(bool value)
{

	if (value) {
		_flags |= TM1637_FLAG_ENABLED;
	} else {
		_flags &= ~TM1637_FLAG_ENABLED;
	}
	TM1637_configure();
}

void
TM1637_configure(void)
{
	uint8_t cmd;

	cmd = TM1637_CMD_SET_DSIPLAY;
	cmd |= _brightness;
	if (_flags & TM1637_FLAG_ENABLED) {
		cmd |= TM1637_SET_DISPLAY_ON;
	}

	TM1637_cmd(cmd);
}

void
TM1637_cmd(uint8_t value)
{

	TM1637_start();
	TM1637_write_byte(value);
	TM1637_stop();
}

void
TM1637_start(void)
{

	TM1637_DIO_HIGH();
	TM1637_CLK_HIGH();
	_delay_us(TM1637_DELAY_US);
	TM1637_DIO_LOW();
}

void
TM1637_stop(void)
{

	TM1637_CLK_LOW();
	_delay_us(TM1637_DELAY_US);

	TM1637_DIO_LOW();
	_delay_us(TM1637_DELAY_US);

	TM1637_CLK_HIGH();
	_delay_us(TM1637_DELAY_US);

	TM1637_DIO_HIGH();
}

uint8_t
TM1637_write_byte(uint8_t value)
{
	uint8_t i, ack;

	for (i = 0; i < 8; ++i, value >>= 1) {
		TM1637_CLK_LOW();
		_delay_us(TM1637_DELAY_US);

		if (value & 0x01) {
			TM1637_DIO_HIGH();
		} else {
			TM1637_DIO_LOW();
		}

		TM1637_CLK_HIGH();
		_delay_us(TM1637_DELAY_US);
	}

	TM1637_CLK_LOW();
	TM1637_DIO_INPUT();
	TM1637_DIO_HIGH();
	_delay_us(TM1637_DELAY_US);

	ack = TM1637_DIO_READ();
	if (ack) {
		TM1637_DIO_OUTPUT();
		TM1637_DIO_LOW();
	}
	_delay_us(TM1637_DELAY_US);

	TM1637_CLK_HIGH();
	_delay_us(TM1637_DELAY_US);

	TM1637_CLK_LOW();
	_delay_us(TM1637_DELAY_US);

	TM1637_DIO_OUTPUT();

	return ack;
}

Credits

Tauno Erik

Tauno Erik

12 projects • 15 followers
learning somthing new

Comments