Sari la conținut
ELFORUM - Forumul electronistilor

Banda led programabila


Vizitator Ovidiu Busuioc

Postări Recomandate

Pentru ca zilele astea am vazut la o masina un semnalizator care mi-a placut - cand a terminat de semnalizat, banda semnalizatoare si-a schimbat culoarea in alb - lumina de zi, am implementat si eu functia respectiva in codul meu.

Am testat cu 4 LED-uri, pe o singura parte. Mie mi se pare ca arata bine.

Codul actualizat, ca intotdeauna, pe github.

Si daca tot eram la schimbat, am schimbat - am separat fata de spate si, cand nu semnalizeaza, aprinde fata alba si spatele rosu.

Am actualizat/corectat si README-ul.

Link spre comentariu
  • 1 an mai târziu...

Ceva rapid.

Totul este efectuat in intrerupere, dar cum uC-ul nu face nimic altceva este acceptabil.

 

/*
 * File:   LEd_shifter_12F629.c
 * Author: mars01
 * uC: 12F629
 * D-sheet: https://www.semic.cz/_obchody/semic.obchodak.net/prilohy/7161/pic12f629-i-p-f0eb78.pdf
 * Compiler: Microchip XC8 1.44
 * Created on September 3, 2018, 11:39 PM
 */

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

#include <xc.h>

#define INPUT   1
#define OUTPUT  0

// aici se seteaza delay-ul
#define DELAY   200

#define REVERSE 0
#define FORWARD 1

#define LOW     0
#define HIGH    1

unsigned char led_states[5] = {1, 2, 4, 16, 32};
unsigned char led_dir = FORWARD;

void hw_sys(){
  // dezactivam comparator
   CMCON = 7;

  // dezactivam intreruperi
   INTCON = 0;

   // ne ocupam de pinul 4 unde conectam push_button-ul-ul si care corespunde GP3
   // GP3 este bitul 3 din GPIO
   TRISIO3 = INPUT; // pinul este INTRARE

   // ne ocupam de restul de pini unde vor fi conectate LED-urile
   TRISIO0 = OUTPUT; // pinul este IESIRE
   TRISIO1 = OUTPUT; // pinul este IESIRE
   TRISIO2 = OUTPUT; // pinul este IESIRE
   TRISIO4 = OUTPUT; // pinul este IESIRE
   TRISIO5 = OUTPUT; // pinul este IESIRE
   
   // starea initiala a LED-urilor
   GPIO = LOW;
   
   //Prescaler 1:4; TMR0 Preload = 6; timpul actual de intrerupere : 1 ms
   OPTION_REG = 0x81;
   TMR0 = 6;
   INTCON = 0xA0;
}

void interrupt ISR(){
    static unsigned int cnt = 0;
    static signed char idx = 0;
    static unsigned char debounce = 0;
    static unsigned char old_button = 0;
    
    if (TMR0IF && TMR0IE){
        TMR0IF = 0;
        TMR0 = 6;
        
        if (cnt == DELAY){
            cnt = 0;
            if (led_dir == REVERSE){
                if (idx == 5){
                    idx = 0;
                }
                else{
                    idx++;
                }
            }
            else{
                if (idx == -1){
                    idx = 4;
                }
                else{
                    idx--;
                }
            }
            GPIO = led_states[(unsigned char)idx];
        }
        else{
            cnt++;
        }
    }
    
    if (GP3 == HIGH){
        old_button = 1;
    }

    if ((GP3 == LOW) && (old_button == 1)){
        if (debounce == 11){
            debounce = 0;
            old_button = 0;
            if (led_dir == REVERSE){
                led_dir = FORWARD;
                idx = 5;
            }
            else{
                led_dir = REVERSE;
                idx = 0;
            }
        }
        else{
            debounce++;
        }
    }

}

void main()
{
   hw_sys();  // apelam si executam astfel functia hw_sys() o singura data

   /* Urmatoarea bucla este o bucla infintia care se va executa la nesfarsit
      (pana la reset de fapt :) )
   */
   while (1);
}

 

LEd_shifter_12F629.X.production.hex

Editat de mars01
Link spre comentariu

multumesc osa il testez si practic, in simulare functioneaza ok

de aici se modifica viteza?

 

// aici se seteaza delay-ul
#define DELAY   200
Editat de kinderu56
Link spre comentariu
16 minutes ago, kinderu56 said:

multumesc osa il testez si practic, in simulare functioneaza ok

de aici se modifica viteza?

 


// aici se seteaza delay-ul
#define DELAY   200

Da, valoarea este in milisecunde.

Link spre comentariu

Mi-am dat seama ca am uitat o parte importanta din sectiunea de debounce a switch-ului.

In sectiunea:

if (GP3 == HIGH){
  old_button = 1;
}

trebuie sa fie asa:

if (GP3 == HIGH){
  old_button = 1;
  debounce = 0;
}

astfel incat atunci cand switch-ul face bounce sa se reseteze contorul "debounce" facand ca numaratoarea sa inceapa din nou.

 

Mai jos este fisierul .hex conform programului corectat.

LEd_shifter_12F629.X.production.hex

Link spre comentariu

functioneaza super asa la 100ms , sar mai  putea modifica o chestie in soft sa ramana toate aprinse pana la ultimu led , inclusiv  el si dupaia sa reia din nou ciclu ? :aplauze

Link spre comentariu
4 hours ago, kinderu56 said:

functioneaza super asa la 100ms , sar mai  putea modifica o chestie in soft sa ramana toate aprinse pana la ultimu led , inclusiv  el si dupaia sa reia din nou ciclu ? :aplauze

 

Modifici linia:

unsigned char led_states[5] = {1, 2, 4, 16, 32};

in:

unsigned char led_states[5] = {1, 3, 7, 23, 55};

 

 

 

Atasat este si fisierul .hex cu acest effect.

LEd_shifter_12F629.X.production.hex

Editat de mars01
Am atasat fisierul .hex cu efectul "filling LED's"
Link spre comentariu

este super ok dar ca sa funcioneze cu as vrea terebuie sa apas pe switch iar la deconectare tensiuni nu mai tine minte si incepe sa funtioneze invers ,adica se aprind toate si se sting pe rand as vre sa fie invers sa se aprida pe rand si sa ramana aprinse pana la ultimul si dupaia sa se stinga toate adata si sa reia din nou ciclu de funcionare 

LEd_shifter_12F629.X.production.DSN

Link spre comentariu

Pentru ca sa functioneze cum doresti trebuie schimbata linia:

unsigned char led_dir = FORWARD;

in

unsigned char led_dir = REVERSE;

 

Programul arata asa:

/*
 * File:   LEd_shifter_12F629.c
 * Author: mars01
 * uC: 12F629
 * D-sheet: https://www.semic.cz/_obchody/semic.obchodak.net/prilohy/7161/pic12f629-i-p-f0eb78.pdf
 * Compiler: Microchip XC8 1.44
 * Created on September 7, 2018, 3:39 PM
 */

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

#include <xc.h>

#define INPUT   1
#define OUTPUT  0

// aici se seteaza delay-ul
#define DELAY   100

#define REVERSE 0
#define FORWARD 1

#define LOW     0
#define HIGH    1

//EFFECT: a single LED is moving forward or reverse
//unsigned char led_states[5] = {1, 2, 4, 16, 32};

//EFFECT: starting all OFF, the LED's are progressively turned ON until they are 
//all ON, forward and reverse, the cycle is repeating 
unsigned char led_states[5] = {1, 3, 7, 23, 55};
unsigned char led_dir = REVERSE;

void hw_sys(){
  // dezactivam comparator
   CMCON = 7;

  // dezactivam intreruperi
   INTCON = 0;

   // ne ocupam de pinul 4 unde conectam push_button-ul-ul si care corespunde GP3
   // GP3 este bitul 3 din GPIO
   TRISIO3 = INPUT; // pinul este INTRARE

   // ne ocupam de restul de pini unde vor fi conectate LED-urile
   TRISIO0 = OUTPUT; // pinul este IESIRE
   TRISIO1 = OUTPUT; // pinul este IESIRE
   TRISIO2 = OUTPUT; // pinul este IESIRE
   TRISIO4 = OUTPUT; // pinul este IESIRE
   TRISIO5 = OUTPUT; // pinul este IESIRE
   
   // initial LED states
   GPIO = LOW;
   
   //Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
   OPTION_REG = 0x81;
   TMR0 = 6;
   INTCON = 0xA0;
}

void interrupt ISR(){
    static unsigned int cnt = 0;
    static signed char idx = 0;
    static unsigned char debounce = 0;
    static unsigned char old_button = 0;
    
    if (TMR0IF && TMR0IE){
        TMR0IF = 0;
        TMR0 = 6;
        
        if (cnt == DELAY){
            cnt = 0;
            if (led_dir == REVERSE){
                if (idx == 5){
                    idx = 0;
                }
                else{
                    idx++;
                }
            }
            else{
                if (idx == -1){
                    idx = 4;
                }
                else{
                    idx--;
                }
            }
            GPIO = led_states[(unsigned char)idx];
        }
        else{
            cnt++;
        }
    }
    
    if (GP3 == HIGH){
        old_button = 1;
        debounce = 0;
    }

    if ((GP3 == LOW) && (old_button == 1)){
        if (debounce == 11){
            debounce = 0;
            old_button = 0;
            if (led_dir == REVERSE){
                led_dir = FORWARD;
                idx = 5;
            }
            else{
                led_dir = REVERSE;
                idx = 0;
            }
        }
        else{
            debounce++;
        }
    }

}

void main()
{
   hw_sys();  // apelam si executam astfel functia init_sys() o singura data

   /* Urmatoarea bucla este o bucla infintia care se va executa la nesfarsit
      (pana la reset de fapt :) )
   */
   while (1);
}

Atasat ai fiserul .hex corespunzator.

LEd_shifter_12F629.X.production.hex

Editat de mars01
Link spre comentariu

Corectat:

/*
 * File:   LEd_shifter_12F629.c
 * Author: mars01
 * uC: 12F629
 * D-sheet: https://www.semic.cz/_obchody/semic.obchodak.net/prilohy/7161/pic12f629-i-p-f0eb78.pdf
 * Compiler: Microchip XC8 1.44
 * Created on September 3, 2018, 11:39 PM
 */

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

#include <xc.h>

#define INPUT   1
#define OUTPUT  0

// aici se seteaza delay-ul
#define DELAY   100

#define REVERSE 0
#define FORWARD 1

#define LOW     0
#define HIGH    1

//EFFECT: a single LED is moving forward or reverse
//unsigned char led_states[5] = {1, 2, 4, 16, 32};

//EFFECT: starting all OFF, the LED's are progressively turned ON until they are 
//all ON, forward and reverse, the cycle is repeating 
unsigned char led_states[6] = {0, 1, 3, 7, 23, 55};
unsigned char led_dir = REVERSE;

void hw_sys(){
  // dezactivam comparator
   CMCON = 7;

  // dezactivam intreruperi
   INTCON = 0;

   // ne ocupam de pinul 4 unde conectam push_button-ul-ul si care corespunde GP3
   // GP3 este bitul 3 din GPIO
   TRISIO3 = INPUT; // pinul este INTRARE

   // ne ocupam de restul de pini unde vor fi conectate LED-urile
   TRISIO0 = OUTPUT; // pinul este IESIRE
   TRISIO1 = OUTPUT; // pinul este IESIRE
   TRISIO2 = OUTPUT; // pinul este IESIRE
   TRISIO4 = OUTPUT; // pinul este IESIRE
   TRISIO5 = OUTPUT; // pinul este IESIRE
   
   // initial LED states
   GPIO = LOW;
   
   //Prescaler 1:4; TMR0 Preload = 6; Actual Interrupt Time : 1 ms
   OPTION_REG = 0x81;
   TMR0 = 6;
   INTCON = 0xA0;
}

void interrupt ISR(){
    static unsigned int cnt = 0;
    static signed char idx = 6;
    static unsigned char debounce = 0;
    static unsigned char old_button = 0;
    
    if (TMR0IF && TMR0IE){
        TMR0IF = 0;
        TMR0 = 6;
        
        if (cnt == DELAY){
            cnt = 0;
            if (led_dir == REVERSE){
                if (idx >= 5){
                    idx = 0;
                }
                else{
                    idx++;
                }
            }
            else{
                if (idx <= 0){
                    idx = 5;
                }
                else{
                    idx--;
                }
            }
            GPIO = led_states[(unsigned char)idx];
        }
        else{
            cnt++;
        }
    }
    
    if (GP3 == HIGH){
        old_button = 1;
        debounce = 0;
    }

    if ((GP3 == LOW) && (old_button == 1)){
        if (debounce == 11){
            debounce = 0;
            old_button = 0;
            if (led_dir == REVERSE){
                led_dir = FORWARD;
                idx = 6;
            }
            else{
                led_dir = REVERSE;
                idx = 0;
            }
        }
        else{
            debounce++;
        }
    }

}

void main()
{
   hw_sys();  // apelam si executam astfel functia init_sys() o singura data

   /* Urmatoarea bucla este o bucla infintia care se va executa la nesfarsit
      (pana la reset de fapt :) )
   */
   while (1);
}

 

LEd_shifter_12F629.X.production.hex

Link spre comentariu
  • 1 an mai târziu...

salut, ma poate ajuta si pe mine un baiat care se pricepe la programare cu un mic soft pentru un PIC 

doresc un integrat ieftin si mic maxim 8 pini , sau chiar 12f629

vreau ca controlarul cand primeste  pe un pin un  minus permanent pe un alt terminal sa aprinda un led pentru 200-300 ms iar cand terminalul este deconectat de la minus sa aprind din nou ledul pentru acelasi timp . multumesc si sper ca nu este ceva imposibil cea ce cer

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări