Jump to content
ELFORUM - Forumul electronistilor

probleme cu lcd 2x16 incepator


Guest freeenergy

Recommended Posts

Guest freeenergy

Sunt foarte nou in microcontrolere si in programare in primul rand da imi trebuie ca vine licentza shi vreau sa prezint ceva practic.Am Atmega8535 cu 16Mhz quartzu shi afishez temperatura pe un lcd cu 2x16 caractere, programez in c cu avrstudio, programu este cel de mai jos care merge brici da functioneaza un timp dupa care inceteaza sa mai afisheze pe lcd si ramane ultima valoare care a fost afisata:#include #asm .equ __lcd_port=0x12 ;PORTD#endasm#include #include #include #define ADC_VREF_TYPE 0xC0 // Read the AD conversion resultunsigned int read_adc(unsigned char adc_input){ADMUX=adc_input|ADC_VREF_TYPE;// Start the AD conversionADCSRA|=0x40;// Wait for the AD conversion to completewhile ((ADCSRA & 0x10)==0);ADCSRA|=0x10;return ADCW;} print(float temp) { int j[4]; char i[6]; int a=0; j[0]=floor(temp/100); j[1]=floor(temp/10-(j[0]*10)); j[2]=floor(temp-(j[0]*100)-(j[1]*10)); j[3]=floor((temp-(j[0]*100)-(j[1]*10)-j[2])*10); if(j[0]==0) i[0]=' '; else i[0]=j[0]|0x30 ; if(j[1]==0&&j[0]==0) i[1]=' '; else i[1]=j[1]|0x30; i[2]=j[2]|0x30; i[3]=','; i[4]=j[3]|0x30; i[5]=0xdf; for(a=0;a<5;a++) { lcd_gotoxy(5+a,0); lcd_putchar(i[a]); delay_ms(10); }; return; } // Declare your global variables herevoid main(void){ float temp=0;// Declare your local variables here// Input/Output Ports initialization// Port A initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00;DDRA=0x00;/// Port B initialization// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTB=0x00;DDRB=0x0F;// Port C initialization// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00;DDRC=0xFF;// Port D initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00;DDRD=0x00;// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: Timer 0 Stopped// Mode: Normal top=FFh// OC0 output: DisconnectedTCCR0=0x00;TCNT0=0x00;OCR0=0x00;// Timer/Counter 1 initialization// Clock source: System Clock// Clock value: Timer 1 Stopped// Mode: Normal top=FFFFh// OC1A output: Discon.// OC1B output: Discon.// Noise Canceler: Off// Input Capture on Falling Edge// Timer 1 Overflow Interrupt: Off// Input Capture Interrupt: Off// Compare A Match Interrupt: Off// Compare B Match Interrupt: OffTCCR1A=0x00;TCCR1B=0x00;TCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;OCR1AH=0x00;OCR1AL=0x00;OCR1BH=0x00;OCR1BL=0x00;// Timer/Counter 2 initialization// Clock source: System Clock// Clock value: Timer 2 Stopped// Mode: Normal top=FFh// OC2 output: DisconnectedASSR=0x00;TCCR2=0x00;TCNT2=0x00;OCR2=0x00;// External Interrupt(s) initialization// INT0: Off// INT1: Off// INT2: OffMCUCR=0x00;MCUCSR=0x00;// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x00;// Analog Comparator initialization// Analog Comparator: Off// Analog Comparator Input Capture by Timer/Counter 1: OffACSR=0x80;SFIOR=0x00; // ADC initialization// ADC Clock frequency: 125,000 kHz// ADC Voltage Reference: Int., cap. on AREF// ADC High Speed Mode: Off// ADC Auto Trigger Source: Free RunningADMUX=ADC_VREF_TYPE;ADCSRA=0xA7;SFIOR&=0x0F; // 2 lines & 16 columnslcd_init(16);// go on the second LCD linelcd_gotoxy(0,0);// display the messagelcd_putsf("temp= C");lcd_gotoxy(10,0);lcd_putchar(0xdf); //semn de grade// LCD module initialization while(1) { temp=read_adc(1); temp=temp*2.56/10.24; print(temp);delay_ms(500);// }; // Place your code here }deci functioneaza bine , imi afiseaza temperatura de la un lm35 chiar foarte precis (am verificat cu un termostream si cu un termometru de laborator cu termocuplu) merge ce merge si dupa cateva zeci de minute , cateoadata si ore , nu mai trimite microcontroleru nimic la lcd , lcd-u ramane cu "scrisu" de ultima data.Recunosc ca nu am optimizat nimic dar ma intereseaza sa functioneze bine si pe perioade lungi. Cineva o idee , i s-a mai intamplat cuiva?

Link to comment
Share on other sites

Ce functie este floor() ?Later edit: am gasit in avr libc, dar nu inteleg de ce folosesti ca parametru float, ca oricum il convertesti in integer. Dar asta nu poate fii motivul pentru care se bloceaza programul.

Link to comment
Share on other sites

Guest freeenergy

ala e codevision avr, nush de ce am scris avrstudio , cred ca eram beat :nebunrau: Moare cateodata intr-o jumate de minut , cateodata intro ora cateodata in mai multe ore , nu are un timp anume. Are fro treaba pinu de reset de la microcontroler ?ca eu il am in aer, da oricum alte programe miau mers ca primadata afisham pe digiti si ala mergea nonstop, doar la lcd am probleme.floor() face ca un numar cu zecimale sa ti-l rotunjeasca in jos exp:floor(2.9348573984)=2, este in , float folosec de prost , nu m-a dus mintea sa mai inmultesc cu 10 in main temperatura(oricum am zis ca nu am optimizat nimic),tot principiul asta l-am folosit si la afisarea pe digiti si ala mergea brici non-stop.

Link to comment
Share on other sites

Atunci cred am rezolvat problema :), pinul reset trebuie sa aiba o stare bine definita, adica leaga un 10K si 100nf in serie (10k la + si 100n la masa), pinul resete il legi intre rezistenta si condensator. (vezi schema atasata)[attachment=0]reset.jpg[/attachment]

Link to comment
Share on other sites

Guest freeenergy

se pare ca nici asha nu merge , da oricum pinu de reset (PINC.6)este pus ca output deci nu cred ca ar fi problema de la asta .Ma gandesc sa nu fie ceva de pe la lcd ,ca daca afishez pe "Seven segment display" imi merge struna, ma gandesc sa schimb quartzu sa pun de frecventa mai mica poate e ceva cu transmisia la lcd, sau stiti cum sa dau rata de transfer de date catre lcd mai mica?AAAAA culmea uite ca pasta tocmai acum am vazut-o daca il las blocat asha dupa cateva zeci de minute incepe sa mearga iar.

Link to comment
Share on other sites

Guest freeenergy

lcd-ul sigur functioneaza impecabil ? :)

intreabal pe producator care cred ca e chinez :da ca nu vad nici un nume de firma pe el , era 30 de lei pe Maica Domnului. Treaba e ca mi se blocheaza programu ca daca pun si lcd-u si alea cu 7 segmente cand se blocheaza nu mai imi afiseaza nici ala nici ala.
Link to comment
Share on other sites

Guest freeenergy

ms ptr program, nu am gasit nimic merge perect si pe perioada lunga, inseamna ca e hardware. Ma gandesc la doua posibilatati 1. ori e cablu prea lung (40cm)de la lcd,2. ori e frecventa prea mare de transmisie a datelor la lcd (presupun ca frecventa este proportionala cu frecventa de ceas de la microcontroller)"mie ca scapa biti pe drum " si da fro eroare ceva da face ca programu sa numai continue.Programu si ptr lcd si ptr afisaj cu 7 segmente ese urmatoru (afisaju cu 7 segmente merge bine numai cand sunt puse fara lcd):#include #asm .equ __lcd_port=0x12 ;PORTD#endasm#include #include #include #define ADC_VREF_TYPE 0xC0 #define timp 2 // Read the AD conversion resultunsigned int read_adc(unsigned char adc_input){ADMUX=adc_input|ADC_VREF_TYPE;// Start the AD conversionADCSRA|=0x40;// Wait for the AD conversion to completewhile ((ADCSRA & 0x10)==0);ADCSRA|=0x10;return ADCW;} verificare(int r){ if (r==0) PORTC=0x81; else if (r==1) PORTC=0xE7; else if (r==2) PORTC=0x92; else if (r==3) PORTC=0xC2; else if (r==4) PORTC=0xE4; else if (r==5) PORTC=0xC8; else if (r==6) PORTC=0x88; else if (r==7) PORTC=0xE3; else if (r==8) PORTC=0x80; else PORTC=0xC0; } print(float temp) { int j[4]; char i[6]; int a=0; j[0]=floor(temp/100); j[1]=floor(temp/10-(j[0]*10)); j[2]=floor(temp-(j[0]*100)-(j[1]*10)); j[3]=floor((temp-(j[0]*100)-(j[1]*10)-j[2])*10); if(j[0]==0) i[0]=' '; else i[0]=j[0]|0x30 ; if(j[1]==0&&j[0]==0) i[1]=' '; else i[1]=j[1]|0x30; i[2]=j[2]|0x30; i[3]=','; i[4]=j[3]|0x30; i[5]=0xdf; for(a=0;a<5;a++) { lcd_gotoxy(5+a,0); lcd_putchar(i[a]); delay_ms(10); }; return; } afishaj(float *nr) { float n=0; int a,b,c,d,i; n=*nr; for(i=0;i<10;i++) { PORTB=0x00; PORTC=0xFF; a=floor(n/100); verificare(a); if (a==0) PORTC=0xFF; PORTB=0x08; delay_ms(timp); b=floor((n-a*100)/10); PORTB=0x00; verificare(b); if (a==0&&b==0) PORTC=0xFF; PORTB=0x04; delay_ms(timp); c=floor(n-a*100-b*10); PORTB=0x00; verificare©; PORTC=PORTC&0x7F; PORTB=0x02; delay_ms(timp); d=(n-a*100-b*10-c)*10; PORTB=0x00; verificare(d); PORTB=0x01; delay_ms(timp); }; } // Declare your global variables herevoid main(void){ float temp=0;// Declare your local variables here// Input/Output Ports initialization// Port A initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00;DDRA=0x00;/// Port B initialization// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTB=0x00;DDRB=0x0F;// Port C initialization// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00;DDRC=0xFF;// Port D initialization// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00;DDRD=0x00;// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: Timer 0 Stopped// Mode: Normal top=FFh// OC0 output: DisconnectedTCCR0=0x00;TCNT0=0x00;OCR0=0x00;// Timer/Counter 1 initialization// Clock source: System Clock// Clock value: Timer 1 Stopped// Mode: Normal top=FFFFh// OC1A output: Discon.// OC1B output: Discon.// Noise Canceler: Off// Input Capture on Falling Edge// Timer 1 Overflow Interrupt: Off// Input Capture Interrupt: Off// Compare A Match Interrupt: Off// Compare B Match Interrupt: OffTCCR1A=0x00;TCCR1B=0x00;TCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;OCR1AH=0x00;OCR1AL=0x00;OCR1BH=0x00;OCR1BL=0x00;// Timer/Counter 2 initialization// Clock source: System Clock// Clock value: Timer 2 Stopped// Mode: Normal top=FFh// OC2 output: DisconnectedASSR=0x00;TCCR2=0x00;TCNT2=0x00;OCR2=0x00;// External Interrupt(s) initialization// INT0: Off// INT1: Off// INT2: OffMCUCR=0x00;MCUCSR=0x00;// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x00;// Analog Comparator initialization// Analog Comparator: Off// Analog Comparator Input Capture by Timer/Counter 1: OffACSR=0x80;SFIOR=0x00; // ADC initialization// ADC Clock frequency: 125,000 kHz// ADC Voltage Reference: Int., cap. on AREF// ADC High Speed Mode: Off// ADC Auto Trigger Source: Free RunningADMUX=ADC_VREF_TYPE;ADCSRA=0xA7;SFIOR&=0x0F; // 2 lines & 16 columnslcd_init(16);// go on the second LCD linelcd_gotoxy(0,0);// display the messagelcd_putsf("temp= C");lcd_gotoxy(10,0);lcd_putchar(0xdf);// LCD module initialization while(1) { temp=read_adc(1); temp=(temp*2.56/10.24); print(temp);//delay_ms(500);afishaj(&temp); }; // Place your code here }Cum fac sa scad viteza datelor catre lcd ?

Link to comment
Share on other sites

Incearca sa pui din loc in loc in diverse functii cate-un led (diferit) sa se aprinda (sau macar portul ... sa-i modifici valoarea) ca sa poti deduce dupa mai multe teste, in functie de ledul care ramane aprins... unde a ramas blocat codul;Ma gandesc ca daca, cu acelasi program, doar deconectand lcd-ul de la fire, uC-ul NU se blocheaza, inseamna ca motivul blocajului uC-ului este datorat prezentei lcd-ului, nu programului; In cazul asta, din cate am impresia, singurul moment in care uC-ul primeste informatii de la lcd este in functia interna librariei lcd.lib de genul lcd_ready .. say lcd_wait Poate moare chiar acolo.... sau cine stie ce alta idee...Cu toate ca nu e relevant, ca softul pare sa mearga ... incearca sa pui tip de date (macar void ) la functii si sa mai simplifici codul, poate e ceva ce nu-i place lui code vision avr (de exemplu sa nu folosesti pointer la "afishaj" si .. ce s-o mai putea); Tot la soft poate mai gasesti ceva prin setarile lui CVavr referitor la optimizarea codului ...

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...
Guest freeenergy

Scuze ca nu am mai scris da nu am mai avut timp sa mai fac nimic in ultima vreme, observ acuma ca toata treaba era de la soclu unde pun microcontroleru. Sa nu va cumparati soclu care are gauri metalice unde intra pinu integratului :speriat , luati-va dala cu lamele.Acuma am alta problema: vreau sa fac fast pwm si fac intrerupere la overflow si la output compare, treaba e ca mie nu imi realizeaza nici o intructiune din intreruperile alea am verificat cu osciloscopu pini A.2 ai A.3 si draci nu scoate nici un semnal. Instructiunea :interrupt [TIM0_COMP] void timer0_comp_isr(void){ }realizeaza intrerupere cand valoarea timerului ajunge la OCR0 nu? ca eu cel putin asha am inteles . Si mai e o chestie cand citesc cu "read_adc(0) " imi strica si valoarea citita cu "read_adc(1)" si imi afiseaza pe lcd un numar care nu vad ca mai depinde de nimic. Folosesc read_adc(0) pentru a face o dependenta intre OCR0 si valoarea analogica citita astfel incat sa maresc sau sa micsorez pulsu dintr-un potentiometru pus pe ADC0 si am pus pe PINA.2 si PINA.3 leduri.codu ptr timeri este cel care urmeaza :#include #asm .equ __lcd_port=0x12 ;PORTD#endasm#include #include #include #define ADC_VREF_TYPE 0xC0 #define timp 2 //Timer 0 overflow interrupt service routineinterrupt [TIM0_OVF] void timer0_ovf_isr(void){// Reinitialize Timer 0 valueTCNT0=0xFF;// Place your code here PORTA=0x0C;}// Timer 0 output compare interrupt service routineinterrupt [TIM0_COMP] void timer0_comp_isr(void){// Place your code herePORTA=0x00;} // Read the AD conversion resultunsigned int read_adc(unsigned char adc_input){ ADMUX=adc_input|ADC_VREF_TYPE;// Start the AD conversionADCSRA|=0x40;// Wait for the AD conversion to completewhile ((ADCSRA & 0x10)==0);ADCSRA|=0x10;return ADCW;} print(int temp) { int j[4]; char i[6]; int a=0; j[0]=floor(temp/1000); j[1]=floor(temp/100-(j[0]*100)); j[2]=floor(temp-(j[0]*1000)-(j[1]*100)); j[3]=floor(temp-(j[0]*1000)-(j[1]*100)-j[2]*10); if(j[0]==0) i[0]=' '; else i[0]=j[0]|0x30 ; if(j[1]==0&&j[0]==0) i[1]=' '; else i[1]=j[1]|0x30; i[2]=j[2]|0x30; i[3]=','; i[4]=j[3]|0x30; i[5]=0xdf; for(a=0;a<5;a++) { lcd_gotoxy(5+a,0); lcd_putchar(i[a]); delay_ms(timp); }; return; } // Declare your global variables herevoid main(void){ float temp=0;// int pwmcut=0;// Declare your local variables here// // Input/Output Ports initialization// Port A initialization// Func7=In Func6=In Func5=In Func4=In Func3=out Func2=out Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=T State0=T PORTA=0x00;DDRA=0x0C;/// Port B initialization// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTB=0x00;DDRB=0x0F;// Port C initialization// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00;DDRC=0xFF;// Port D initialization// Func7=out Func6=out Func5=out Func4=out Func3=out Func2=out Func1=out Func0=out // State7=o State6=0 State5=0 State4=0 State3=o State2=0 State1=0 State0=0 PORTD=0x00;DDRD=0xFF;// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 2000,000 kHz// Mode: Fast PWM top=FFh// OC0 output: DisconnectedTCCR0=0x4B;TCNT0=0xFF;OCR0=0x77;// Timer/Counter 1 initialization// Clock source: System Clock// Clock value: Timer 1 Stopped// Mode: Normal top=FFFFh// OC1A output: Discon.// OC1B output: Discon.// Noise Canceler: Off// Input Capture on Falling Edge// Timer 1 Overflow Interrupt: Off// Input Capture Interrupt: Off// Compare A Match Interrupt: Off// Compare B Match Interrupt: OffTCCR1A=0x00;TCCR1B=0x00;TCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;OCR1AH=0x00;OCR1AL=0x00;OCR1BH=0x00;OCR1BL=0x00;// Timer/Counter 2 initialization// Clock source: System Clock// Clock value: Timer 2 Stopped// Mode: Normal top=FFh// OC2 output: DisconnectedASSR=0x00;TCCR2=0x00;TCNT2=0x00;OCR2=0x00;// External Interrupt(s) initialization// INT0: Off// INT1: Off// INT2: OffMCUCR=0x00;MCUCSR=0x00;// Timer(s)/Counter(s) Interrupt(s) initializationTIMSK=0x03;// Analog Comparator initialization// Analog Comparator: Off// Analog Comparator Input Capture by Timer/Counter 1: OffACSR=0x80;SFIOR=0x00; // ADC initialization// ADC Clock frequency: 125,000 kHz// ADC Voltage Reference: Int., cap. on AREF// ADC High Speed Mode: Off// ADC Auto Trigger Source: Free RunningADMUX=ADC_VREF_TYPE;ADCSRA=0xA7;SFIOR&=0x0F; // 2 lines & 16 columnslcd_init(16);// go on the second LCD linelcd_gotoxy(0,0);// display the messagelcd_putsf("temp= C");lcd_gotoxy(10,0);lcd_putchar(0xdf);// LCD module initialization // Global enable interrupts#asm("sei") while(1) { temp=read_adc(1); temp=(temp*2.56/1.024); print(floor(temp));delay_ms(500);//afishaj(temp);//pwmcut=read_adc(1)/1024;//OCR0=pwmcut; }; // Place your code here }

Link to comment
Share on other sites

Guest freeenergy

am gasit problema cu pwm-u meu// Reinitialize Timer 0 valueTCNT0=0xFF; nu mai tre pusa , asta mi-o genera codevision si imi face ca atunci cand face intrerupere la overflow sareinitializeze timeru la 0xFF si se intampla dinou intreruperea deci cumva intra intr-o bucla infinita

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines