csongore Postat Februarie 3, 2018 Partajează Postat Februarie 3, 2018 Salutare am o mica problema cu un program pentru PIC16F877A se reseteaza simularea in Proteus la citirea ultimului curent si nu stiu de ce. Daca scot citirea de curent pe ultima faza nu se mai reseteaza.In mikro C nu am nici o eroare.Daca aveti ceva ideii? // LCD module connections 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; // End LCD module connections unsigned int Tensiune,curent1,curent2,curent_medie; unsigned long u,i; unsigned char ch; void main() { TRISA = 0xFF; // designate PORTA as input INTCON = 0; // Disable all interrupts IRP_bit = 0 ; Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Cmd(_LCD_CLEAR); // Clear display Delay_ms(100); LCD_Out(1,3,"VOLT/AMPERMETRU"); LCD_Out(3,3,"**By CsOnGoRe**"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); LCD_Out(1, 8,"R="); LCD_Out(2, 8,"R="); LCD_Out(3, 1,"S="); LCD_Out(4, 1,"S="); LCD_Out(3, 14,"T="); LCD_Out(4, 14,"T="); while (1) { // Citire Tensiune 1 Tensiune=ADC_read(0); // get ADC value for U from channel 1 u=(long)Tensiune*3500; // covert adc reading to milivolts u=u/1023; // 0..1023 -> 0-3500mV ch=u/1000; // extract 10.00 U digit if (ch==0) { LCD_Chr(1,11, 32); // write empty space if digit is 0 } else { LCD_Chr(1,11,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 ch=(u/10) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('V'); // write 'V' at cursor point //Curent 1 curent1=ADC_read(1); // get ADC value for U from channel 1 Delay_ms(50); curent2=ADC_read(1); // get ADC value for U from channel 1 Delay_ms(50); curent_medie=(curent1+curent2)/2; i=(long)curent_medie*2000; // covert adc reading to milivolts i=i/1023; // 0..1023 -> 0-2000mV ch=i/10000; // extract 10.00 U digit if (ch==0) { LCD_Chr(2,10, 32); // write empty space if digit is 0 } else { LCD_Chr(2,10,48+ch); // write ASCII digit at 1st row, 2nd column } ch=(i/1000) %10; // extract 01.00 U digit LCD_Chr_CP(48+ch); ch=(i/100) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point ch=i %10; // extract 00.01 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('A'); // Citire Tensiune 2 Tensiune=ADC_read(2); // get ADC value for U from channel 1 u=(long)Tensiune*3500; // covert adc reading to milivolts u=u/1023; // 0..1023 -> 0-3500mV ch=u/1000; // extract 10.00 U digit if (ch==0) { LCD_Chr(3,4, 32); // write empty space if digit is 0 } else { LCD_Chr(3,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 ch=(u/10) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('V'); // write 'V' at cursor point //Curent 2 curent1=ADC_read(3); // get ADC value for U from channel 1 Delay_ms(50); curent2=ADC_read(3); // get ADC value for U from channel 1 Delay_ms(50); curent_medie=(curent1+curent2)/2; i=(long)curent_medie*2000; // covert adc reading to milivolts i=i/1023; // 0..1023 -> 0-2000mV ch=i/10000; // extract 10.00 U digit if (ch==0) { LCD_Chr(4,3, 32); // write empty space if digit is 0 } else { LCD_Chr(4,3,48+ch); // write ASCII digit at 1st row, 2nd column } ch=(i/1000) %10; // extract 01.00 U digit LCD_Chr_CP(48+ch); ch=(i/100) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point ch=i %10; // extract 00.01 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('A'); // Citire Tensiune 3 Tensiune=ADC_read(4); // get ADC value for U from channel 1 u=(long)Tensiune*3500; // covert adc reading to milivolts u=u/1023; // 0..1023 -> 0-3500mV ch=u/1000; // extract 10.00 U digit if (ch==0) { LCD_Chr(3,17, 32); // write empty space if digit is 0 } else { LCD_Chr(3,17,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 ch=(u/10) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('V'); // write 'V' at cursor point //Curent 3 curent1=ADC_read(5); // get ADC value for U from channel 1 Delay_ms(50); curent2=ADC_read(5); // get ADC value for U from channel 1 Delay_ms(50); curent_medie=(curent1+curent2)/2; i=(long)curent_medie*2000; // covert adc reading to milivolts i=i/1023; // 0..1023 -> 0-2000mV ch=i/10000; // extract 10.00 U digit if (ch==0) { LCD_Chr(4,16, 32); // write empty space if digit is 0 } else { LCD_Chr(4,16,48+ch); // write ASCII digit at 1st row, 2nd column } ch=(i/1000) %10; // extract 01.00 U digit LCD_Chr_CP(48+ch); ch=(i/100) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point ch=i %10; // extract 00.01 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('A'); }} Link spre comentariu
Mircea Postat Februarie 5, 2018 Partajează Postat Februarie 5, 2018 Nu ai oferit toate detaliile cat sa fie clar ce si cum. Dar, 1. Ce face watchdog-ul? Cum e setat? Daca pui asta face la fel? LCD_Chr_CP('V'); // write 'V' at cursor point asm clrwdt end; //Curent 3 2. Contrar credintei larg raspandite pe Internet ca sunt 1023 valori, de la 0 la 1023 sunt 1024 valori, e mai corect asa: u=u/1024; // 0..1023 -> 0-3500mV 3. ADC_Read(x) este echivalentul lui: ADC_Init() ADC_Get_Sample(x) De ce sa tot initializezi ADC-ul la fiecare citire? Stiu ca aici nu conteaza viteza de executie, dar poate alta data... Deci, se scrie asa: void main() { ADC_Init() while (1) { // Citire Tensiune 1 Tensiune=ADC_Get_Sample(0); // get ADC value for U from channel 1 4. Vad ca faci medieri de citiri cu intarzieri intre citiri. Felul cum o faci (si o afisezi) iti va rezulta in valori care clipesc pe ecran. Da, la cate sute de ms adunate ai acolo pentru o executie de ciclu complet, au sa clipeasca. Ai putea opta pentru supraesantionare (eu nu te pot ajuta in MikroC, caci lucrez in Mikrobasic, dar Florin are aici codul https://forum.mikroe.com/viewtopic.php?t=20393). Altfel, faci o bucla For si citesti n valori (sa zicem 50-100). Doar 2 valori la 50ms mi se pare prea intamplator. In orice caz, ca sa eviti clipirea, va trebui sa citesti ADC-ul si sa vezi daca noua valoare difera de precedenta (alta variabila va fi buffer-ul precedentei). Daca ai aceeasi valoare nu mai scrii pe ecran. Astfel ai sa ai update de ecran doar daca valoarea variaza intradevar. Foloseste butonul CODE (ala de arata <>) in editorul full. Se intelege mai bine codul. Opinie personala: pune totul pe un breadboard, cine stie ce setari ai in simulator. 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