我创建了一个8x8 LED矩阵,由一个微控制器(特别是Atmega8),一个8位移位寄存器(HEF4794)和一个驱动器阵列(MIC2981)控制。我遇到的问题是应该显示的模式不居中。它需要向左移动一列并向下移动两行。任何帮助将不胜感激。
我从这里得到了这个项目的想法: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
}
答案 0 :(得分: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位。有可能你可能不得不乱用循环,所以你不会写到超出范围内存,但这就是它设置像素的地方,所以只看看改变行和列数做什么和你应该能够弄清楚如何使它居中。