nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 Buna ziua, cum pot seta la pic16f876a portul A astfel incat A0,A1,A2 sa fie intrari analogice si restul sa fie iesiri digitale? nu pricep mare lucru din datashet la chestia cu registrii. folosesc compilatorul mikroC. Multumesc!Incearca asa:ADCON1 = 0b00000011; // configure RA2 pin as analog TRISA = 0x07; // PORTA.0-2 is input Link spre comentariu
Liviu M Postat August 19, 2013 Partajează Postat August 19, 2013 @Vlad: Nu poti.Combinatiile analog/digital sunt configurate cu bitii PCFG3:PCFG0 din registrul ADCON1.La pagina 128 in data-sheet ai combinatiile posibile. Cea mai apropiata de ce-ti trebuie pare PCFG3:PCFG0 = 0100, caz in care RA0, RA1 & RA3 sunt intrari analogice, ceilalti pini fiind digitali. Link spre comentariu
Vlad Mihai Postat August 19, 2013 Partajează Postat August 19, 2013 multumesc Liviu, m-am uitat si eu in datasheet si am observat alea. O sa modific cablajul si pun in loc de A2, A3, acum ramane cum le declar in cod, poate imi dai o idee.@nico_2010 multumesc de sfat dar din pacate nu functioneaza. Link spre comentariu
nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 Si totusi, incearca acest cod si simuleaza-l (este facut in graba, fara pretentii): MCU: PIC16F876A http://ww1.microchip.com/downloads/en/DeviceDoc/39762d.pdf Oscillator: HS, 10.0000 MHz Ext. Modules: - SW: mikroC PRO for PIC http://www.mikroe.com/eng/products/view/7/mikroc-pro-for-pic/ */// LCD module connectionssbit LCD_RS at RB4_bit;sbit LCD_EN at RB5_bit;sbit LCD_D4 at RB0_bit;sbit LCD_D5 at RB1_bit;sbit LCD_D6 at RB2_bit;sbit LCD_D7 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;unsigned int temp_res[3];unsigned int i;char txt3[] = "Test ADC";char txt4[7];char txt5[7];char txt6[7];void main() { ADCON1 = 0b00000011; // configure RA2 pin as analog TRISA = 0x07; // PORTA is input TRISC = 0; // PORTC is output Lcd_Init(); Lcd_Cmd(_LCD_CLEAR); // Clear display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1,6,txt3); // Write text in first row Delay_ms(500); Lcd_Cmd(_LCD_CLEAR); // Clear display do { for(i=0;i<3;i++) temp_res[i] = ADC_Read(i); // Get results of AD conversion IntToStr(temp_res[0], txt4); IntToStr(temp_res[1], txt5); IntToStr(temp_res[2], txt6); Lcd_Out(1,1,txt4); Lcd_Out(1,5,txt5); Lcd_Out(1,9,txt6); } while(1); // endless loop} Link spre comentariu
Vlad Mihai Postat August 19, 2013 Partajează Postat August 19, 2013 @nico am testat practic acum, am pus secventa ta de cod in codul meu. si nu merge. pe RA0 citest o tensiune de 12v cu divizor de tensiune de 10X, problema e ca mie in loc de 12v cat trebuie sa imi arate imi indica 55.55V. 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.F4 = 0; //comanda motor2 PORTC.F0 = 0; //blocare motor1 PORTC.F3 = 0; //blocare motor1 PORTC.F4 = 0; //blocare motor2 PORTA.F4 = 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.F4 = 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.F4 = 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.F4 = 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 } } codul presupune controlul independent a 2 motoare de cc cu o punte H L298N si turatie reglabila cu pwm(cu ajutorul unui potentiometru). daca pun asta ADCON1 = 0x80; TRISA = 0xFF; // PORTA is inputimi functioneaza ADC corect, dar nu merge RA4 ca iesire digitala. Link spre comentariu
nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 Verifica-l si acum: 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 txt5[7]; unsigned char txt6[7]; unsigned char ch; unsigned short current_duty1,current_duty2; unsigned int Tensiune,valoare_adc1,valoare_adc2,curent1,curent2; // Variabile unsigned int temp_res1,temp_res2; // adaugate de nico_2010 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.F4 = 0; //comanda motor2 PORTC.F0 = 0; //blocare motor1 PORTC.F3 = 0; //blocare motor1 PORTC.F4 = 0; //blocare motor2 PORTA.F4 = 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.F4 = 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.F4 = 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.F4 = 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 //conversie int to string IntToStr(current_duty1, txt5); //pentru teste doar. nico_2010 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 //conversie int to string IntToStr(current_duty2, txt6); //pentru teste doar. nico_2010 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,1, 32); // write empty space if digit is 0 } else { LCD_Chr(1,1,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(1,2,'.'); // write '.' at cursor point ch=(u/10) %10; // extract 00.10 U digit LCD_Chr(1,3,(48+ch)); // write ASCII digit at cursor point ch=u %10; // extract 00.01 U digit LCD_Chr(1,4,(48+ch)); // write ASCII digit at cursor point LCD_Chr_CP('V'); // write 'V' at cursor point//afisare continut ADC 1 si 2 pentru testarea functionarii setarilor de utilizare a ADC. nico_2010 LCD_Out(1, 10,txt5); LCD_Out(2, 10,txt6); delay_ms(2500); Lcd_Cmd(_LCD_CLEAR); } }In coltul din dreapta, pe cele doua linii, incepand cu poz.10 vei regasi valoarea ADC 1, respectiv ADC 2, iar pe prima linie, poz.1 ai valoarea convertita a ADC 0 Link spre comentariu
Liviu M Postat August 19, 2013 Partajează Postat August 19, 2013 Cu ADCON1 = 0b00000011; // configure RA2 pin as analog foloseste referinta externa. Ce tensiune ai pe Vref+ (cum e legat pinul RA3)?acum ramane cum le declar in cod, poate imi dai o idee.N-am inteles intrebarea. RA0, RA1 & RA2 nu ajunge?ADCON1 = 0xY4? Link spre comentariu
nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 Cu ADCON1 = 0b00000011; // configure RA2 pin as analog foloseste referinta externa. Ce tensiune ai pe Vref+ (cum e legat pinul RA3)?Am pornit de la premisa ca Vref=tensiunea de alimentare de 5V, sper ca nu este gresita. Link spre comentariu
Vlad Mihai Postat August 19, 2013 Partajează Postat August 19, 2013 @nico_2010 multumesc de ajutor dar nu afiseaza corect valoarea adc convertita adc0 imi afiseaza 5.55v desi trebuia sa afiseze 12v. celelalte 2 se comporta ciudat. invart un pic de potentiometre si imi arata maxim 255, potentiometrele sunt de 50k.@Liviu Ra3 este in aer.ziceai ca nu pot configura conform datasheet ra0,ra1,ra2 si restul sa fie digitali, ci trebuie sa fac cu ra0,ra1 si ra3 restul sa fie digitali nu? valoarea aia cu ADCON1=0xY4; nu e corecta imi da eroare. Link spre comentariu
nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 @nico_2010 multumesc de ajutor dar nu afiseaza corect valoarea adc convertita adc0 imi afiseaza 5.55v desi trebuia sa afiseze 12v. celelalte 2 se comporta ciudat. invart un pic de potentiometre si imi arata maxim 255, potentiometrele sunt de 50k.@Liviu Ra3 este in aer.Conecteaza RA3 la +5V.Vezi in imaginea alaturata cum ar trebui sa iti apara pe LCD. Link spre comentariu
Vlad Mihai Postat August 19, 2013 Partajează Postat August 19, 2013 da, acum functioneaza potentiomerele ok pe adc, la afisarea valorii adc0 convertite imi afiseaza 1.2 ma gandesc ca e o eroare undeva in soft nu? acum sa inteleg ca merge ra4 ca iesire digitala? Link spre comentariu
nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 da, acum functioneaza potentiomerele ok pe adc, la afisarea valorii adc0 convertite imi afiseaza 1.2 ma gandesc ca e o eroare undeva in soft nu? acum sa inteleg ca merge ra4 ca iesire digitala?Testeaza-l pe RA4 punandu-l sa aprinda, de exemplu, un LED si apoi sa-l stinga.Edit: Nu-l vei putea folosi ca port digital I/O Link spre comentariu
Vlad Mihai Postat August 19, 2013 Partajează Postat August 19, 2013 nu merge, am introdus noile date in codul meu, altfel nu am cum testa, pentru am deja cablajul facut, conform codului atunci cand apas un anumit buton RA4 se face 1 logic si impreuna cu alt pin care se face 0 logic roteste motorul intr-un sens. la mine e problema ca motorul se roteste doar cand ra4 e 0 adica intr-un singur sens. cand apas pe buton sa execute ra4 1 logic nu se intampla nimic. am masurat cu voltmetrul am 0V atunci cand ar trebuie sa fie 1 logic. codul e cel de mai sus. la care am pus modificarile din codul de la nico_2010 cu privire la adcon si portulA. e sa aiba? mentionez ca ma chinui cu acest pin ca nu mai am alt pin pe alt port, as mai avea liber RA5. multumescpai atunci nu ma ajuta cu nimic ceea ce am facut noi adineari, ca si mie imi mergeau toate porturile adc corect, doar ca vroiam ca un port adc sa fie digital si nu am reusit. in rest mi-a functionat corect intrarile analogice. Link spre comentariu
nico_2010 Postat August 19, 2013 Partajează Postat August 19, 2013 Foloseste RA 5 in locul lui RA 4 Link spre comentariu
Vlad Mihai Postat August 19, 2013 Partajează Postat August 19, 2013 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? Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum