32x32 Matrix z číny a Atmega8

No blahozelam :slight_smile:

Uz sa v tom da na prvy pohlad vyznat.
Napriklad je vidiet, ze program zbehne len raz a potom opustis pomocou retur(0) funkciu main a kde to to skonci ako v kremikovom nebi nevedia :slight_smile:
Ak uz si napisal nekonecnu slucku s while(1), co je spravne,

potom miesto return(0), lebo totam fakt nema co robit, radsej vloz nejaky _delay_us aby medzi SET_LAT a naslednym RES_LAT prebehol nejaky cas.

Potom je vidiet, ze mas chaos v nastaveni smeru IO pinov. Ako chces aby sa na fyzickom vystupe CLK a LAT menila hodnota log.1 a log.0, ked tento pin bezostisne nastavujes ako vstupny?
Tomu sa uplne vyhni takym tym globalnym zapisom typu:

#define PORTD_RES (PORTD = 0x00);
#define PORTC_RES (PORTC = 0x00);
#define PORTB_RES (PORTB = 0x00);



int main(){
DDRD = 0xFF;
DDRC = 0xFF;
DDRB = 0x10;
 /...

   else {
         PORTD_RES;
         PORTC_RES;
   };
 
/ ...

To je tiez sucastou bordelu v programe, ktory sa Ti aj hned prejavuje.
Vobec sa neboj pracovat s kazdym bitom osve. Program to prakticky nepredlzi ani casovo a ani kodovo. Na tych par bajtov sa mozes kludne z vysoka …

#define __DELAY_BACKWARD_COMPATIBLE__
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define R0 PD0
#define G0 PD1
#define R0_OUT (DDRBD |= 1<<PD0);
#define R0_SET (PORTD |= 1<<PD0);
#define R0_RES (PORTD &= ~(1<<PD0));
#define G0_OUT (DDRBD |= 1<<PD1);
#define G0_SET (PORTD |= 1<<PD1);
#define G0_RES (PORTD &= ~(1<<PD1));
// ...

#define CLK_OUT (DDRB |= 1<<PB0);
#define CLK_SET (PORTB |= 1<<PB0);
#define CLK_RES (PORTB &= ~(1<<PB0));
// ... 

#define LAT_OUT (PORTB |= 1<<PB2);
#define LAT_SET (PORTB |= 1<<PB2);
#define LAT_RES (PORTB &= ~(1<<PB2));


int main(){
/* uplne nafigu zapis a aj sa Ti to vypomstieva
DDRD = 0xFF;
DDRC = 0xFF;
DDRB = 0x10;
*/
// miesto toho

LAT_OUT;
R0_OUT;
G0_OUT;
CLK_OUT;
   
   while(1){ 
      LAT_RES;
      for (int i = 0; i<32; i++){  //projeď všechny sloupce
         if (i==0){   //pokud se jedna o prvni sloupec
            R0_SET; //nastav R0 a G0 na true
            G0_SET;
         }
         else {
/* Tento zapis je vhodny len za urcitych okolnosti. 
// teraz by som vsak pouzil pre testovanie nieco jednojednoznacne
// a nazornejsie aby sa moznost chyb minimalizovalo.
            PORTD_RES;
            PORTC_RES;
*/
            R0_RES; //nastav R0 a G0 na nulu
            G0_RES;

// alebo ked uz chces silou mocou setrit na par bajtoch programu, 
// tak zapis, ale este sa aj tak budes mylit,
// ci je dany pin naozaj na tom porte. 
// Nedajboze budes menit hw a tak budes taketo zbytocnosti opravovat v celom programe. 
// Preto je potrebne pisat kod tak, aby si zmeny bitov a portov urcoval
// iba raz na zaciatku programu alebo v prislusnom headri.

            PORTD &= ~((1<<R0) + (1<<G0));
         }
   
         _delay_us(5); //pockej 5 mikrosekund jelikož mají být data dřív než dojde ke clocku
   
         CLK_SET;
         _delay_us(495); //nyni je CLK na high a data jsou posilany do registrů
         CLK_RES;
         _delay_us(500); //clc na low
      }
      LAT_SET;  //všechny data by měli být v shift registrech tudíž nastavuju LAT na high
      _delay_us(500); 
   }
} 

A davaj si velky pozor na odsadzovanie zatvoriek a vnoreni. Vyhnes sa chybam a lahsie sa to po Tebe bude citat inym.