Sari la conținut
ELFORUM - Forumul electronistilor

PIC16F688


svi67

Postări Recomandate

Buna ziua.As vrea sa va rog daca puteti sa ma ajutati cu combinarea celor doua programe, nu ma descurc cu combinarea celor doua "do"-uri cel din prog1 cu cel din prog2.PROG1:// LCD module connections sbit LCD_RS at RC4_bit; sbit LCD_EN at RC5_bit; sbit LCD_D4 at RC0_bit; sbit LCD_D5 at RC1_bit; sbit LCD_D6 at RC2_bit; sbit LCD_D7 at RC3_bit; sbit LCD_RS_Direction at TRISC4_bit; sbit LCD_EN_Direction at TRISC5_bit; sbit LCD_D4_Direction at TRISC0_bit; sbit LCD_D5_Direction at TRISC1_bit; sbit LCD_D6_Direction at TRISC2_bit; sbit LCD_D7_Direction at TRISC3_bit;// End LCD module connectionschar Message1[] = "VOLTMETRU";unsigned int ADC_Value, DisplayVolt;char *volt = "00.0";void main() { ANSEL = 0b00000100; // RA2/AN2 is analog input ADCON0 = 0b00001000; // Analog channel select @ AN2 ADCON1 = 0x00; // Reference voltage is Vdd CMCON0 = 0x07 ; // Disable comparators TRISC = 0b00000000; // PORTC All Outputs TRISA = 0b00001100; // PORTA All Outputs, Except RA3 and RA2 Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // CLEAR display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1,1,Message1); Lcd_Chr(2,8,'V'); do { ADC_Value = ADC_Read(2); DisplayVolt = ADC_Value * 2; volt[0] = DisplayVolt/1000 + 48; volt[1] = (DisplayVolt/100)%10 + 48; volt[3] = (DisplayVolt/10)%10 + 48; Lcd_Out(2,3,volt); delay_ms(500); // Hold for 500 ms } while(1);} // End main()si PROG2:/* Toggle an LED with a Push Button SwitchInternal Oscillator @ 4MHz, MCLR Enabled, PWRT Enabled, WDT OFF*/// Define the LED @ RA1 and push button switch @ RA0sbit LED at RCA1_bit;sbit Switch at RA0_bit;// Macros for Button() function#define Switch_Pin 0#define Switch_Port PORTA#define Debounce_Time 20 // Switch Debounce time 20msvoid main() {ANSEL = 0b00000100; //All I/O pins are configured as digital except RA2/AN2TRISC = 0b00000000; // PORTC All OutputsTRISA = 0b00001101; // PORTA All Outputs except RA3,RA0,RA2LED = 0;do {if (Button(&Switch_Port, Switch_Pin, Debounce_Time, 0)) {if (!Switch) { // Check the button press again after the debounce timeLED = ~LED;}while (!Switch); // Wait until the button is released}} while(1); // Infinite Loop}atasez si schema.Defapt intrebarea ar fi cum combin cele doua programe?Multumesc.

Link spre comentariu
  • 4 săptămâni mai târziu...
  • Răspunsuri 18
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • svi67

    12

  • Liviu M

    3

  • francezu

    3

  • puiu

    1

Top autori în acest subiect

Divizorul tau rezistiv are un factor de 0.25 (1.3/(1.3+3.9).0.25 *20V = 5V la intrarea ADC-ului. Tot ce trece de tensiunea asta (20V) "iese din scala".

Link spre comentariu

Trebuie modificat divizorul rezistiv pt a accepta 30V la intrare, si de asemenea modificat in soft conversia. Vezi codul de mai jos, am inclus si partea de toggle pt led.

-butonul se conecteaza intre RA0 si masa, cu rezistenta pull-up (10k);

-led-ul se conecteaza intre pinul RA1 si masa, cu rezistenta serie de minim 330ohm;

-divizorul rezistiv de la intrare se modifica astfel: R2=7.5kohm, R3=1.5kohm ;

-intrarea se leaga pe RA2, nu RA4 asa cum este in schema (in soft se foloseste AN2);

Nu garantez pt cod, mai ales la greseli de sintaxa, nu am programat niciodata in C.

program vmetersymbol LED=RA1_bitsymbol SW_port=PORTAsymbol SW_pin=0// LCD module connectionssbit LCD_RS at RC4_bit;sbit LCD_EN at RC5_bit;sbit LCD_D4 at RC0_bit;sbit LCD_D5 at RC1_bit;sbit LCD_D6 at RC2_bit;sbit LCD_D7 at RC3_bit;sbit LCD_RS_Direction at TRISC4_bit;sbit LCD_EN_Direction at TRISC5_bit;sbit LCD_D4_Direction at TRISC0_bit;sbit LCD_D5_Direction at TRISC1_bit;sbit LCD_D6_Direction at TRISC2_bit;sbit LCD_D7_Direction at TRISC3_bit;// End LCD module connectionschar Message1[] = "VOLTMETRU";unsigned int ADC_Value, DisplayVolt;char *volt = "00.0";void main() {ANSEL = 0b00000100; // RA2/AN2 is analog inputADCON0 = 0b00001000; // Analog channel select @ AN2ADCON1 = 0x00; // Reference voltage is VddCMCON0 = 0x07 ; // Disable comparatorsTRISC = 0b00000000; // PORTC All OutputsTRISA = 0b00001101; // PORTA All Outputs, Except RA0,RA2 and RA3Lcd_Init(); // Initialize LCDLcd_Cmd(_LCD_CLEAR); // CLEAR displayLcd_Cmd(_LCD_CURSOR_OFF); // Cursor offLcd_Out(1,1,Message1);Lcd_Chr(2,8,'V');do {for i=0 to 50 {    if(Button(&SW_port,SW_pin,50,0)){      LED=~LED;      while(!SW_port.SW_pin);      }Delay_ms(10);}next iADC_Value = ADC_Read(2);DisplayVolt = (ADC_Value * 30) / 1023;volt[0] = DisplayVolt/1000 + 48;volt[1] = (DisplayVolt/100)%10 + 48;volt[3] = (DisplayVolt/10)%10 + 48;Lcd_Out(2,3,volt);} while(1);} // End main()
Link spre comentariu
  • 8 luni mai târziu...

As mai avea o intrebare ,am inteles ca nu este bine sa se foloseasca delay-uri mari la picuri .Daca am o aplicatie unde am de aprins 4 LEDURI din minut in minut succesiv unde precizia nu conteaza , de ce nu ar merge cu un delay de 1min fara a se utiliza Timerul intern?

Link spre comentariu

Nu este nici o problema, se poate face cu delay-uri mari, si este totodata mai simplu. Insa aceasta abordare nu permite constructia unor programe mai complexe, in care se doreste ca uC sa execute si alte operatii in perioadele acelea de intarziere. Poti sa te gandesti la o situatie de pseudo-multitasking, in care spre exemplu vrei ca un led sa palpaie odata la 10 sec, iar in acelasi timp sa supraveghezi una dintre intrari la care este legat un buton. Daca ai folosi delay-uri mari, mai mult ca sigur ai rata apasarea butonului. Deci mai sigur este sa folosesti delay-uri mai mici executate de X ori pentru a obtine intarzierea dorita( de exemplu o bucla for...). In interiorul buclei introduci si codul care trebuie executat mai rapid, in cazul de mai sus - supravegherea unei intrari. Delay-urile pot fi "in line" sau generate de un timer intern.

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

Buna ziua ,As mai avea nevoie de un sfat pentru conectarea unui senzor de umiditate HIH-4000-002.Din datasheet am inteles ca tensiunea de iesire este undeva intre 0,7 si 3,6 v .Intrebarea mea ar fi ce referinta de tensiune sa folosesc si cum sa calculez conversia ADC ?Nu reusesc sa prind idea formulei de calcul si conversia ei pentru afisarea %Rh care se situeaza intre 0 - 100% pentruvalorile de mai sus. Rezultatul il voi afisa pe LCD.

Link spre comentariu

Pentru a translata un interval in procente folosesti urmatoarea formula : %(Z)= (Z-X)/(Y-X)*100, undeX- capatul inferior al intervalului( 0.7 in cazul tau), Y- capatul superior(3.6 in cazul tau), Z- un nr din interval pentru care vrei sa calculezi ce procent din intervalul respectiv reprezinta.Referinta de tensiune a ADC-ului poti sa o iei chiar tensiunea de alimentare a uC-ului (VDD), dar aceasta trebuie sa fie stabilizata; alternativ se poate si cu referinta externa.Iti sugerez sa faci calculele in valori ADC, pentru a nu irosi RAM si ROM cu variabile float. Astfel vei converti capetele de interval in valori corespunzatoare ale ADC-ului (in functie de rezolutia aleasa pe 8 sau 10 biti).

Link spre comentariu
  • 3 luni mai târziu...

Buna ziua!Cum as putea extrage inca o zecimala de la senzorul de temperatura DS18B20 Folosind formula urmatoare:// Converts sensor data byte to integersigned short ConTemp(unsigned temp){ int tt; unsigned short sign, frac; signed short x=0; if(temp>=2048) { sign=1; tt=(0xFFFF-temp)+1; } else { sign=0; tt=temp; } //frac=tt & 0xF; tt>>=4; x=tt; //+(frac*0.0625); if(sign==1) x*=(-1); return (x);}m-am jucat cu frac-ul dar nu am reusit .

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

Buna ziua din nou.Revin cu o alta problema legata de un termostat .Senzorul folosit este 18B20.Am facut valoarea citita de la senzor egala cu o variabila de tipul unsigned int x1; pe care o folosesc si la afisarea valorilor pe LCD ,valoarea temperaturii este un unsigned Temp_Tinta; care ajunge si ea la un moment dat egala cu x1 pentru afisare si efectuarea setarilor de temperatura.Nedumerirea mea este ca orice valoare atribui lui Temp_Tinta intre 0 si 11000 de exemplu,afisarea acestuia pleaca de la "00.0" si se incrementeaza la apasarea butonului "Up" .Compararea temperaturii citite cu cea setata se efectueaza corect si functioneaza corect la simulare cu Proteus.Oare este corect ?Nu am posibilitatea de a testa inca real montajul.De fapt ma asteptam ca la o valoare 6536 sa zicem ,sa am afisat ceva cateva grade pe partea de setare.

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