No blahozelam
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
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.