Hilfe bei PIC Programmierung, C Code

OP #4803757
Lesenswert?

Hallo, ich habe ein Problem bei meiner Steuerung (PIC16F628A, 
ULN2803A,LP2950 ACZ5.0). Ich lasse 12 LED´s nacheinander aufleuchten und 
diese gehen nach 250ms aus da die Spannung abfällt. Nun habe ich das 
Problem das die ersten beiden LEDs leicht nach glimmen beim abschalten 
da in den Kondensatoren die meine 12V auf 5V per Festspannungsregler 
runter regeln noch kurz Spannung abgeben. Wie kann ich dies verhindern? 
Hatte mir gedacht am besten kurz vor dem Spannungsabfall per timer im 
Code die LED´s abschalten. Leider bin ich kein experte in C, könnte mir 
da jemand einen Abschalt timer einfügen?
1
#define _XTAL_FREQ 4000000
2

3
#include <xc.h>
4
#include <stdint.h>
5

6

7
// Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT
8
// pin, I/O function on RA7/OSC1/CLKIN)
9
#pragma config FOSC = INTOSCIO 
10
// Watchdog Timer Enable bit (WDT disabled)
11
#pragma config WDTE = OFF   
12
// Power-up Timer Enable bit (PWRT disabled)
13
#pragma config PWRTE = OFF     
14
// RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
15
#pragma config MCLRE = ON      
16
// Brown-out Detect Enable bit (BOD enabled)
17
#pragma config BOREN = ON     
18
// Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function,
19
// HV on MCLR must be used for programming)
20
#pragma config LVP = OFF       
21
// Data EE Memory Code Protection bit (Data memory code protection off)
22
#pragma config CPD = OFF        
23
// Flash Program Memory Code Protection bit (Code protection off)
24
#pragma config CP = OFF      
25

26
void main(void) {
27
    
28
    uint16_t leds = 0;
29
    // Init IOs
30
    TRISA = 0;
31
    TRISB = 0;
32
    PORTA = 0;
33
    PORTB = 0;
34
    
35
    
36
    __delay_ms(81); // Start Verzögerung (Licht Aussen))
37
    
38
    while (1) {
39
        
40
        // Berechnung des LED Blinkmuster
41
        leds = (leds << 1) | 1;
42

43

44
        // Aussgang des LED Blinkmuster an Ports
45
        PORTA = ((leds >> 8) & 0x1F) | ((leds >> 7) & 0xC0);
46
        PORTB = leds & 0xFF;
47
       
48
        __delay_ms(9); // Geschwindigkeit (1LED zu 2LED))
49
    }
50
    
51
    
52
    
53
   
54
    
55
      
56
      
57
}
OP #4803973
Lesenswert?

Hier mein Schaltplan. Aber nochmal zum Programm, wie lautet der befehl 
um die LED´s nach 250 ms abzuschalten? könntet ihr mir da helfen?

Cyborg schrieb:
> Man vollbringt hier ja manchmal Wunder, aber hexen ist leider nicht
> drin.
> Lies mal das und handele danach:
>
> 
http://www.mikrocontroller.net/articles/Netiquette#Klare_Beschreibung_des_Problems
>
> Zu einem Programm gehört auch ein Schaltplan, um zu sehen, was du
> da zusammen gebastelt hast.
Angehängte Dateien:
#4804003
Lesenswert?

Sebastian A. schrieb:
> wie lautet der befehl
> um die LED´s nach 250 ms abzuschalten?
1
PORTA = PORTB = 0;

Versuch erstmal den Ablauf in einzelnen Sequenzen verständlich zu 
beschreiben und am besten sofort in Kommentaren abzufassen.

Das Lauflicht ist eine von mehreren Sequenzen in dem Ablauf, und nach 16 
Schleifendurchläufen fertig. Da du es aber in einer Endlosschleife 
eingeschlossen hast, geht es nach dem Lauflicht nicht mehr weiter. Wenn 
du statt while(1) eine vernünftige Bedingung formulierst, kann's mit 
delays nach dem Lauflicht weiter gehen. Wenn der Ablauf fertig ist und 
der µC nichts mehr zu tun hat, kannst du ihn mit SLEEP(); oder mit 
while(1); in den Feierabend verabschieden.

Gruß
witkatz
#4804006
Lesenswert?

Brich einfach die Endlosschleife nach 250ms ab (Pi*Daumen ca. 25 
Durchläufe).
1
i = 25; // Anzahl Durchläufe
2
while (i) {
3
        
4
        // Berechnung des LED Blinkmuster
5
        leds = (leds << 1) | 1;
6

7

8
        // Aussgang des LED Blinkmuster an Ports
9
        PORTA = ((leds >> 8) & 0x1F) | ((leds >> 7) & 0xC0);
10
        PORTB = leds & 0xFF;
11
       
12
        __delay_ms(9); // Geschwindigkeit (1LED zu 2LED))
13
        i--;
14
    }
15
    PORTA = 0;
16
    PORTB = 0;
OP #4804040
Lesenswert?

Poster schrieb:
> Ist ja ein toller Plan, aber aufgebaut hast du unter Garantie was
> anderes.
> Wo bekommt man 200m Ohm Widerstände zu kaufen? Wie rum beschaltet man
> LEDs?
> Was bringt den momentan die LEDs zum ausschalten?

Widerstände habe ich einfach nur werte in den Schaltplan. Die 
beschaltung der LED´s passt. Meine Platine funktioniert ja soweit.

Die LED´s werden durch das abschalten der Spannung ausgeschalten.
OP #4804953
Lesenswert?

Witkatz :. schrieb:
> Sebastian A. schrieb:
>> Widerstände habe ich einfach nur werte in den Schaltplan.
> Die Werte im Schaltplan sind aber nicht die in der Schaltung. 200m steht
> für 200 Milliohm also 0.2 Ohm
>
>> Die beschaltung der LED´s passt.
> Aber nicht im Schaltplan.
>
>> Meine Platine funktioniert ja soweit.
> Aber du weisst nicht warum. Das ist meistens schlimmer als anders rum.


Die Werte der Widerstände musste ich eh nachträglich ändern auf der 
Fertigen Platine, daher keine echten Werte.

Und die LED´s passen, was ist daran Falsch? Sonst würden sie ja nicht 
Leuchten. Die Osram SMD´s hatte Target nicht mit der passenden Belegung.

Was kann ich jetzt tun? Programm umschreiben oder schwächere 
Kondensatoren verbauen?
OP #4804978
Lesenswert?

Witkatz :. schrieb:
> Sebastian A. schrieb:
>> wie lautet der befehl
>> um die LED´s nach 250 ms abzuschalten?
>
>
1
PORTA = PORTB = 0;
>
> Versuch erstmal den Ablauf in einzelnen Sequenzen verständlich zu
> beschreiben und am besten sofort in Kommentaren abzufassen.
>
> Das Lauflicht ist eine von mehreren Sequenzen in dem Ablauf, und nach 16
> Schleifendurchläufen fertig. Da du es aber in einer Endlosschleife
> eingeschlossen hast, geht es nach dem Lauflicht nicht mehr weiter. Wenn
> du statt while(1) eine vernünftige Bedingung formulierst, kann's mit
> delays nach dem Lauflicht weiter gehen. Wenn der Ablauf fertig ist und
> der µC nichts mehr zu tun hat, kannst du ihn mit SLEEP(); oder mit
> while(1); in den Feierabend verabschieden.
>
> Gruß
> witkatz

Okay, soweit schonmal Verstanden. Aber stehe noch gerade etwas auf dem 
Schlauch. Wäre es so richtig? dann komme ich auf 250 ms gesamt Programm 
laufzeit. 16 x 9ms + 144ms = 250ms
1
i = 16; // Anzahl Durchläufe
2
while (i) {
3
        
4
        // Berechnung des LED Blinkmuster
5
        leds = (leds << 1) | 1;
6

7

8
        // Aussgang des LED Blinkmuster an Ports
9
        PORTA = ((leds >> 8) & 0x1F) | ((leds >> 7) & 0xC0);
10
        PORTB = leds & 0xFF;
11
       
12
        __delay_ms(9); // Geschwindigkeit (1LED zu 2LED))
13
        i--;
14
    }
15

16
__delay_ms(144);
17

18
    PORTA = 0;
19
    PORTB = 0;
#4806574
Lesenswert?

Sebastian A. schrieb:
> Passt etwas nicht?

Wie gesagt, mach weiter. Lies noch mal die Antworten genau durch und 
mach dir Gedanken dazu. Du musst selber deine Lösung an der 
Aufgabenstellung verifizieren, also feststellen ob die Lösung alle 
beschriebenen Funktionen erfüllt.
1. Welche Sequenzen des Ablaufs hast du definiert? Es gehört eine 
Kurzbeschreibung ins Quellcode. Ein kurzer Kommentartext vor jeder 
Sequenz: was/wie/wie lange in der Sequenz passieren soll. Dann hat man's 
beim Debuggen vor den Augen.
2. Welche Sequenzen sind umgesetztzt? Wie testest du sie? MPLAB-X 
Simulator? Debug-LED? Oszi am Debug Ausgang?
3. Fehlt am Ende vielleicht was? Was macht der µC nach deiner letzten 
Sequenz, also nach dem Abschalten der LED's?

Testen musst du schon selber, weil keiner deine Schaltung nachbauen kann 
oder will. Dazu kommt, dass die Schaltung in deinem Schaltplan nicht 
funktionieren kann, du hast also was anderes aufgebaut als gepostet. 
Vielleicht sind es nur die LED Polaritäten und Widerstandswerte, aber 
wenn du bei so einfachen Grundlagen schluderst und behauptest, es wäre 
alles in Ordnung mit der Schaltung, dann weiss ich auch nicht mehr 
weiter...
#4806659
Lesenswert?

Sebastian A. schrieb:
> wie lautet der befehl
> um die LED´s nach 250 ms abzuschalten?

ich würde dafür einen Timer nehmen.
1
    // init: TIMER1 start
2
    TMR1 = 0; // Clear TMR1
3
    T1CONbits.TMR1CS = 0; // Timer1 Clock Source  Internal clock (FOSC/4)
4
    T1CONbits.T1CKPS = 0b11; // 1:8 Prescale value -> 8µs
5
    T1CONbits.TMR1ON = 1; // Enable Timer1
6

7
    ... Lauflicht Gedönse ...
8

9
    // warten auf Timer1 >= 250ms
10
    while(TMR1 < 31250); // 250ms = 31250 * 8µs 
11
    T1CONbits.TMR1ON = 0; // Disable Timer1
12
    
13
    // LEDS aus
14
    
15
    // ENDE µC in Idle setzen
OP #4806881
Lesenswert?

Witkatz :. schrieb:
Dazu kommt, dass die Schaltung in deinem Schaltplan nicht
> funktionieren kann, du hast also was anderes aufgebaut als gepostet.
> Vielleicht sind es nur die LED Polaritäten und Widerstandswerte, aber
> wenn du bei so einfachen Grundlagen schluderst und behauptest, es wäre
> alles in Ordnung mit der Schaltung, dann weiss ich auch nicht mehr
> weiter...


Target wandelt mein Schaltplan 1:1 in das Platinen Layout um, diese habe 
ich bei einem Platinen Hersteller herstellen lassen, Bauteile Korrekt 
aufgelötet und es Funktioniert. Die Beschaltung der SMD´s musste ich so 
machen da in
Target die OSRAM LY E67F anders beschaltet sind, und ich die Belegung im 
Bauteil nicht ändern konnte. War ein wenig kompliziert.
#4806894
Lesenswert?

Sebastian A. schrieb:
> Bauteile Korrekt
> aufgelötet

eben nicht, deine LEDs sind im Schaltplan verkehrt herum. Alle Hinweise 
darauf ignorierst du mit dem Hinweis auf die (zufällig) funktionierende 
Schaltung. Deswegen schrieb ich, dass die Schaltung funktioniert und du 
weisst nicht warum. Du hast einfach nur Glück, dass es ein Bautel mit 
zwei Anschlüssen ist, das du dann auch noch verkehrt herum einlöten 
kannst so dass es dann zufällig funktioniert.
OP #4806901
Lesenswert?

Witkatz :. schrieb:

> ich würde dafür einen Timer nehmen.
>
>
1
    // init: TIMER1 start
2
>     TMR1 = 0; // Clear TMR1
3
>     T1CONbits.TMR1CS = 0; // Timer1 Clock Source  Internal clock 
4
> (FOSC/4)
5
>     T1CONbits.T1CKPS = 0b11; // 1:8 Prescale value -> 8µs
6
>     T1CONbits.TMR1ON = 1; // Enable Timer1
7
> 
8
>     ... Lauflicht Gedönse ...
9
> 
10
>     // warten auf Timer1 >= 250ms
11
>     while(TMR1 < 31250); // 250ms = 31250 * 8µs
12
>     T1CONbits.TMR1ON = 0; // Disable Timer1
13
> 
14
>     // LEDS aus
15
> 
16
>     // ENDE µC in Idle setzen
17
>

Danke Witkatz :-), Ja genau das meinte ich, perfekt. Könntest du mir das 
in mein Main Programm intigrieren? Habe es mit Mplabx gerade probiert, 
irgendwas mache ich falsch bei der Implementierung... Du hast da 
wesentlich mehr Ahnung von wie ich.

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