Ik ben bezig met 'n programma voor m'n laatsteproject: het aansturing van een rgbdotmatrix. Alle leds zitten aangesloten op de schuifregisters: 74hc595
Het werkt helemaal perfect, behalve de snelheid. Ipv PWM knipperen mijn leds zichtbaar.
Nu weet ik dat jullie absoluut geen zin hebben in een lap code, maar hier komt die toch:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
// Lagen definieëren
#define L0 PD0
#define L1 PD1
#define L2 PD2
#define L3 PD3
#define L4 PD4
#define L5 PD5
#define L6 PD6
#define L7 PD7
// Schuifregisters definieëren
#define SR_DAT PC1
#define SR_CLK PC0
#define SR_LAT PC2
#define SR_MR PC3
#define SR_OE PC4
//leds definieëren
char l11=10;
char l12=50;
char l13=100;
char l14=170;
char l15=250;
char l16=190;
char l17=115;
char l18=8;
void setshift(char RED,char GREEN,char BLUE) {
PORTC&=~(1<<SR_LAT);
char x;
for (x=0; x<8; x++) {
if ((GREEN & 0x80) == 0x80) { // een '1'
PORTC|=(1<<SR_DAT);
} else {
PORTC&=~(1<<SR_DAT);
}
GREEN = GREEN << 1;
PORTC|=(1<<SR_CLK);
_delay_us(6);
PORTC&=~(1<<SR_CLK);
_delay_us(6);
}
for (x=0; x<8; x++) {
if ((RED & 0x80) == 0x80) { // een '1'
PORTC|=(1<<SR_DAT);
} else {
PORTC&=~(1<<SR_DAT);
}
RED = RED << 1;
PORTC|=(1<<SR_CLK);
_delay_us(6);
PORTC&=~(1<<SR_CLK);
_delay_us(6);
}
for (x=0; x<8; x++) {
if ((BLUE & 0x80) == 0x80) { // een '1'
PORTC|=(1<<SR_DAT);
} else {
PORTC&=~(1<<SR_DAT);
}
BLUE = BLUE << 1;
PORTC|=(1<<SR_CLK);
_delay_us(6);
PORTC&=~(1<<SR_CLK);
_delay_us(6);
}
PORTC|=(1<<SR_LAT);
}
int main(void) {
//richting aangeven
DDRD=0xff;
DDRC=0xff;
PORTC&=~(1<<SR_OE);
PORTC|=(1<<SR_MR);
unsigned char timer;
char shiftreg;
PORTD|=(1<<L0);
PORTD|=(1<<L1);
PORTD|=(1<<L2);
PORTD|=(1<<L3);
PORTD|=(1<<L4);
PORTD|=(1<<L5);
PORTD|=(1<<L6);
PORTD|=(1<<L7);
PORTD&=~(1<<L3);
while(1) {
for(timer=0; timer<250; timer++) {
shiftreg=0;
if(l11<timer) {
shiftreg = shiftreg+1;
}
if(l12<timer) {
shiftreg = shiftreg+2;
}
if(l13<timer) {
shiftreg = shiftreg+4;
}
if(l14<timer) {
shiftreg = shiftreg+8;
}
if(l15<timer) {
shiftreg = shiftreg+16;
}
if(l16<timer) {
shiftreg = shiftreg+32;
}
if(l17<timer) {
shiftreg = shiftreg+64;
}
if(l18<timer) {
shiftreg = shiftreg+128;
}
setshift(0,shiftreg,0);
}
}
return 0;
}
Dit programma is gemaakt voor het aansturen van de 3, aan elkaar doorgelinkte, schuifregister en laat maar 1 rij branden in maar 1 kleur op het display, maar deze dus met meerdere mogelijke 'grijstinten'
Ik heb ook al een andere kristal gebruikt. Het geheel zit trouwens aangesloten op een atmega8-16mhz versie
Ik denk zelf dat de functie setshift te traag is maar dat zou eigenlijk niet moeten kunnen.
Ziet iemand de reden waarom het zo traag gaat?
Tommyboy
Zo goed als het vroeger was, is het nooit geweest.
Ik zat er net naar te kijken in de datasheet.
Die fuses heb ik dus niet ingesteld. Even kijken hoe dat moet 
-edit-
Hmm kan ik deze ook instellen in avr studio of moet dat in de programmer?
-edit2-
Met het programma quickprog een 'externen quatz' geactiveerd.. Het gaat nu wel sneller, maar het knippers nog steeds
-edit3-
Delay's allemaal weggehaald en gewoon een simpele monocolor greyscale regalaar (loopt automatisch op).
Het PWM-t nu in ieder geval, maar volgens mij nog heel traag... Maar dat is voor morgen!
[Bericht gewijzigd door ken536 op (24%)]
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Sommige AVR's (ATmega88, ATtiny2313, ...) hebben de mogelijkheid om hun klok door 8 te delen. Dat is dan meestal de fabrieks-configuratie.
Op volle toeren draaien kan dan op 2 manieren:
Het CKDIV8-fusebit deactiveren.
Dit stukje code in main() plaatsen:
CLKPR = (1 << CLKPCE);
CLKPR = 0; // Set max. system-clk
Ik heb perongelijk nu de fuse bits naar external, low frequentie kristal gezet.. Nu doet het allemaal helemaal niks meer en ik kan het ook niet meer programmeren
Hoe kan ik het weer terug krijgen?
Marcel
AVR C tutorial http://expand.xs4all.nl/avr
Dan heb je nu direct geleerd heel zorgvuldig te zijn met het setten/resetten van fuse bits. Sluit extern een low-frequency kristal aan (zie datasheet hoeveel dat precies is) en je kan weer programmeren. Een programmer die parallel programmeert (STK500) is ook een optie omdat die zijn eigen programmeer clock aanbied.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Misschien eens in de rommeldoos zoeken naar een horlogekristal? Weet niet of het werkt, maar proberen kan geen kwaad, dunkt me.
Belangrijk in dit geval, is het feit dat de programmer-software moet weten dat de AVR op lage snelheid draait. Bij avrdude volstaat het "-i 1000" (of desnoods "-i 100000") als extra-argument op te geven.
Voor de snelheid gewoon even de avr zelf veranderd. Besteld wel een keer een 32k... kristal mee om hem weer op te lappen..
(als die nog leeft na het desolderen in ieder geval)
Marcel
AVR C tutorial http://expand.xs4all.nl/avr
Als je dan toch bezig bent, zet er een voetje in de plaats. Mocht er ooit nog weer iets gebeuren, dan kan je de AVR eenvoudig vervangen. Ik zet IC's bijna altijd in een voetje. Het gaat bijna nooit mis, maar als het dan toch mis gaat is het zo makkelijk.
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
je probleem is dagt je 3 afzonderlijke loops hebt ....
terwijl 1 loop draait slapen de andere 2 ... vandaar dat de boel 'knippert'
merge je code in 1 loop.
( je hebt nu 3 for-next constructies ) terwijl de for-next voor rood draait slapen groen en blauw....
en dan zijn die leds af ...
dus : 1 for next maken waarbinnn alles draait.
zal al een flink stum minder knipperen en je haalt bijna 3x snelheids winst..
Voetjes is een beetje moeilijk met tqfp 
En de loops lopen niet afzonderlijk maar gelijk. Ik laat nu gelijk het doorschuiven van de data in de loop gebeuren en ik heb de 'bithoogtje' veranders van 8 (255) naar 5(32). Hierhoor kan ik nog >32000 kleuren maken, wat meer dan genoeg is.
Hardware pwm heb ik nu inderdaad lang niet genoeg aan..