目前共有15篇帖子。
[ATtiny13項目]8x8點陣顯示數字和字母
1樓 巨大八爪鱼 2015-7-19 19:39
電路板:
三極體全部都是9012的。左邊的74HC595是決定一橫排的顯示內容,右邊的74HC595則是決定顯示哪一橫排。
左上角的按鍵是RESET鍵,最下面的按鍵是暫停鍵(程序中是K1)
白色的開關為電源開關。
電阻的大小可以直接看色環。
電容是10μF的,位於複位電路上。
左下角的10PIN介面是ISP下載口,用來把程序燒錄到ATtiny13單片機中。
2樓 巨大八爪鱼 2015-7-19 19:43
右邊的8個三極體是的基極是通過右上角的電阻後接到最右邊的74HC595的。

筆者所用操作系統:Fedora Linux 22
程序編譯器:gcc-avr
程序燒錄器:avrdude
Windows下可以用WinAVR來編譯和燒寫。
注意,請不要用AVR_frighter燒寫ATtiny13單片機,這是AVR_frighter的一個bug。燒寫後程序無法運行,I/O口無法輸出任何電平。
3樓 巨大八爪鱼 2015-7-19 19:46
運行效果圖:

按下暫停鍵K1後,黃色LED燈熄滅,點陣停止動畫。
4樓 巨大八爪鱼 2015-7-19 19:46
下面公布程序代碼。
「74HC595.c」
#include <avr/io.h>
#include "74HC595.h"

void HC595_ParOut(void)
{
    HC595_STCK0;
    HC595_STCK1;
}

void HC595_SerIn(unsigned char data)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
        HC595_SHCK0; // CLOCK_MAX = 100MHz
        if (data & _BV(7 - i))
            HC595_SD1;
        else
            HC595_SD0;
        HC595_SHCK1;
    }
}
5樓 巨大八爪鱼 2015-7-19 19:47
「74HC595.h」
#define HC595_SHCK1 PORTB|=_BV(2) // PIN11
#define HC595_SHCK0 PORTB&=~_BV(2)
#define HC595_STCK1 PORTB|=_BV(1) // PIN12
#define HC595_STCK0 PORTB&=~_BV(1)
#define HC595_SD1 PORTB|=_BV(0) // PIN14
#define HC595_SD0 PORTB&=~_BV(0)

void HC595_ParOut(void);
void HC595_SerIn(unsigned char data);
6樓 巨大八爪鱼 2015-7-19 19:47
「main.c」
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#define F_CPU 1200000U
#include <util/delay.h>
#include "74HC595.h"

#define K1 (PINB&_BV(3))

const uint8_t* EEPROM_START = 0x00;
unsigned char count = 0;
unsigned char num = 0x0;
unsigned char left = 252;
unsigned char right = 0;

unsigned char status = 0x00;
#define ROLL 7
#define PAUSE 5

const unsigned char NUM0TO7[] PROGMEM = {
  0x0C, 0x12, 0x12, 0x12, 0x12, 0x12, 0x0C, 0x00,
  0x08, 0x0C, 0x08, 0x08, 0x08, 0x08, 0x1C, 0x00,
  0x0C, 0x12, 0x10, 0x08, 0x04, 0x02, 0x1E, 0x00,
  0x0C, 0x12, 0x10, 0x0C, 0x10, 0x12, 0x0C, 0x00,
  0x08, 0x0C, 0x0C, 0x0A, 0x0A, 0x1E, 0x08, 0x00,
  0x1E, 0x02, 0x02, 0x0E, 0x10, 0x10, 0x0E, 0x00,
  0x0C, 0x12, 0x02, 0x0E, 0x12, 0x12, 0x0C, 0x00,
  0x1E, 0x12, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00};

unsigned char read(unsigned char pos)
{
    if (pos < 64)
        return pgm_read_byte(NUM0TO7 + pos);
    else
    {
        pos -= 64;
        eeprom_busy_wait();
        return eeprom_read_byte(EEPROM_START + pos);
    }
}

void matrixFull(void)
{
    HC595_SerIn(0x00);
    HC595_ParOut();
    HC595_SerIn(0x00);
    HC595_ParOut();
    _delay_ms(1500);
    HC595_SerIn(0xff);
    HC595_ParOut();
}

void matrixScan(unsigned char times)
{
    unsigned char i;
    while (times--)
    {
        if (status & _BV(ROLL))
        {
            /* Roll numbers 0x0 ~ 0xF */
            for (i = 0; i < 8; i++)
            {
                HC595_SerIn(~_BV(i));
                HC595_ParOut();
                if (i < 7)
                {
                    if (left > 200)
                    {
                        /* -1 => 255 (<<4), 4 = 3 + (56 - ([255] - 200))
                        ** -2 => 254 (<<5), 5 = 3 + (56 - ([254] - 200))
                        ** -3 => 253 (<<6), 6 = 3 + (56 - ([253] - 200))
                        ** -4 => 252 (<<7), 7 = 3 + (56 - ([252] - 200)) : completely hidden
                        **/
                        right = (read(num * 8 + i) << (3 + (56 - (left - 200))));
                    }
                    else
                        right = ((read(num * 8 + i) << 3) >> left);
                } else {
                    /* The dot at the bottom */
                    if (num == 0x0 && (left == 0 || left > 200))
                    {
                        // Do not display ". 0"
                        right = 0x00;
                    } else if (num == 0xf && (left >= 3 && left < 200))
                    {
                        // Do not display "F ."
                        right = 0x00;
                    }
                    else
                    {
                        if (left < 200 && left >= 5)
                            right = (0x80 >> (left - 5));
                        else if (left > 200)
                        {
                            /* -4 => 252 (>>3), 3 = [252] - 249
                            ** -3 => 253 (>>4), 4 = [253] - 249
                            ** -2 => 254 (>>5), 5 = [254] - 249
                            ** -1 => 255 (>>6), 6 = [255] - 249
                            **/
                            right = (0x80 >> (left - 249));
                        }
                        else if (left == 0)
                            right = 0x01;
                        else
                            right = 0x00;
                    }
                }
                HC595_SerIn(~right);
                HC595_ParOut();
                _delay_us(500);
                HC595_SerIn(0xff);
                HC595_ParOut();
            }
           
            if (!(status & _BV(PAUSE)))
            {
                count++;
                if (count >= 10)
                {
                    count = 0;
                    left++;
                    if (left < 200 && left >= 8)
                    {
                        // display the next number
                        left = 252;
                        num++;
                        if (num >= 0x10)
                        {
                            // when all the 16 numbers have appeared
                            num = 0x00;
                            status &= ~_BV(ROLL); // stop rolling numbers
                        }
                    }
                }
            }
        }
        else
        {
            /* Display Numbers 0x00 ~ 0xFF */
            for (i = 0; i < 8; i++)
            {
                HC595_SerIn(~_BV(i));
                HC595_ParOut();
                left = (read((num / 0x10) * 8 + i) >> 1);
                right = (read((num % 0x10) * 8 + i) << 3);
                HC595_SerIn(~(left | right));
                HC595_ParOut();
                _delay_us(500);
                HC595_SerIn(0xff);
                HC595_ParOut();
            }
           
            if (!(status & _BV(PAUSE)))
            {
                count++;
                if (count >= 80)
                {
                    count = 0;
                    num++; // num is from 0x00 to 0x99; it's impossible to be 0x100
                    if (num == 0x00)
                    {
                        status |= _BV(ROLL); // begin to roll numbers
                        num = 0x0;
                        left = 252;
                    }
                }
            }
        }
    }
}

void keyScan(void)
{
    // PAUSE Key
    if (!K1)
    {
        matrixScan(7);
        if (!K1)
        {
            if (status & _BV(PAUSE))
            {
                PORTB |= _BV(4);
                status &= ~_BV(PAUSE);
            }
            else
            {
                PORTB &= ~_BV(4);
                status |= _BV(PAUSE);
            }
           
            while (K1)
                matrixScan(5);
            matrixScan(14);
        }
    }
}

int main(void)
{
    DDRB = 0x17; // 00010111
    PORTB = 0x1f; // 00011111
   
    matrixFull();
    status |= _BV(ROLL);
   
    while (1)
    {
        matrixScan(1);
        keyScan();
    }
    return 0;
}

7樓 巨大八爪鱼 2015-7-19 19:47
「Makefile」
# make
main.hex: main.c 74HC595.c
    avr-gcc -mmcu=attiny13 -Wall -Os main.c 74HC595.c -o main.o
    avr-objcopy -j .text -j .data -O ihex main.o main.hex

# make run   
run: main.hex
    sudo avrdude -p t13 -c usbasp -e -U flash:w:main.hex
8樓 巨大八爪鱼 2015-7-19 19:49
在控制台中執行make編譯程序,執行make run編譯程序並通過ISP線燒寫到單片機中。
生成的hex文件大小為2.6 kB (2,575 bytes),佔用Flash 904位元組。
9樓 巨大八爪鱼 2015-7-19 19:58
晶片//chip的EEPROM內容如下:


可以使用下面的C程序寫入上述EEPROM內容:
#include <avr/eeprom.h>

uint8_t* EEPROM_START = 0x00;

int main()
{
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 0, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 1, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 2, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 3, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 4, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 5, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 6, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 7, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 8, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 9, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 10, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 11, 0x1C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 12, 0x10);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 13, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 14, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 15, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 16, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 17, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 18, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 19, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 20, 0x1E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 21, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 22, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 23, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 24, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 25, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 26, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 27, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 28, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 29, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 30, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 31, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 32, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 33, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 34, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 35, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 36, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 37, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 38, 0x0C);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 39, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 40, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 41, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 42, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 43, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 44, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 45, 0x12);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 46, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 47, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 48, 0x1E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 49, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 50, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 51, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 52, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 53, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 54, 0x1E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 55, 0x00);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 56, 0x1E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 57, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 58, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 59, 0x0E);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 60, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 61, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 62, 0x02);
    eeprom_busy_wait();
    eeprom_write_byte(EEPROM_START + 63, 0x00);
    while (1);
    return 0;
}
10樓 巨大八爪鱼 2015-7-19 20:21
[注意]
本人發現,該程序可以在ISP供電環境下正常運行,但無法在5V電源插頭上正常運行(開機顯示滿屏後有時直接出現空白,有時從00開始顯示,跳過了0~F滾動字幕顯示)
目前本人還在查找原因。

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。