2012-05-05 49 views
3

我已经创建了一个8×8的LED矩阵,其由mircocontroller(具体Atmega8的)来控制,一个8位的移位寄存器(HEF4794),和驱动器阵列(MIC2981)。我遇到的问题是应该显示的图案不居中。它需要被转移到左边的一列和两列。任何帮助将非常感激。LED矩阵使用AVR控制器

我计上心来为这个项目从这里:http://www.instructables.com/id/LED-matrix-using-shift-registers/

/* 
* AVRGCC3.c 
* 
* Created: 4/28/2012 1:39:29 PM 
* Author: Scott 
*/ 

#define F_CPU 12000000UL 

#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <util/delay.h> 
#include <avr/pgmspace.h> 
#include "font8x8.h" 

#define ShiftPort PORTC 
#define ShiftDDR DDRC 
#define LatchPin (1 << 0) 
#define DataPin  (1 << 1) 
#define ClkPin  (1 << 2) 
#define OE   (1 << 3) 

#define RowPort  PORTD 
#define RowDDR  DDRD 
#define RowPin0  (1 << 0) 
#define RowPin1  (1 << 1) 
#define RowPin2  (1 << 2) 
#define RowPin3  (1 << 3) 
#define RowPin4  (1 << 4) 
#define RowPin5  (1 << 5) 
#define RowPin6  (1 << 6) 
#define RowPin7  (1 << 7) 

#define ScrollSpeed 75 //How many milliseconds to pause before shifting columns left 

typedef unsigned char u8; 
typedef unsigned int u16; 

u8 row_track = 0; 

volatile u8 row_buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 

void Delay_ms(int cnt) //Function delays a give number of milliseconds. Depends on F_CPU being defined 
{ 
    while (cnt-->0) _delay_ms(1); 
} 

static inline void InitPorts(void) //Function used once to initialize the ports 
{ 
    ShiftDDR |= (LatchPin | ClkPin | DataPin | OE); //Setup shift register control pins 
    RowDDR |= (RowPin0 | RowPin1 | RowPin2 | RowPin3 | RowPin4 | RowPin5 | RowPin6 | RowPin7); //Setup row driver pins 

    ShiftPort |= OE; 
    RowPort |= RowPin0;    //Drive first row and enable shift registers 

    ShiftPort |= LatchPin;    //Set latch pin high 
    ShiftPort &= ~(ClkPin | DataPin);    //Set ClkPin and DataPin low 
} 

static inline void InitTimers(void) //Function used once to set up the timer 
{ 
    TCCR1B |= 1<<WGM12 | 1<<CS11 | 1<<CS10;  //Start timer1 in CTC mode with prescaler of 64 
    TIMSK |= 1<<OCIE1A;     //Enable compare match interrupt 
    OCR1A = 0x00BB;     //Set compare value for 1 mSec 
    sei();      //Enable global interrupts 
} 

void Shift_Int(u8 shiftData)  //Function used to shift in data 
{ 
    ShiftPort &= ~(LatchPin | ClkPin | DataPin);  //All pins low: LatchPin low signals a write operation 

    for (char i=0; i<8; i++) 
    { 
    ShiftPort &= ~ClkPin;    //Set ClkPin low 

    if (shiftData & (1<<i)) ShiftPort |= DataPin;  //Set DataPin high if current bit is 1 
    else ShiftPort &= ~DataPin;    //Set DataPin low if current bit is 0 

    ShiftPort |= ClkPin;    //Set ClkPin high to increment shift register 
    ShiftPort &= ~DataPin;    //Set DataPin low to prepare for next write 
    } 

    ShiftPort |= LatchPin;    //Set LatchPin high to signal end of write operation 
    ShiftPort &= ~(ClkPin | DataPin);    //Reset ClkPin and DataPin to low 
} 

void Write_Char(u8 pattern)  //Function that writes one pattern to the LED Matrix 
{ 
    //Writes a char to the led matrix 
    //Patterns come from font8x8[] in progmem (font8x8.h) 
    pattern -= 32;       
    char temp; 
    for (char i=0; i<8; i++)    //Read one column of char at a time 
    { 
    temp = pgm_read_byte((char *)((int)font8x8 + (8 * pattern) + i)); //Get column from progmem 
    for (char j=0; j<8; j++)      //Cycle through each bit in column 
    { 
     //Write bits to appropriate row_buffer location 
     if (temp & (1<<j)) row_buffer[8-j] |= 1<<(8-i); 
     else row_buffer[8-j] &= ~(1<<(8-i)); 
    } 
    } 
} 

int main(void) 
{ 
    InitPorts(); 
    InitTimers(); 
    while(1) 
    { 
     for (char x = 0; x<255; x++) 
     { 
      Write_Char(x); 
      Delay_ms(500); 
     } 

    } 
} 

ISR(TIMER1_COMPA_vect)    //Interrupt Service Routine handles the display. 
{ 
    if(++row_track == 8) row_track = 0;  //Row tracking 
    Shift_Int(row_buffer[row_track]);  //Shift in data for next row 

    ShiftPort &= ~OE;    //Used to prevent ghosting 
    if (row_track == 0)    //Shut down high side controller 
    { 
    RowPort &= ~(1<<7);    //If Row0 is next, shutdown Row7 
    } 
    else 
    { 
    RowPort &= ~(1<<(row_track-1));  //Shutdown previous row 
    } 

    ShiftPort |= LatchPin;   //Latch low side shift registers 
    RowPort |= (1<<row_track);   //Drive high side controller 
    ShiftPort |= OE;    //Used to prevent ghosting 
} 
+2

你有没有设法缩小这或多个例行程序很可能是错误的?这是一大堆代码尝试调试,而无需访问硬件来显示正在发生的事情...... – sarnold

+0

我认为问题出现在Write_Char例程中。 –

回答

2

好像你应该能够只是更改此代码:

//Write bits to appropriate row_buffer location 
    if (temp & (1<<j)) row_buffer[8-j] |= 1<<(8-i); 
    else row_buffer[8-j] &= ~(1<<(8-i)); 

也许这只是猜测:

//Write bits to appropriate row_buffer location 
    if (temp & (1<<j)) row_buffer[6-j] |= 1<<(7-i); 
    else row_buffer[6-j] &= ~(1<<(7-i)); 

将8的值更改为6,对于行将8更改为7,对于列将8更改为7。有可能你可能不得不把这些循环弄乱,所以你最终不会写出界限内存,但这就是它看起来像设置像素的地方,所以只要看看什么改变了行和列的数字就可以了。应该能够弄清楚如何居中。

+0

感谢您的帮助。我尝试改变为6和7,并且抵消了太多,所以我做了7个,现在它的中心和完美的工作。再次感谢。 –