目前共有15篇帖子。
[ATtiny13項目]8x8點陣顯示數字和字母
11樓 巨大八爪鱼 2017-4-4 16:06
5V電源上程序卡死的問題已經解決了。是因為開機時的滿屏顯示電流過大導致的。
(當電源電壓=5.76V時滿屏顯示需要非常大的電流,單片機承受不了)
把滿屏顯示的程序改成一行一行地動態掃描就解決問題了。

【更新後的matrixFull函數】
void matrixFull(void)
{
    uint8_t i, tmp;
    uint32_t cnt = 100;
    while (cnt--)
    {
        tmp = 1;
        for (i = 0; i < 8; i++)
        {
            HC595_SerIn(~tmp); // 寫成~_BV(i)太占空間, 改成這種形式會節約一點空間
            HC595_SerIn(0x00);
            HC595_ParOut();
            _delay_ms(1);
            tmp <<= 1;
        }
    }
}

由於晶片//chip所剩的Flash空間已經不多了,而_BV裡面的(1<<n)語句和~運算符要佔用好幾十位元組的Flash,所以設置了一個tmp變數來代替。
在Windows下的Atmel Studio裡面編譯時,可添加一個頭文件:#include <avr/sfr_defs.h>,以解決代碼編輯器里_BV有下劃線警告的問題。
12樓 巨大八爪鱼 2017-4-4 16:13
另外,matrixScan函數里有幾個HC595_ParOut是多餘的,應該去掉。
編譯後,佔用的Flash大小為1018位元組(容量為1024位元組)。
EEPROM是之前燒寫好了的,用完了整個64位元組的空間。
【編譯信息】
------ Build started: Project: TinyBoard, Configuration: Debug AVR ------
Build started.
Project "TinyBoard.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project "E:\Users\Octopus\Documents\Atmel Studio\7.0\TinyBoard\TinyBoard\TinyBoard.cproj" (target "Build" depends on it):
    Task "RunCompilerTask"
        Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
        C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 4 --output-sync
        make: Nothing to be done for 'all'.
    Done executing task "RunCompilerTask".
    Task "RunOutputFileVerifyTask"
                Program Memory Usage     :    1018 bytes   99.4 % Full
                Data Memory Usage         :    8 bytes   12.5 % Full
    Done executing task "RunOutputFileVerifyTask".
Done building target "CoreBuild" in project "TinyBoard.cproj".
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').
Target "Build" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Avr.common.targets" from project "E:\Users\Octopus\Documents\Atmel Studio\7.0\TinyBoard\TinyBoard\TinyBoard.cproj" (entry point):
Done building target "Build" in project "TinyBoard.cproj".
Done building project "TinyBoard.cproj".

Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
14樓 巨大八爪鱼 2017-4-4 16:18
滿屏畫面改成動態掃描方式顯示後,會發現亮度比原來靜態顯示時要高一些,這充分說明原來的電流太大了,單片機無法承受。
15樓 巨大八爪鱼 2017-4-4 18:01
【更新後的main.c文件】
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/sfr_defs.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)
{
    uint8_t i, tmp;
    uint32_t cnt = 100;
    while (cnt--)
    {
        tmp = 1;
        for (i = 0; i < 8; i++)
        {
            HC595_SerIn(~tmp); // 寫成~_BV(i)太占空間, 改成這種形式會節約一點空間
            HC595_SerIn(0x00);
            HC595_ParOut();
            _delay_ms(1);
            tmp <<= 1;
        }
    }
}

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));
                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);
            }
          
            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));
                left = (read((num / 0x10) * 8 + i) >> 1);
                right = (read((num % 0x10) * 8 + i) << 3);
                HC595_SerIn(~(left | right));
                HC595_ParOut();
                _delay_us(500);
            }
          
            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;
}
16樓 巨大八爪鱼 2017-4-4 18:01
回復15樓 @巨大八爪鱼 的內容:
【更新後的main.c文件】
#include <avr/io.h>
#include <avr/eeprom.h>
#include <a...
該程序編譯後的大小為1006位元組。

回復帖子

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