Forum: Mikrocontroller und Digitale Elektronik Hilfe bei PIC Programmierung, C Code


von Sebastian A. (micropoint)


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
}

: Verschoben durch Moderator
von 1N4148 (Gast)


Lesenswert?

Kleinerer C? Oder was ist dein Problem?

von Greg (Gast)


Lesenswert?

Sebastian A. schrieb:
> da in den Kondensatoren die meine 12V auf 5V per Festspannungsregler
> runter regeln noch kurz Spannung abgeben. Wie kann ich dies verhindern?

Eine stabile Spannungsversorgung muss schon sein. Größeres Netzteil 
benutzen.

von Cyborg (Gast)


Lesenswert?

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.

von Sebastian A. (micropoint)


Angehängte Dateien:

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.

von 1N 4. (1n4148)


Lesenswert?

250ms nach was? Dem Urknall?

von bigbeng (Gast)


Lesenswert?

Ja, nach dem Urknall! Wie also lautet der Befehl um die LEDs 250ms nach 
dem Urknall abzuschalten?

von Sebastian A. (micropoint)


Lesenswert?

bigbeng schrieb:
> Ja, nach dem Urknall! Wie also lautet der Befehl um die LEDs 250ms nach
> dem Urknall abzuschalten?


Tut mir leid für mein schlechtes Fachwissen. Ich möchte das das ganze 
Programm 250ms läuft. Dann sollen alle LED´s wieder aus sein.

von Witkatz :. (wit)


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

von 1N 4. (1n4148)


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;

von Poster (Gast)


Lesenswert?

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?

von Sebastian A. (micropoint)


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.

: Bearbeitet durch User
von Witkatz :. (wit)


Lesenswert?

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.

: Bearbeitet durch User
von Sebastian A. (micropoint)


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?

von Erich (Gast)


Lesenswert?

Sebastian A. schrieb:
> Was kann ich jetzt tun? Programm umschreiben ... ?

Liest du eigentlich auch Antworten?
Beitrag "Re: Hilfe bei PIC Programmierung, C Code"

von Sebastian A. (micropoint)


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;

von Witkatz :. (wit)


Lesenswert?

Sebastian A. schrieb:
> Wäre es so richtig?

OK, einen kleinen Teil der Vorschläge hast du umgesetzt, bis jetzt nicht 
schlecht. Weiter so!

von Sebastian A. (micropoint)


Lesenswert?

Witkatz :. schrieb:
> Sebastian A. schrieb:
>> Wäre es so richtig?
>
> OK, einen kleinen Teil der Vorschläge hast du umgesetzt, bis jetzt nicht
> schlecht. Weiter so!

Passt etwas nicht?

von Witkatz :. (wit)


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

von Witkatz :. (wit)


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

von Sebastian A. (micropoint)


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.

von Witkatz :. (wit)


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.

von Sebastian A. (micropoint)


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.

von Witkatz :. (wit)


Lesenswert?

Sebastian A. schrieb:
> Könntest du mir das
> in mein Main Programm intigrieren?

Nö. Mach dein Kram selber.

von Sebastian A. (micropoint)


Lesenswert?

Witkatz :. schrieb:
> Sebastian A. schrieb:
>> Könntest du mir das
>> in mein Main Programm intigrieren?
>
> Nö. Mach dein Kram selber.


Ja ist ja in Ordnung, sitze schon den ganzen Tag dran. Versuche es 
weiter. Trotzdem danke.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.