November 26, 2011
by SirHobbes3
|
Okay let me rephrase that, i did the ledarray educational code and flashed it to the mcu no problem, but when i plug it in , only 4 colummns light up(maybe 5), and there is a colummn in between them, so it's like this(cl=lit colummn, nl=not lit colummn) cl, nl, cl,nl, cl,nl,cl,nl,cl?,nl,nl,nl...... So i don't know what exactly to do here.
If it helps, here is the code...
// ledarray.c
// for NerdKits with ATmega168
// Austin Moss
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/uart.h"
#include "font.h"
// PIN DEFINITIONS:
//
// PB1-5 ROW DRIVERS (0-4)
// PC0-5,PD2-7: COLUMN DRIVERS (0-11)
#define F_CPU 14745600
#define ROWS 5
#define COLS 24
volatile uint8_t la_row, real_row;
volatile uint8_t la_data[COLS];
inline uint8_t ledarray_get(uint8_t i, uint8_t j) {
if(i < ROWS && j < COLS) {
if((la_data[j] & (1<<i)) != 0) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
inline void ledarray_set(uint8_t i, uint8_t j, uint8_t onoff) {
if(i < ROWS && j < COLS) {
if(onoff) {
la_data[j] |= (1<<i);
} else {
la_data[j] &= ~(1<<i);
}
}
}
//sense variable indicates direction of LED: sense == 1 indicates COL wire must be
//hight for LED to turn on. sense == 0, COL wire must be low to turn LED on
inline void ledarray_set_columndriver(uint8_t j, uint8_t onoff, uint8_t sense) {
// cols 0-5: PC0-5
// cols 6-11: PD2-7
if(j < 6) {
if(onoff){ //led on
DDRC |= (1 << (PC0 + j));
if(sense) {
PORTC |= (1 << (PC0 + j));
} else {
PORTC &= ~(1<< (PC0 + j));
}
} else { // led off, pins to high impedance
DDRC &= ~(1 << (PC0 + j));
PORTC &= ~(1 << (PC0 + j));
}
} else {
if (onoff){ //led on
DDRD |= (1 << (PD2 + j));
if (sense) {
PORTD |= (1 << (PD2 + j));
} else {
PORTD &= ~(1 << (PD2 + j));
}
} else { //led off, ping in high impedance
DDRC &= ~(1 << (PD2 +j));
DDRC &= ~(1 << (PD2 +j));
}
}
}
inline void ledarray_all_off() {
// turn off all row drivers
DDRB &= ~( (1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5) );
PORTB &= ~( (1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5) );
// turn off all column drivers
DDRC &= ~( (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) );
PORTC &= ~( (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) );
DDRD &= ~( (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7) );
PORTD &= ~( (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7) );
}
SIGNAL(SIG_OVERFLOW0) {
// turn off old row driver
DDRB &= ~(1 << (PB1 + real_row));
PORTB &= ~(1 << (PB1 + real_row));
ledarray_all_off();
// increment row number
if(++la_row == 2*ROWS)
la_row = 0;
// set column drivers appropriately
uint8_t j;
if(la_row%2 == 0) {
// even la_row number: fill even columns
real_row = la_row / 2;
for(j=0; j<COLS/2; j++) {
ledarray_set_columndriver(j, ledarray_get(real_row, 2*j), 1);
}
// activate row driver SINK
PORTB &= ~(1 << (PB1 + real_row));
DDRB |= (1 << (PB1 + real_row));
} else {
// odd la_row number: fill odd columns
real_row= (la_row-1)/ 2;
for(j=0; j<COLS/2; j++) {
ledarray_set_columndriver(j, ledarray_get(real_row, 2*j + 1), 0);
}
// activate row driver SOURCE
PORTB |= ~(1 << (PB1 + real_row));
DDRB |= (1 << (PB1 + real_row));
}
}
void ledarray_init() {
// Timer0 CK/64 (900Hz)
TCCR0B = (1<<CS01) | (1<<CS00);
TIMSK0 = (1<<TOIE0);
// outputs (set row drivers low for off)
DDRC &= ~( (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) );
DDRD &= ~( (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7) );
DDRB &= ~( (1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5) );
}
void ledarray_left_shift() {
// shift everything one position left
uint8_t i, j;
for(i=0; i<ROWS; i++) {
for(j=0; j<COLS-1; j++) {
ledarray_set(i,j, ledarray_get(i, j+1));
}
}
}
void ledarray_blank() {
uint8_t i, j;
for(i=0; i<ROWS; i++) {
for(j=0; j<COLS; j++) {
ledarray_set(i,j,0);
}
}
}
void ledarray_testpattern() {
uint8_t i, j;
ledarray_blank();
for(i=0;i<ROWS;i++) {
for(j=0;j<COLS;j++) {
ledarray_set(i,j, 1 - ledarray_get(i,j));
delay_ms(30);
}
}
for(i=0;i<ROWS;i++) {
for(j=0;j<COLS;j++) {
ledarray_set(i,j, 1 - ledarray_get(i,j));
delay_ms(30);
}
}
}
void font_get(char match, char *buf) {
// copies the character "match" into the buffer
uint8_t i;
PGM_P p;
for(i=0; i<FONT_SIZE; i++) {
memcpy_P(&p, &font[i], sizeof(PGM_P));
if(memcmp_P(&match, p,1)==0) {
memcpy_P(buf, p, 7);
return;
}
}
// NO MATCH?
font_get('?', buf);
}
uint8_t font_width(char c) {
char buf[7];
buf[1] = 0;
font_get(c, buf);
return buf[1];
}
void font_display(char c, uint8_t offset) {
char buf[7];
font_get(c, buf);
uint8_t width = buf[1];
uint8_t i, j;
for(i=0; i<ROWS; i++) {
for(j=0; j<width; j++) {
if((offset + j) < COLS) {
// set the row of led_array at the right offset.
if( (buf[2+j] & (1<<i)) != 0) {
ledarray_set(i,offset + j,1);
} else {
ledarray_set(i,offset + j,0);
}
}
}
}
// blank the next column to the right
for(i=0; i<ROWS; i++) {
ledarray_set(i, offset+width, 0);
}
}
void do_scrolling_display() {
ledarray_blank();
int8_t offset = 0, next_offset = 0;
uint8_t is_started = 0;
char x=' ';
while(1) {
if(is_started) {
delay_ms(125);
ledarray_left_shift();
if(next_offset > 0) {
offset -= 1;
next_offset -= 1;
} else {
is_started = 0;
}
font_display(x, offset);
} else {
offset = COLS-1;
}
// if we can now accept a new character, tell the computer
if(next_offset == COLS)
uart_write('n');
while(uart_char_is_waiting()) {
if(is_started)
offset = next_offset;
x = uart_read();
if(x=='a') {
ledarray_blank();
return;
}
font_display(x, offset);
next_offset = offset + font_width(x)+1;
is_started = 1;
// if we can now accept a new character, tell the computer
if(next_offset <= COLS)
uart_write('n');
}
}
}
void do_simple_display() {
ledarray_blank();
uint8_t offset = 0;
char x = ' ';
while(1){
x = uart_read();
if(x == 'z'){
ledarray_blank();
offset = 0;
} else {
//fill in code to render character here
}
}
}
int main() {
ledarray_init();
// activate interrupts
sei();
// init serial port
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
stdin = stdout = &uart_stream;
uint8_t i, j;
while(1)
for(i=0;i<ROWS;i++) {
for(j=0;j<COLS;j++) {
ledarray_set(i,j, 1);
delay_ms(30);
}
}
for(i=0;i<ROWS;i++) {
for(j=0;COLS;j++) {
ledarray_set(i, j, 0);
delay_ms(30);
}
}
}
//do_simple_display();
//do_scrollint_display();
|