Sari la conținut
ELFORUM - Forumul electronistilor

Cum sa programez un PIC


sofian

Postări Recomandate

Ra5 e si intrare analogica AN4, nu mai trebuie sa modific nimic acolo la ADCON1? pur si simplu il declar ca iesire si gata? ar trebuie sa mearga?

Da, trebuie sa mearga ca port digital I/O. Doar inlocuiesti PORTA.F4 cu PORTA.F5
Link spre comentariu
  • Răspunsuri 604
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Liviu M

    54

  • Vlad Mihai

    28

  • bbogdanmircea

    27

  • seichter

    24

Top autori în acest subiect

Imagini postate

am testat si cu ra5 tot nu merge si cu modificarile de rigoare.

atasez codul:

sbit LCD_RS at RB2_bit;sbit LCD_EN at RB3_bit;sbit LCD_D4 at RB4_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D7 at RB7_bit;sbit LCD_RS_Direction at TRISB2_bit;sbit LCD_EN_Direction at TRISB3_bit;sbit LCD_D4_Direction at TRISB4_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D7_Direction at TRISB7_bit; //initiere conexiuni pic cu LCD  unsigned char txt1[] = "    Dc motor    ";  unsigned char txt2[] = "    Control     ";  unsigned char txt3[] = "     David      ";   unsigned char txt4[] ="    Valentin    ";  unsigned char ch;  unsigned short current_duty1,current_duty2;  unsigned int Tensiune,valoare_adc1,valoare_adc2,curent1,curent2;  unsigned long u,i;void main() {  TRISB = 0xC0;  PORTB = 0x00;  CMCON=7;  ADCON1 = 0b00000011;        // configure RA2 pin as analog  TRISA  = 0x07;              // PORTA.0-2 is input  TRISC.F7 = 1;                   //   butonul de oprire  TRISC.F6 = 1;                   //   butonul pentru dreapta motor1  TRISC.F5 = 1;                   //   butonul pentru stanga motor1  TRISB.F1 = 1;                   //   butonul pentru stanga motor2  TRISB.F0 = 1;                   //   butonul pentru dreapta motor2  TRISC.F0 = 0;                          //comanda motor1  TRISC.F3 = 0;                          //comanda motor1  TRISC.F4 = 0;                          //comanda motor2  TRISA.F5 = 0;                          //comanda motor2  PORTC.F0 = 0;                           //blocare motor1  PORTC.F3 = 0;                          //blocare motor1  PORTC.F4 = 0;                          //blocare motor2  PORTA.F5 = 0;                          //blocare motor2  PWM1_Init(10000);               //setare frecventa pwm1  10Khz  PWM2_Init(10000);                 //setare frecventa pwm2    10Khz  Lcd_Init();                        // Initialize LCD  Lcd_Cmd(_LCD_CLEAR);               // Clear display  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off  Lcd_Out(1,1,txt1);                 // Write text in first row  Lcd_Out(2,1,txt2);                 // Write text in second row  Delay_ms(300);  Lcd_Cmd(_LCD_CLEAR);               // Clear display  Lcd_Out(1,1,txt3);                 // Write text in first row  Lcd_Out(2,1,txt4);                 // Write text in second row  Delay_ms(300);  Lcd_Cmd(_LCD_CLEAR);               // Clear display  LCD_Out(1, 1,"Va:");  LCD_Out(2, 1,"Sens:");  current_duty1  = 0;  current_duty2 = 0;                 // valori initiale   PWM1_Start();                       // start PWM1   PWM2_Start();                       // start PWM2  PWM1_Set_Duty(current_duty1);        // setare   factor de umplere  PWM2_Set_Duty(current_duty2);while (1) { //control sens motor1      if(PORTB.F1 == 0)                      //If the switch is pressed    {       Delay_ms(100);                             //Switch Debounce       if(PORTB.F1 == 0)                       //If the switch is still pressed       {          Delay_ms(100);        PORTC.F4 = 1;                          //1 logic        PORTA.F5 = 0;                          //0 logic        LCD_Out(2, 6,"St       ");       }    }  if(PORTB.F0 == 0)                      //If the switch is pressed    {       Delay_ms(100);                             //Switch Debounce       if(PORTB.F0 == 0)                       //If the switch is still pressed       {          Delay_ms(100);         PORTC.F4 = 0;                          //0 logic         PORTA.F5 = 1;                          //1 logic        LCD_Out(2, 6,"Dr       ");       }    }    //control sens motor2      if(PORTC.F6 == 0)                      //If the switch is pressed    {       Delay_ms(100);                             //Switch Debounce       if(PORTC.F6 == 0)                       //If the switch is still pressed       {          Delay_ms(100);         PORTC.F0 = 1;                           //1 logic         PORTC.F3 = 0;                          // 0 logic        LCD_Out(2, 9,"      Dr");       }    }  if(PORTC.F5 == 0)                      //If the switch is pressed    {       Delay_ms(100);                             //Switch Debounce       if(PORTC.F5 == 0)                       //If the switch is still pressed       {          Delay_ms(100);         PORTC.F0 = 0;                           //0 logic         PORTC.F3 = 1;                          // 1 logic        LCD_Out(2, 9,"      St");       }    }     if(PORTC.F7 == 0)                          //If the switch is pressed    {       Delay_ms(100);                           //Switch Debounce       if(PORTC.F7 == 0)                        //If the switch is still pressed       {           PORTC.F0 = 0;                        //blocare motor1           PORTC.F3 = 0;                        //blocare motor1           PORTC.F4 = 0;                        //blocare motor2           PORTA.F5 = 0;                        //blocare motor2          Delay_ms(100);        LCD_Out(2, 6,"   STOP     ");       }    }    //    /* end */         valoare_adc1 = ADC_Read(1); current_duty1= valoare_adc1>> 2;  // conversie citire de pe ADC din 10 Biti in 8 Biti    si setare pwm in fucntie de    ce citeste pe ADC PWM1_Set_Duty(current_duty1); valoare_adc2 = ADC_Read(2); current_duty2= valoare_adc2>> 2; // conversie citire de pe ADC din 10 Biti in 8 Biti    si setare pwm in fucntie de    ce citeste pe ADC PWM2_Set_Duty(current_duty2);      // Tensiune alimentare motoare      Tensiune=ADC_read(0);                // get ADC value for U from channel 1      u=(long)Tensiune*5555;         // covert adc reading to milivolts -valoare calculata in  functie de divizor rezistiv      u=u/1023;                            // 0..1023 -> 0-3500mV      ch=u/1000;                           // extract 10.00 U digit      if (ch==0)        {          LCD_Chr(1,4, 32);                // write empty space if digit is 0        }      else        {          LCD_Chr(1,4,48+ch);              // write ASCII digit at 1st row, 2nd column        }      ch=(u/100) %10;                      // extract 01.00 U digit      LCD_Chr_CP(48+ch);                   // write ASCII digit at cursor point        LCD_Chr_CP('.');                     // write '.' at cursor point      ch=(u/10) %10;                       // extract 00.10 U digit      LCD_Chr_CP(48+ch);                   // write ASCII digit at cursor point      ch=u %10;                            // extract 00.01 U digit      LCD_Chr_CP(48+ch);                  // write ASCII digit at cursor point      LCD_Chr_CP('V');                     // write 'V' at cursor point } }
Link spre comentariu

valoarea aia cu ADCON1=0xY4; nu e corecta imi da eroare.

Sigur ca nu e corecta, unde ai mai vazut tu cifra hexazecimala Y? :ras: 4 e pe post de "asta trebuie sa configurezi intrarile pentru RA0, RA1 & RA3 analog, restul digital", iar Y pe post de "nu are treaba cu ce vreau eu sa spun".
Link spre comentariu

Hai ca nu-i asa greu.

Te uiti in data-sheet la ADC si vezi ca trebuie sa configurezi doi registri ADCON0 si ADCON1.

Ne ocupam putin de ADCON1, ca sa iasa si configurarea care-ti lipseste.

Cum ziceam si mai devreme, in data-sheet e tratat la pagina 128.

In primul rand, avem un "tabel" cu semnificatia bitilor - b7 = ADFM, bit6 = ADCS2...

Urmeaza descrierea lor functionala:

bit 7 = ADFM:

- daca e = 1, rezultatul conversiei e aliniat la dreapta. Adica rezultatul (pe 10 biti) sta in ADRESH<1:0>&ADRESL<7:0>.

Bitii ADRESH<7:2> sunt 0.

- daca e = 0, rezultatul conversiei e aliniat la stanga. Adica rezultatul (pe 10 biti) sta in ADRESH<7:0>&ADRESL<7:6>.

Bitii ADRESL<5:0> sunt 0.

Nu e foarte important ce scrii aici, numai ca trebuie sa prelucrezi rezultatul in functie de ce scrii.

bit 6 = ADCS2

Impreuna cu ADCS1 din ADCON0 formeaza bitii de selectie a ceasului cu care se face achizitia. Pentru detalii despre ceas trebuie sa citesti atent data-sheetul.

Bitii 5 si 4 nu conteaza, ii ignori (pui 0).

Si ajungem la bitii care te intereseaza pe tine. Te uiti in tabelul ala mare de pe pagina si vezi ca:

- coloana din stanga reprezinta combinatiile pe care le pot lua bitii PCFG3:PCFG0.

- restul coloanelor sunt pentru tipul (analog/digital) pe care-l va avea fiecare port (care poate fi analog => AN7..AN0) si unde sunt conectate referintele pentru fiecare combinatie PCFG3:PCFG0.

Ca sa vezi despre care port e vorba, te uiti la pinout/consulti tabelele de la I/O Ports (capitolul 4).

De exemplu, pentru PCFG3:PCFG0 = 0000, toate intrarile sunt analoge (in coloana AN7 ai A, in AN6 A...) si referintele sunt VDD & VSS.

Pentru varinata recomandata de mine (pentru cazul cu tau cu 3 intrari analogice), PCFG3:PCFG0 = 0100, ai AN7..AN4 = D, AN3 = A, AN1..AN0 =A. Te uiti la pinout si vezi cine-s AN7..AN0 si ajungi la ce am zis anterior.

 

Sper ca nu te-am confuzat si mai tare.

 

Cu alte cuvinte, pentru 3 intrari analoge, referintele la alimentare (Vref+ = VDD, Vref- = VSS), clock si aliniere ca la nico, mie-mi iese

ADCON1 = 0x04;
Link spre comentariu

Liviu merge m-ai salvat din nou. RA5 se comporta corect ca o iesire. tot nu am priceput cu ai ajuns de valoarea aia din tabel(PCFG3:PCFG0 = 0100) la ADcon1=0x04, dar o sa mai citesc eu; Multumesc de timp si lamurire!

Link spre comentariu

Am cautat in tabel o combinatie pentru care sa fie 3 porturi analogice si referintele sa fie la alimentari. Singura care s-a potrivit a fost PCFG3:PCFG0 = 0100.Daca te uiti in table pe randul corespunzator PCFG3:PCFG0 = 0100 ai sa ajungi si tu la aceeasi concluzie:AN7 = RE2 = D, adica digitalAN6 = RE1 = D, adica digitalAN5 = RE0 = D, adica digitalAN4 = RA4 = D, adica digitalAN3 = RA3 = A, adica analogAN2 = RA2 = D, adica digitalAN1 = RA1 = A, adica analogAN0 = RA0 = A, adica analogAdica la configuratia asta ai trei porturi analogice si restul digitale.

Link spre comentariu

Si pentru ca acum am citit cum trebuie intrebarea, raspunsul potrivit.E simplu, PCFG3..PCFG0 sunt bitii b3..b0 ai ADCON1.Daca ei sunt 0100 (in binar) = 4 (hex), => ADCON1 are nibble-ul lsb =4.

Link spre comentariu
  • 1 lună mai târziu...

Incerc sa scriu un PIC18F2550 cu un JDM si WINPIC cu hexul de la PICKIT2.Cand incarc hexul in program imi da mesajul "Aborting LoadAndProgram because of error(s)".Daca continui sa-l scriu il scrie cu erori. Similar si cu PIC Pgm. Cum sa-l fac sa mearga OK?Multumesc.

post-4078-139829687313_thumb.jpg

Link spre comentariu

cu jdm , print port serial , pe ce windows ? daca schema e corecta si conexiunile la fel ... e vorba de driverul portului COM care " merge prea repede" . incearca sa rulezi programele in compatibility mode , si la setings sa pui chiar si windows98. A fost o idee...

Link spre comentariu
  • 2 săptămâni mai târziu...

salutam incercat noul (pentru mine cel putin) xc8 (compilator de c gratuit de la microchip).si... m-am oprit la faptul ca nu recunoaste comanda "delay". adica __delay_ms() sau __delay_us().s-a confruntat cineva cu aceasta problema?am pus #define FOSC si tot nu merge.aveti vreo idee?

Link spre comentariu

Daca prin "nu recunoaste" intelegi "sublinierea cu rosu" in mplabx, atunci e doar o problema de parser/afisare, compilarea merge.Daca nu merge compilarea, atunci posteaza un exemplu si mesajele de eroare corespunzatoare.

Link spre comentariu
  • 1 lună mai târziu...
Vizitator cereal_port

salutare!am si eu o problema mai de incepatori, as avea nevoie de o idee. as vrea sa scriu un cuvant pe un lcd cu ajutorul unui pic16f84 si doua butoane astfel: cand apas un buton litera curenta sa se roteasca inainte in alfabet iar cand il apas pe al doilea sa se roteasca inapoi in alfabet, sa selectez litera dorita si sa trec la litera urmatoare. programez in C app, daca ati putea sa imi dati o idee...am o idee cu un vector in care sa am toate literele alfabetului iar cu ajutorul unei variabile pe care o incrementez sau decrementez sa afisez elementul corespunzator al vectorului dar mi se pare cam "urata".

Link spre comentariu

Pai nu-ti trebuie nimic special, e suficient sa folosesti codurile ascii. De altfel chiar asta asteapta afisoarele LCD.In C n-ai decat sa folosesti caractere ('a'..'z'...) sau siruri de caractere, depinde de functiile folosite.

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