Hallo,
Ik ben mezelf aan het verdiepen in het gebruik van Shift-registers. Nu heb ik verschillende voorbeeld code's gevonden op internet gevonden en ben daarmee aan het proberen gegaan. Ik heb de shift register hiermee werkend gehad. Deze zit gekoppeld aan een Atmega 8.
Nu heb ik een stuk code gevonden wat ideaal voor mij zou zijn. Hier kan ik voldoende mee uitbreiden met het project wat ik graag zou willen maken. Helaas krijg ik deze niet werkend.
Wanneer ik het programma in de Atmega laad, dan gaan er willekeurig wat leds aan die aan het shift-register zitten gekoppeld.
Hieronder heb ik de code geplaatst. Is er iemand die mij hierin zou kunnen helpen?
Alvast bedankt!
#include <avr/io.h>
#include <util/delay.h>
#define number_of_74hc595s 1 //How many of the shift registers are there daisey chained?
int main(){
DDRC = 0xFF;
PORTC = 0x00;
char counter = 0;
while(1){
counter++; // Counter used for displaying a number in binary via the shift register
shift(PC2, PC1, PC0, counter); // PC2 = SERCLK - SH_CP PC1 = RCLK - ST_CP PC0 = SER - DS
_delay_ms(1000);
shift(PC2, PC1, PC0, 0x00); // Set all pins to off
_delay_ms(1000);
}
return 0;
}
void shift(int SRCLK_Pin, int RCLK_Pin, int SER_Pin, unsigned long data){
PORTC &= ~(1 << RCLK_Pin); // Set the register-clock pin low
for (int i = 0; i < (8 * number_of_74hc595s); i++){ // Now we are entering the loop to shift out 8+ bits
PORTC &= ~(1 << SRCLK_Pin); // Set the serial-clock pin low
PORTC |= (((data&(0x01<<i))>>i) << SER_Pin ); // Go through each bit of data and output it
PORTC |= (1 << SRCLK_Pin); // Set the serial-clock pin high
PORTC &= ~(((data&(0x01<<i))>>i) << SER_Pin ); // Set the datapin low again
}
PORTC |= (1 << RCLK_Pin); // Set the register-clock pin high to update the output of the shift-register
}flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Da's het nadeel als je klakkeloos een stuk code copieert. Als er dan maar iets niet klopt, zit je gelijk vast. Probeer eerst eens te bepalen wat er moet gebeuren om bits in het register te shiften. Als je dat snapt, dan klop je de code in 5 minuten zelf even in.
[edit] zeker willen we je hier helpen 
Ik begrijp hoe een shift register werkt. Mijn C-kennis loopt niet zo ver, daarom vraag ik hulp om hier achter te komen.
Hopelijk willen jullie mij helpen?
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Op het eerste zicht lijkt de code OK.
Als er lange draden tusse AVR en schuifregister zitten, zou ik wel kleine vertragingen tussen de stappen van shift() inlassen.
Enne, je hebt de OE- en de RESET-pinnen van het schuifregister toch aangesloten?
Nee, ik heb hem op een breadboard aangesloten waardoor de draden kort zijn. Alles is aangesloten zoals het hoort. Ik heb er net vertragingen tussen gezet, maar dit heeft geen invloed.
Een andere code van internet heb ik geprobeerd, deze werkt wel. Daarom lijkt het me niet in de hardware te zitten, maar softwarematig.
Ik kan de code een heel eind begrijpen, daarom snap ik ook niet dat het niet werkt.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Verander "char counter = 0;" eens in "unsigned char counter = 0;"
En roep de shift-functie aan met "shift(PC2, PC1, PC0, (unsigned long)counter);"
Ik heb het geprobeerd en dit werkt!
''Unsigned char counter = 0'', dit is niet nodig, unsigned mag hier weggelaten worden. (Unsigned long) moet wel toegevoegd worden om het te laten werken.
De reden snap ik niet. Zou je dit kunnen verklaren?
GJ_, een simpele vermenigvuldiging met 2, wat bedoel je hiermee?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Het hangt een beetje van de uitwerking door de compiler af...
Als die de vermenigvuldiging werkelijk uitvoert, kost dit veel meer processortijd als een shift. (shift is een directe instructie)
Sommige compilers zijn intelligent genoeg om van een vermenigvuldiging met 2 zelf een shift left te maken...
Op 3 februari 2013 13:44:37 schreef Martijn222:
GJ_, een simpele vermenigvuldiging met 2, wat bedoel je hiermee?
Ehhh, dan schuiven alle bitjes 1 plaats op.
Op 3 februari 2013 13:47:12 schreef Arco:..kost dit veel meer processortijd als een shift..
Lekker belangrijk, in dit geval. Met een delay van 1000ms er achteraan 
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Ik maak er een gewoonte van, om de compiler heel precies te vertellen hoe hij met 8- 16- en 32-bits variabelen moet omgaan. Dus:
unsigned long tmp;
tmp = ADC * 11000; // NIET zo
tmp = (unsigned long)(ADC) * 11000UL; // maar ZO
Doe je dat niet, dan moet je niet verbaasd zijn als de compiler net dat doet, wat je niet wil...
Beetje vreemd dat het uberhaupt compileert. Heb het hier geprobeerd, en de compiler protesteert:
-- "Warning : conflicting types for shift"
In je main is counter een char dwz 8 bit.
en de shift functie is dan nog niet gecompileerd, die komt pas later..
Dan neemt de compiler default een 16-bit parameter waarschijnlijk, dus de char counter wordt als 2 bytes in de Avr registers gezet.
Maar later blijkt dat de procedure een unsigned long verwacht, dwz een 4-byte parameter. Dus die gebruikt meer registers dan er daadwerkelijk zijn ingevuld --> random results.
Kun je oplossen door de volgorde te veranderen. Als je de shift funktie boven de main funktie zet dan weet de compiler dat die procedure een unsigned long verwacht.
Kun je ook oplossen door bovenaan in je programma een prototype van de shift funktie te plaatsen (let op de puntkomma):
void shift(int SRCLK_Pin, int RCLK_Pin, int SER_Pin, unsigned long data);
Trouwens:
Het is ook niet zo verstandig om een int te gebruiken voor de bitnummers. Dan moet de compiler veel grotere getallen doorgeven dan nodig is. Voor AVR worden dat 16-bit getallen, terwijl een enkele byte hier ruimschoots volstaat. In dit geval heb je al 3 ints als parameters doorgegeven. Dan kom je in de buurt van het maximum dat via registers kan worden doorgegeven, en dan gaan de rest van de parameters via de stack. Is normaal allemaal niet zo een probleem, maar hier gaat het mis doordat het type van de parameters in je main anders is dan het type in de shift functie.