This information was partially found at http://gathering.tweakers.net/forum/list_message/29939964#29939964
more discussion on http://www.circuitsonline.net/forum/view/60243/1/dot+matrix+baco
J1: data input
J2: data output (for connecting a second board → this will effectually make one large shift register per row. Connecting two boards yields horizontal shift registers of 64 bits.
| nc | 15 | 16 | GND |
| LDAT | 13 | 14 | GND |
| nc | 11 | 12 | GND |
| UDAT | 9 | 10 | GND |
| A2 | 7 | 8 | GND |
| A1 | 5 | 6 | /OE |
| A0 | 3 | 4 | STROBE |
| CLK | 1 | 2 | GND |
Bovenste helft en onderste helft hebben aparte data ingangen (LDAT en UDAT)
while(1) {
for y=0 to 8 {
for x=0 to 32 {
maak LDAT hoog als je op (x,y+8) een pixel wilt weergeven
maak UDAT hoog als je op (x,y) een pixel wilt weergeven
maak CLK laag
maak CLK hoog
}
maak OE hoog (dit zet alle LEDs tijdelijk uit)
maak STROBE laag
maak STROBE hoog
zet [A2..0] naar y
maak OE laag
wacht een tijd, afhankelijk van de gewenste refreshrate
}
}
Is working!
The code is written for WinAVR. Also the AVRlib.zip libraries by Pascal Stang have been used. You can download them from here
//*****************************************************************************
// File Name : main.c
//
// Titel : Display controller
// Revisie : 1.0
//
// Revision History:
// When Who Description of change
// ----------- ----------- -----------------------
// 05-Mrt-2007 e13 generic Mublock Source
// 29-Dec-2008 e13 adapted for display
//*****************************************************************************
//----- Include Files ---------------------------------------------------------
#include <avr/io.h> // include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h> // include interrupt support
#include "global.h" // include our global settings
#include "uart.h" // include uart function library
#include "rprintf.h" // include printf function library
#include "a2d.h" // include A/D converter function library
#include "timer.h" // include timer function library (timing, PWM, etc)
#include "vt100.h" // include VT100 terminal library
#include "pic.h"
#define limit(number,boundary) ( ((number)>(boundary))?(boundary):( ((number)<(-boundary))?(-boundary):(number)) )
#define GRAYINC (1<<3)
#define CLK PC7
#define A0 PC4
#define A1 PC5
#define A2 PC6
#define UDAT PB1
#define LDAT PB0
#define STROBE PB3
#define OE PB2
unsigned char dispmem[512];
void Timer0Overflow(void);
volatile int fastcount;
volatile char hzflag;
void flashGreen(void);
void flashRed(void);
int main(void) // hoofdprogramma
{
int x,y,n;
outb(DDRB,0x0F);
outb(PORTB,0x0F);
outb(PORTA,0xF0); //pullup on 1 and 2
outb(DDRA,0x00);
outb(DDRC,0xF0);
outb(PORTC,0xF0);
// initialize our libraries
// initialize the UART (serial port)
uartInit();
// set the baud rate of the UART for our debug/reporting output
uartSetBaudRate(9600);
// set uartSendByte as the output for all rprintf statements
rprintfInit(uartSendByte);
// initialize the timer system
timerInit();
// initialize vt100 library
vt100Init();
// initialize cmdline system
// turn on and initialize A/D converter
a2dInit();
// set the a2d prescaler (clock division ratio)
// - a lower prescale setting will make the a2d converter go faster
// - a higher setting will make it go slower but the measurements
// will be more accurate
// - other allowed prescale values can be found in a2d.h
a2dSetPrescaler(ADC_PRESCALE_DIV32);
// set the a2d reference
// - the reference is the voltage against which a2d measurements are made
// - other allowed reference values can be found in a2d.h
a2dSetReference(ADC_REFERENCE_AVCC);
// use a2dConvert8bit(channel#) to get an 8bit a2d reading
// use a2dConvert10bit(channel#) to get a 10bit a2d reading
timer0SetPrescaler(TIMER_CLK_DIV8);
TCNT0=0x83; //16000Hz @ 8 - 16MHz
timerAttach(TIMER0OVERFLOW_INT, Timer0Overflow);
for (x=0; x<512; x++) dispmem[x]=picture[x];
sei();
while(1)
{
}
return 0;
}
void Timer0Overflow(void)
{
static char rowno; //number of the row we're at now
static short pos; //position in display memory
static unsigned char comp; //compare-value for grayscales
char x;
TCNT0=0x83; //16000 hz
//Send next line
PORTB&=~(1<<STROBE); //disable strobe in advance
for (x=0; x<32; x++)
{ //for each pixel:
PORTB&=~((1<<UDAT)|(1<<LDAT)); //clear data inputs
PORTC&=~(1<<CLK); //reset clock in advance
if (dispmem[pos]>comp) PORTB|=(1<<UDAT); //if pixel should be shown, set output
if (dispmem[pos+(32*8)]>comp) PORTB|=(1<<LDAT); //same for the lower 8 rows
pos++; //next memory position
PORTC|=(1<<CLK); //clock in the bits
comp+=128; //invert phase of pwm every pixel
}
comp+=128; //invert phase of pwm every row too
PORTB|=(1<<STROBE); //latch in the led values
PORTB|=(1<<OE); //disable led output
//select correct row
PORTC&=~((1<<A0)|(1<<A1)|(1<<A2));
if (rowno&1) PORTC|=(1<<A0);
if (rowno&2) PORTC|=(1<<A1);
if (rowno&4) PORTC|=(1<<A2);
PORTB&=~(1<<OE); //enable led output
rowno++; //Ok, this row is done.
if (rowno>7)
{ //Frame done?
rowno=0; //reset row count
pos=0; //reset memory pos
comp+=128+GRAYINC; //invert phase of pwm and increase
}
}
void flashRed(void){ if (PORTB & 0x01) cbi(PORTB,0); else sbi(PORTB,0);}
void flashGreen(void){ if (PORTB & 0x02) cbi(PORTB,1); else sbi(PORTB,1);}
And ofcourse the image file:
//pic.h
//Size: 32 16
const char picture[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,0,25,0,0,25,0,0,25,25,0,0,25,25,0,0,25,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,25,0,25,0,25,0,25,0,25,0,25,0,25,0,25,0,25,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,25,0,25,25,25,0,25,25,0,0,25,25,0,0,25,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,25,0,25,0,25,0,25,0,25,0,0,0,25,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,0,25,0,25,0,25,0,25,0,0,0,25,0,0,0,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,25,25,0,25,25,25,0,25,0,0,0,25,0,0,25,0,25,0,25,25,25,0,0,25,0,0,25,25,0,0,0,25,0,25,0,25,0,0,0,25,0,0,0,25,0,0,25,0,25,0,25,0,0,0,25,0,25,0,25,0,25,0,0,25,0,25,0,25,25,0,0,25,0,0,0,25,0,0,25,25,25,0,25,25,0,0,25,25,25,0,25,25,0,0,0,25,0,25,0,25,0,0,0,25,0,25,0,25,0,0,0,25,0,0,25,0,0,0,25,0,25,0,25,0,25,0,0,25,0,25,0,25,25,25,0,0,25,0,25,0,0,0,0,25,0,0,25,25,25,0,25,0,25,0,25,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Generated with the following Processing file:
/**
* Pixel Print
*
* Print brightness values for pixels
*/
PImage a;
int[] aPixels;
int direction = 1;
boolean onetime = true;
float signal;
void setup()
{
size(32, 16);
aPixels = new int[width*height];
a = loadImage("test.bmp");
for(int i=0; i<width*height; i++) {
aPixels[i] = a.pixels[i];
print((int)brightness(aPixels[i])/10);
print(',');
}
}
void draw()
{
}