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

#define TM1628_DIO_PORTNAME     B
#define TM1628_DIO_BIT          5
#define TM1628_CLK_PORTNAME     B
#define TM1628_CLK_BIT          7
#define TM1628_STB_PORTNAME     B
#define TM1628_STB_BIT          4

#ifndef _CONCAT_
#define _CONCAT_
#define CONCAT(a, b)            a ## b
#define CONCAT_DDR(portname)    CONCAT(DDR, portname)
#define CONCAT_PORT(portname)   CONCAT(PORT, portname)
#define CONCAT_PIN(portname)    CONCAT(PIN, portname)
#endif /* CONCAT */

#define TM1628_DIO_DDR          CONCAT_DDR(TM1628_DIO_PORTNAME)
#define TM1628_DIO_PORT         CONCAT_PORT(TM1628_DIO_PORTNAME)
#define TM1628_DIO_PIN          CONCAT_PIN(TM1628_DIO_PORTNAME)
#define TM1628_DIO_0            TM1628_DIO_PORT &= ~(1 << TM1628_DIO_BIT)
#define TM1628_DIO_1            TM1628_DIO_PORT |= (1 << TM1628_DIO_BIT)
#define TM1628_DIO_VALUE        (TM1628_DIO_PIN & (1 << TM1628_DIO_BIT))

#define TM1628_CLK_DDR          CONCAT_DDR(TM1628_CLK_PORTNAME)
#define TM1628_CLK_PORT         CONCAT_PORT(TM1628_CLK_PORTNAME)
#define TM1628_CLK_PIN          CONCAT_PIN(TM1628_CLK_PORTNAME)
#define TM1628_CLK_0            TM1628_CLK_PORT &= ~(1 << TM1628_CLK_BIT)
#define TM1628_CLK_1            TM1628_CLK_PORT |= (1 << TM1628_CLK_BIT)

#define TM1628_STB_DDR          CONCAT_DDR(TM1628_STB_PORTNAME)
#define TM1628_STB_PORT         CONCAT_PORT(TM1628_STB_PORTNAME)
#define TM1628_STB_PIN          CONCAT_PIN(TM1628_STB_PORTNAME)
#define TM1628_STB_0            TM1628_STB_PORT &= ~(1 << TM1628_STB_BIT)
#define TM1628_STB_1            TM1628_STB_PORT |= (1 << TM1628_STB_BIT)

#define SEG_NULL      0x00
#define SEG_P         0x73
#define SEG_N         0x37
#define SEG_U         0x3e
#define SEG_L         0x38
#define SEG_H         0x76
#define SEG_NEG       0x40

#define LEFT          0
#define RIGHT         1

unsigned 
char _data[10], brightness = 0;
long n = 0;

unsigned 
char number[] =
{
    
0x3f,0x06,0x5b,0x4f,
    
0x66,0x6d,0x7d,0x07,
    
0x7f,0x6f,0x77,0x7c,
    
0x39,0x5e,0x79,0x71
};

void TM1628_TxByte(unsigned char _data)
{
    unsigned 
char i = 0;

    TM1628_CLK_1;
    TM1628_DIO_DDR 
|= (1 << TM1628_DIO_BIT);
    
for (i = 0; i < 8; i++)
    {        
        TM1628_CLK_0;
        
if (_data & 0x01)
        {
            TM1628_DIO_1;
        }
        
else
        {
            TM1628_DIO_0;
        }
        TM1628_CLK_1;
        _data 
>>= 1;
    }
    _delay_us(
2);
}

unsigned 
char TM1628_RxByte(void)
{
    unsigned 
char _data = 0, i = 0;

    TM1628_CLK_1;
    TM1628_DIO_DDR 
&= ~(1 << TM1628_DIO_BIT);
    TM1628_DIO_1;
    
for (i = 0; i < 8; i++)
    {
        TM1628_CLK_0;
        _data 
>>= 1;
        TM1628_CLK_1;
        _delay_us(
1);
        
if (TM1628_DIO_VALUE)
        {
            _data 
|= 0x80;
        }
    }

    
return _data;
}

void TM1628_WriteCommand(unsigned char command)
{
    TM1628_STB_0;
    TM1628_TxByte(command);
    TM1628_STB_1;
}

void TM1628_Display(unsigned char *p_data, unsigned char brightness)
{
    unsigned 
char i = 0, j = 0, temp = 0;
    unsigned 
char dis_arr[14= {00000000000000};
    
for (i = 0; i < 7; i++)
    {
        temp 
= 0;
        
for (j = 0; j < 8; j++)
        {
            
if(p_data[j] & (1 << i))
            {
                temp 
|= (1 << j);
            }
        }
        dis_arr[i 
<< 1= temp;
    }
    
for (i = 0; i < 7; i++)
    {
        temp 
= 0;
        
for (j = 0; j < 2; j++)
        {
            
if(p_data[j + 8& (1 << i))
            {
                temp 
|= (1 << j);
            }
        }
        dis_arr[(i 
<< 1+ 1= temp;
    }
    TM1628_WriteCommand(
0x03);
    TM1628_WriteCommand(
0x40);
    TM1628_STB_0;
    TM1628_TxByte(
0xc0);
    _delay_us(
1);
    
for (i = 0; i < 14; i++)
    {
        TM1628_TxByte(dis_arr[i]);
    }
    TM1628_STB_1;
    
if (brightness > 7)
    {
        brightness 
= 7;
    }
    TM1628_WriteCommand(
0x88 + brightness);
}
//数据,进制,起始位置,占用位数,对齐方式,亮度
void TM1628_DisplayNumber(long n, unsigned char ary, unsigned char start, unsigned char size, unsigned char left_right, unsigned char brightness)
{
    unsigned 
char i = 0, temp[size], neg_flag = 0, length = 0;
    
if (-> 0)
    {
        n 
= -n;
        neg_flag 
= 1;
    }
    
for (i = 0; ((i < size) && (n > 0)); i++)
    {
        temp[i] 
= number[n % ary];
        n 
/= ary;
    }
    
if (i == 0)
    {
        temp[i] 
= number[0];
        i 
= 1;
    }
    
if (neg_flag && (i < size))
    {
        temp[i] 
= SEG_NEG;
        i
++;
    }
    length 
= i;
    
if (left_right == LEFT)
    {
        
for (i = 0; i < length; i++)
        {
            _data[start 
+ i] = temp[length - i - 1];
        }
        
for (i = length; i < size; i++)
        {
            _data[start 
+ i] = SEG_NULL;
        }
    }
    
else if (left_right == RIGHT)
    {
        
for (i = 0; i < size - length; i++)
        {
            _data[start 
+ i] = SEG_NULL;
        }
        
for (i = size - length; i < size; i++)
        {
            _data[start 
+ i] = temp[size - i - 1];
        }
    }
    TM1628_Display(_data, brightness);
}

unsigned 
char TM1628_ReadKey(void)
{
    unsigned 
char i = 0, temp = 0;
    
    TM1628_STB_0;
    TM1628_TxByte(
0x42);
    _delay_us(
100);
    
for (i = 0; i < 5; i++)
    {
        _delay_us(
2);
        temp 
= TM1628_RxByte();
        
if (temp)
        {
            
break;
        }
    }
    TM1628_STB_1;
    
if (temp & 0x03)
    {
        temp 
= (2 * i + 1+ ((temp & 0x03- 1* 10;
    }
    
else if (temp & 0x18)
    {
        temp 
= (2 * (i + 1)) + (((temp & 0x18>> 3- 1* 10;
    }
    
return temp;
}

void key_process(unsigned char key)
{
    
if (key != 0)
    {
        TM1628_DisplayNumber(key, 
1022, LEFT, brightness);
    }
    
if (key == 1 && brightness < 7)
    {
        brightness
++;
        TM1628_DisplayNumber(brightness, 
1001, LEFT, brightness);
    }
    
else if (key == 11 && brightness > 0)
    {
        brightness
--;
        TM1628_DisplayNumber(brightness, 
1001, LEFT, brightness);
    }
    
else if (key == 10)
    {
        n
++;
        TM1628_DisplayNumber(n, 
1055, RIGHT, brightness);
    }
    
else if (key ==20)
    {
        n
--;
        TM1628_DisplayNumber(n, 
1055, RIGHT, brightness);
    }
}

int main(void)
{
    unsigned 
char i = 0, key = 0, now = 0, repeat_flag = 0;
    unsigned 
int repeat_count = 0;

    _delay_ms(
100);
    TM1628_STB_1;
    TM1628_STB_DDR 
|= (1 << TM1628_STB_BIT);
    TM1628_CLK_1;
    TM1628_CLK_DDR 
|= (1 << TM1628_CLK_BIT);

    
for (i = 0; i < 10; i++)
    {
        _data[i] 
= SEG_H;
    }
    
for (i = 0; i < 7; i++)
    {
        TM1628_Display(_data, i 
+ 1);
        _delay_ms(
100);
    }
    
for (i = 0; i < 7; i++)
    {
        TM1628_Display(_data, 
7 - i);
        _delay_ms(
100);
    }

    
for (i = 0; i < 10; i++)
    {
        _data[i] 
= SEG_NULL;
    }

    TM1628_DisplayNumber(brightness, 
1001, LEFT, brightness);
    TM1628_DisplayNumber(n, 
1055, RIGHT, brightness);

    
while (1)
    {
        key 
= TM1628_ReadKey();
        
if (key != now)
        {
            now 
= key;
            repeat_flag 
= 0;
            repeat_count 
= 0;
            key_process(key);
        }
        
else
        {
            
if (repeat_flag)
            {
                key_process(key);
                _delay_ms(
50);
            }
            
else 
            {
                repeat_count
++;
                
if (repeat_count > 5000)
                {
                    repeat_flag 
= 1;
                    repeat_count 
= 0;
                }
            }
        }
    }
}