Schieberegister mit Pic ansteuern

OP #2972264
Lesenswert?

hallo miteinander

ich wollte mit hilfe von MPLABX und dem XC8 compiler meinen Pic16f877a 
dazu bringen, dass das Schieberegister ein einfaches muster herausgibt. 
an den Q's des Schieberegister sind  LED's angeschlossen.
den uC programmiere ich über den Brenner 8P von Sprut via ICSP.
das programm ist ziemlich einfach in C realisiert. Wenn der uC auf run 
ist scheint das SR wie tot. wenn der uC auf stop ist ( um ein Programm 
rüberzuladen) flackern alle led's unontrolliert. das wäre mir noch egal 
aber sobald er auf run geht sollte sich das SR füllen und mein gewähltes 
muster ausgeben. Ihr könnt mir sicher helfen. im anhang befindet sich 
ein photo und das schema.

das programm sieht so aus.

/** I N C L U D E S *******************************************/
#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
#include <pic.h>

// PIC16F877A Configuration Bit Settings

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT 
oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT 
disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT 
disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR 
enabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) 
In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; 
low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection 
bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable 
bits (Write protection off; all program memory may be written to by 
EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Prot


#ifndef _XTAL_FREQ
#define _XTAL_F REQ 4000000L // (4mhz)
#endif

#define clk RA1
#define data RA0

void clock(void);

/** H A U P T P R O G R A M M *********************************/
void main(void)
{
/** D E F I N E S *********************************************/
    TRISD = 0x00;
    TRISA = 0x00;



  while(1) {          //Hauptschleife
            data =1;
            clock();
            data =0;
            clock();
             data =1;
            clock();
            data =0;
            clock();
             data =1;
            clock();
            data =0;
            clock();
             data =1;
            clock();
            data =0;
            clock();
  }
}


void clock(void)
{
    clk=0;
    NOP();
    clk=1;
   NOP();
    clk=0;
}
Angehängte Dateien:
#2972303
Lesenswert?

Und zur Not kann man immer noch nach jedem clock() (oder besser gleich 
in der Funktion) noch eine zusätzliche Wartezeit von sagen wir mal 2 
Sekunden einlegen. Das hat dann den Vorteil, dass man an die beiden 
µC-Pins noch zusätzliche LED anhängen kann und mithilfe der LED sehen 
kann, ob und wenn ja was sich an den beiden Pins tut.

Dem Schieberegister ists wurscht wie langsam du taktest.


Blöde Frage. Aber du hast schon kontrolliert, ob dein µC grundsätzlich 
läuft? So mit einfach nur eine LEd an einen Portpin hängen und die 
gezielt ein/aus schalten bzw. auch mal blinken lassen.
Gast #2972308
Lesenswert?

Schau mal ob die nicht besser die analogen Eingange abschaltest 
(ANSELx)? Die sind m.W. und aus guten Gründen nach dem Reset 
bevorrechtigt. Gilt aber wohl nur für Eingänge.

Das nächste sind die Fuse bits. Reicht es das du deinem compiler das 
pragma übergibst oder programmiert der die extra?

und wo sit eigentlich der Quartz Oszillator nebst Zubehör vom Schaltplan 
auf dem Steckbrett? Wenn das so aufgebaut ist wie der rest wird das 
vielelicht nicht anschwingen. Besser vielleicht erstmal einen PIC mit 
internen OSC zu nehmen.
Gast #2972335
Lesenswert?

danilo S. schrieb:
> SR habe ich schon mehrmals ausgetauscht.

Mach das ganze langsamer. Dein clock aus Nops ist bei den Leitungslängen 
und der Verdrahtung dann doch arg kurz.

Karl Heinz Buchegger schrieb:
> Blöde Frage. Aber du hast schon kontrolliert, ob dein µC grundsätzlich
> läuft? So mit einfach nur eine LEd an einen Portpin hängen und die
> gezielt ein/aus schalten bzw. auch mal blinken lassen.

Die Frage ist sehr naheliegend, würde ich als erstes mal testen.
OP #2973039
Lesenswert?

Ich habe zwei neue ausgänge genommen. RD3 und RD2(unten rechts am uC)
wenn ich nun zwei led's anhänge blinken die genau so wie ich will. D.h 
am anschluss Data und CLK des SR kommt alles richtige an. aber ich will 
ja ein muster ausgeben.  mit diesem programm soll ja die eine LED 
leuchten und die nächste nicht usw. aber bei mir leuchtet die erste geht 
weiter zur nächsten und so weiter bis sie an Q7 angekommen ist, und dann 
scheint das SR wie tot, obwohl es in einer endlosschleife ist.
Gast #2973256
Lesenswert?

Ich kann dir ein Beispiel zeigen aber in anderer Sprache.
1
-- pin defines
2
-- Any other  I/O pin could be used  
3
var volatile bit  CLK  is  pin_b0      -- Clock pin3
4
var volatile bit  D  is  pin_b1        -- Data pin2
5
var volatile bit  STR  is  pin_b2      -- Strobe pin1
6
var volatile bit  OE  is  pin_b3      -- Output Enable pin15
7

8
var volatile bit CLK_dir is pin_b0_direction
9
var volatile bit D_dir is pin_b1_direction
10
var volatile bit STR_dir is pin_b2_direction
11
var volatile bit OE_dir  is pin_b3_direction
12

13
  CLK_dir = output
14
  D_dir = output
15
  STR_dir = output
16
  OE_dir = output
17

18
-- load a byte into the '4094
19
procedure 4094_send(byte in ib) is
20
  var byte stemp
21
  stemp = ib
22
  OE = low
23
  STR = low
24
  for 8 loop
25
    D = low
26
    if ((stemp & 128) != 0) then
27
    D = high
28
    end if
29
    CLK = high
30
    asm nop
31
    CLK = low
32
    stemp = stemp << 1
33
  end loop
34
   OE = high
35
   STR = high
36

37
end procedure
Gast #2973333
Lesenswert?

Nach main solltest du sowas haben:

CMCON |=7;  // disable comparators
ADCON1 = 6; // disable adc

weiters wäre es nicht schlecht, die nop() durch dly() zu ersetzten,
zumindest für den Debug.
#define dly() clk4(62) // ca 4HZ bei optimierenden Compiler.

void clk4(unsigned char count) { do CLRWDT(); while(count--); }

Dann kannst du auch mittels einer Led + Widerstand die Impulse 
verifizieren,
und bei Bedarf schneller werden.
oder für deinen Aufbau zumindest clk4(0) anstelle clk4(62) .
Eventuell kannst du immer noch ein
#define dly() NOP()
machen, für den Endgültigen Code.

Und natürlich nach dem letzten clock() ein clk4(250) machen, für ca 
1Sek.
Ansonsten zappelt es immer, da du mit 400khz deine Daten kontinuierlich 
reinschiebst und die Leds dann nie zum Stillstand kommen und einfach nur 
flackern.
Gast #2973414
Lesenswert?

Ansonsten, in C solltest du eher sowas machen:


void ShiftOut(unsigned char value)
{
    unsigned char cnt=8;
    do {
        clk=0;
        dat=value&1;
        value>>=1;
        clk=1;
   } while(--cnt);
}


und in main nach dem Init anstelle des while:

  ShiftOut(0xAA);
  for(;;);


So wird ca alle 9ms das bitpattern 10101010 ausgegeben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren