ovy_pas Postat Decembrie 20, 2011 Autor Partajează Postat Decembrie 20, 2011 functiile lui elef testate care functioneaza sunt:void write_eeprom(unsigned int val,unsigned int adr){unsigned char * buffer;buffer=(unsigned char*)&val;eeprom_write (adr, buffer[0]);eeprom_write (adr+1, buffer[1]);}unsigned int read_eeprom(unsigned int adr){unsigned char buffer[2];buffer[0]=eeprom_read (adr);buffer[1] =eeprom_read (adr+1);return *((unsigned int*)buffer);}Multumesc elef.Nu mi-ati raspuns care sunt avatajele sau dezavantajele memoriei falsh vs eeprom. Link spre comentariu
Elef Postat Decembrie 20, 2011 Partajează Postat Decembrie 20, 2011 Sincer n-as face o comparatie intre flashul si eepromul uc-ului.Functiile lor sunt total diferite: flashul iti tine programul, eepromul iti permite sa salvezi diferite date in timpul rularii programului. Link spre comentariu
ovy_pas Postat Decembrie 20, 2011 Autor Partajează Postat Decembrie 20, 2011 "flashul iti tine programul" fii mai explicit te rog, daca poti da un exemplu.. Link spre comentariu
Mix Postat Decembrie 20, 2011 Partajează Postat Decembrie 20, 2011 Ok Elef. Asa este M-am grabit. Acum doar nu e iei ca "atac la persoana". Bine ca s-a clarificat treaba cu pointerii, sa inteleaga si altii. Spor la lucru! Link spre comentariu
Elef Postat Decembrie 20, 2011 Partajează Postat Decembrie 20, 2011 @ovy_pas hex-ul este scris in flash si de acolo se ruleaza direct.@Mix departe de mine gandul a o lua ca un atac la persoana. Link spre comentariu
ovy_pas Postat Decembrie 21, 2011 Autor Partajează Postat Decembrie 21, 2011 PWM max. resolution is 10-bitSe refera la duty cycle PWM = 0 - 1024 ? (2^10 = 1024) Din cate tin minte duty cycle il setam intre 0 - 255 Link spre comentariu
Elef Postat Decembrie 22, 2011 Partajează Postat Decembrie 22, 2011 @ovy_pass informatia pe care o ceri se gaseste in pdf-ul uc-ului(parca ai spus ca e un 16f877).Asa ca in paragraful 8.3.2 vei gasi raspunsul la intrebarea ta. Link spre comentariu
ovy_pas Postat Ianuarie 5, 2012 Autor Partajează Postat Ianuarie 5, 2012 Am vazut ca unele proiecte in C mplab sau in mikroC pot fi scrise pe mai multe fisiere salvate cu extensie .c, am incercat sa realizez un astfel de proiect, de exemplu o functie pe alt fisier care sa fie chemata in fisierul menu si imi da eroare la compilare. Aveti idee cum trebuie realizat ca sa fie compilat cu succes? Link spre comentariu
Liviu M Postat Ianuarie 5, 2012 Partajează Postat Ianuarie 5, 2012 Ca intr-un fisier sa poti folosi functii definite in alte fisiere, trebuie ca in fisierul apelant sa-i spui ca trebuie sa caute functiile in alte fisiere. Pentru asta ori declari ca extern la inceputul fisierului functiile din alte fisiere, ori folosesti un fisier header (cu extensia .h) in care declari (ca extern) functiile din alte fisiere si pe care-l incluzi cu directiva #include Presupunand ca ai un fisier fis1.c in care ai o functie void functieApelata1(void){ //corpul functiei } pe care vrei s-o folosest in fis2.c, atunci fis2.c poate arata asa #include <stdlib.h>extern void functieApelata(void); // cuvantul cheie spune ca functia e definite in alta partevoid main(void){ functieApelata1();} sau poti avea un fisier terminat cu .h, sa zicem specific.h, caz in care programul o sa arate: Fisierul specific.h extern void functieApelata(void); // cuvantul cheie spune ca functia e definite in alta parte Iar fisierul fis2.c va arata #include <stdlib.h>#include "specific.h" //remarci ghilimelele in locul parantezelor ascutite, asta inseamna ca fisierul e cautat in directorul curent void main(void){ functieApelata1();} Cand da de directiva #include, precompilerul ia codul din specific.h si-l copiaza in fis2.c. Avantajul cu fisierele .h e ca poti avea mai multe, pentru fiecare functionalitate cate unul si nu pierzi "vederea de ansamblu". Bineinteles, toate cele trei fisiere (fis1.c, fis2.c si specific.h) trebuie adaugate proiectului. PS Sper ca n-am zis prea multe prostii, eu am folosit doar varianta cu fisiere header. Link spre comentariu
ovy_pas Postat Ianuarie 10, 2012 Autor Partajează Postat Ianuarie 10, 2012 Nu ai spus deloc prostii Liviu_M am incercat si eu cu fisiere de tip .h dar nu mi-a iesit fiindca foloseam parateze ascutite in loc de gilimele, precizez ca a mers si fara cuvantul cheie "extern".La proiectul cu 16f870 afisez ficare cacarter in parte si declar constante unde este cazul sa nu imi pape din RAM dar imi papa din ROM astfel am ajuns cu memoria memoria ROM la maxim. Nu mai spun ca mi-am redus preferintele, nu doresc decat sa fac 5 operatii cu 5 int si 2 float si sa afisez 5 parametrii pe LCD sunt nevoit sa renunt si la variabilele float si sa fac calcule cu int, pierd din precizia rezultatului. ( Este din ce in ce mai evident si clar pentru mine ca acest microcontroler e bun pt instalatii de pom sa aprinzi si sa stingi leduri cu el.)Idei, strategii cum pot opera cu int in loc de float pentru a avea un rezultat cu erori cat mai mici? Link spre comentariu
Liviu M Postat Ianuarie 10, 2012 Partajează Postat Ianuarie 10, 2012 Daca nu e secret, pune si tu codul aici, poate mai vine cate cineva cu idei de optimizare. Referitor la calcule, desi n-am idee prea mare cu ce se mananca, sunt sanse sa iesi mai bine daca faci calculele in virgula fixa decat in virgula mobila. LE Am vazut si eu ca merge si fara calificatorul extern, da' standardul am impresia ca zice sa fie folosit, asa ca poate e mai bine sa-l pui. Link spre comentariu
ovy_pas Postat Ianuarie 10, 2012 Autor Partajează Postat Ianuarie 10, 2012 Nu e nici un secret proiectul cu 16f870 este un PID pentru control temperatura cu afisare parametrii dar nu am reusit sa impletemtez prea multe ma limiteaza resursele microcontrolerului si preferintele mele tot scad. Am adaugat cateva explicatii la ce am facut, daca nu am fost foarte clar pot sa revin cu explicatii. Programul este realizat in MikroC_PIC.// Lcd pinout settings -pinii pt LDCsbit LCD_RS at RB0_bit;sbit LCD_EN at RB1_bit;sbit LCD_D7 at RB5_bit;sbit LCD_D6 at RB4_bit;sbit LCD_D5 at RB3_bit;sbit LCD_D4 at RB2_bit;// Pin directionsbit LCD_RS_Direction at TRISB0_bit;sbit LCD_EN_Direction at TRISB1_bit;sbit LCD_D7_Direction at TRISB5_bit;sbit LCD_D6_Direction at TRISB4_bit;sbit LCD_D5_Direction at TRISB3_bit;sbit LCD_D4_Direction at TRISB2_bit;bit bB_Run, bB_Man, bB_OK, bB_Cancel, bB_Dec, bB_Inc; //declar variabile de tip bitbit bL_Run, bL_Statut, bL_Err, bTiristor;bit bAutomat,bManual, bAvarie;bit M0,M1,M2,M3,M4,M5,M6;unsigned short cnt,ton; // declar variabile tip intint err_new, err_old, err_sum, err_dif;int proces_value, set_point;int kp,ki,kd; // sunt acum int desi le voiam floatint out; // sunt acum int desi le voiam floatconst bit zero; // am incercat sa mai bag ceva in ROM probabil nu e folositchar sute(int nr){ //mi-am creat functie pt afisare sute (pt economie RAM si folosire ROM) LDC_out ia cam mult din RAM return (nr/100);}char zeci(int nr){ //mi-am creat functie pt afisare zeci (pt economie RAM si folosire ROM) LDC_out ia cam mult din RAMreturn (nr/10)-(nr/100)*10;}char unit(int nr) { //mi-am creat functie pt afisare unitati (pt economie RAM si folosire ROM) LDC_out ia cam mult din RAM return nr - (nr/100)*100 - ((nr/10)-(nr/100)*10 )*10 ;}void int_to_lcd(int nr, int r, int p){ //mi-am creat functie pt afisare in care folosesc cele 3 functii pt afisare nr cu 3 digiti pe LCD if (sute(nr)==0) Lcd_Chr(r,p,' '); else Lcd_Chr(r,p,sute(nr)+48); if ( (sute(nr)==0) && (zeci(nr)==0) ) Lcd_Chr(r,p+1,' '); else Lcd_Chr(r,p+1,zeci(nr)+48); Lcd_Chr(r,p+2,unit(nr)+48); } else { Lcd_Chr(r,p-1,'-'); if (sute(nr)==0) Lcd_Chr(r,p,' '); else Lcd_Chr(r,p,sute(nr)*(-1)+48); if ( (sute(nr)==0) && (zeci(nr)==0) ) Lcd_Chr(r,p+1,' '); else Lcd_Chr(r,p+1,zeci(nr)*(-1)+48); Lcd_Chr(r,p+2,unit(nr)*(-1)+48); }}void interrupt() { // intrerupere pe timer0 in care vreau sa calculez PID control temperatura if (T0IF_bit) cnt++; // increment counter TMR0 = 236; // 1ms T0IF_bit = 0; // clear TMR0IF if (cnt>100) { // aici creez un PWM pentru comanda tiristor cnt=0; err_new = set_point - proces_value; err_sum = err_sum + err_new; err_dif = err_new - err_old; out = kp*err_new; //+ ki*err_sum + kd*err_dif ; // nu am reusit sa implementez corect nici macar factorul proportional asa cum trebuie nu mai vorbesc de integrativ si derivativ dupa cum se vede in sintaxa programului. err_old = err_new; if (out< 0) out = 0; if (out> 100) out = 100; ton=out; } if (bAutomat) { RC4_bit = (cnt < ton); //RC4 iesire tiristor rezistenta incalzire } }void write_eeprom(unsigned int val,unsigned int adr){ // Functie scriere epromunsigned char * buffer;buffer=(unsigned char*)&val;eeprom_write (adr, buffer[0]);eeprom_write (adr+1, buffer[1]);}unsigned int read_eeprom(unsigned int adr){ //Functie citire epromunsigned char buffer[2];buffer[0]=eeprom_read (adr);buffer[1] =eeprom_read (adr+1);return *((unsigned int*)buffer);}void main() { //Functie main aci incepe programul TRISA=0b00111111; TRISB=0b00000000; TRISC=0b00001111; //Initializare PORTA=0b00000000; PORTB=0b00000000; PORTC=0b00000000; ADCON0=0b00000000; ADCON1=0b00000100; OPTION_REG=0b10000111; // Assign prescaler to TMR0 INTCON = 0b10100000; // Enable TMRO interrupt TMR0 = 236; // Timer0 initial value cnt = 0; // Initialize cnt Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off RA4_bit=1; RA5_bit=1; RC0_bit=1; RC1_bit=1; RC2_bit=1; RC3_bit=1; set_point = read_eeprom(0x0000); //incarc parametrii din eprom kp = read_eeprom(0x0002); ki = read_eeprom(0x0004); kd = read_eeprom(0x0008); err_new=0; err_old=0; err_sum=0; err_dif=0; out=0; while(1) { //CITIRE INTRARI ANALOGICE proces_value = ADC_Read(0); // citesc temperatura reala //iAnalog1 = ADC_Read(1); //iTemp_cupla = ADC_Read(3); //CITIRE INTRARI DIGITALE // citesc intrarile digitale bB_Run = !RA4_bit; bB_Man = !RA5_bit ; bB_OK = !RC0_bit; bB_Cancel = !RC1_bit; bB_Dec = !RC2_bit; bB_Inc = !RC3_bit; //IESIRI DIGITALE // actualizez iesirile digitale RC7_bit = bL_Run; RC6_bit = bL_Statut; RC5_bit = bL_Err; //RC4_bit = bTiristor; //RESET PARAMETRII if ( bB_OK && bB_Inc) {set_point=0; kp=0; ki=0; kd=0;} // Comanda resetare parametrii in zero Lcd_Chr(1,1,'T'); Lcd_Chr(1,2,'E'); Lcd_Chr(1,3,'M'); Lcd_Chr(1,4,'P'); //Asa afisesz ca sa nu imi pape din RAM cu funtia Lcd_out dar imi papa din ROM int_to_lcd(proces_value,1,12); //lcd_out(1,12,"proces_value"); Lcd_Chr(2,1,'T'); Lcd_Chr(2,2,'A'); Lcd_Chr(2,3,'R'); Lcd_Chr(2,4,'G'); Lcd_Chr(2,5,'E'); Lcd_Chr(2,6,'T'); int_to_lcd(set_point,2,12); if (bB_Cancel > M3) { // La fiecare modificare a valorii unui singur parametru incarc in eprom toti parametrii write_eeprom(set_point,0x0000); write_eeprom(kp, 0x0002); write_eeprom(ki, 0x0004); write_eeprom(kd, 0x0008); } M3 = bB_Cancel; Delay_ms(100); // intarziere de 100 ms } } Link spre comentariu
Liviu M Postat Ianuarie 10, 2012 Partajează Postat Ianuarie 10, 2012 N-am prea mult timp, asa ca nu o sa scriu decat cateva chestii care mi-au sarit repede in ochi. Cred ca functiile de calculat zecile & unitatile sunt cam stufoase. S-ar putea ca variantele mele sa fie mai "economice". char sute(int nr){ //mi-am creat functie pt afisare sute (pt economie RAM si folosire ROM) LDC_out ia cam mult din RAM return (nr/100);} Sutele asa-mi dau si mie. char zeci(int nr){ //mi-am creat functie pt afisare zeci (pt economie RAM si folosire ROM) LDC_out ia cam mult din RAM return (nr/10)-(nr/100)*10;}Varianta mea char zeci(int nr){ return ((nr/10)%10); //restul impartirii de 2 ori la 10; dupa prima impartire ramane un intreg} char unit(int nr) { //mi-am creat functie pt afisare unitati (pt economie RAM si folosire ROM) LDC_out ia cam mult din RAM return nr - (nr/100)*100 - ((nr/10)-(nr/100)*10 )*10 ;} Si aici varianta mea e, cred, mai buna - rezultatul e restul impartirii cu 10: char zeci(int nr){ return (nr%10); } if (sute(nr)==0) Lcd_Chr(r,p,' '); else Lcd_Chr(r,p,sute(nr)+48); Aici e OK, da' cred ca e mai clar daca in loc de 48 (codul lui 0), folosesti '0' (carecterul 0), sunt echivalente. if (sute(nr)==0) Lcd_Chr(r,p,' '); else Lcd_Chr(r,p,sute(nr)+'0');Cand testezi intreruperile e bine ca testul sa-l faci nu numai dupa flagul corespunzator, ci si dupa starea intreruperii (activa/dezactiva), pentru ca cele mai multe flaguri sunt setate si cand intreruperile corespunzatoare sunt incative. Si daca ai alte intreruperi active, te trezesti cu rezultate ciudate.Cu alte cuvinte, in loc de void interrupt() { // intrerupere pe timer0 in care vreau sa calculez PID control temperatura if (T0IF_bit) cnt++; // increment counter TMR0 = 236; // 1ms T0IF_bit = 0; // clear TMR0IF as scrie void interrupt() { // intrerupere pe timer0 in care vreau sa calculez PID control temperatura if (T0IF_bit && T0IE_bit) // sper ca T0IE_bit exista { cnt++; // increment counter TMR0 = 236; // 1ms T0IF_bit = 0; // clear TMR0IF } A propos, cred ca ai uitat acoladele inainte de cnt++ si dupa T0IF_bit. Mai departe, data viitoare. Link spre comentariu
ovy_pas Postat Ianuarie 11, 2012 Autor Partajează Postat Ianuarie 11, 2012 Multumesc Liviu M optimizarile recomandate m-au ajutat, am recuperat 3% la RAM si 3% la ROM.Astept si alte observatii daca sunt. Link spre comentariu
Liviu M Postat Ianuarie 11, 2012 Partajează Postat Ianuarie 11, 2012 La afisarea p LCD, eu mi-am scris propriile functii (total). La inceput am avut o singura functie care afisa un caracter (lcdScrieChar(unsigned char caracter)). Dupaun timp, folosind functia de afisat caractere, mi-am scris o functie de afisat siruri void lcdScrieSir(unsigned char *sir){ while(*sir) { lcdScrieChar(*sir); *sir++; }}functie pe care am folosit-o sa afisez siruri. Spres surprinderea mea, desi foloseam si functia strcpy sa generez sirurile de afisat, codul generat era mai mic decat daca apelam functie de afisat caractere pentru fiecare litera din mesaj. Cu alte cuvinte, dupa compilare codul unsigned char ucSir[20];...strcpy(ucSir, "Mesaj");lcdScrieSir(ucSir);era mai mic decat lcdScrieSir('M');lcdScrieSir('e');lcdScrieSir('s');lcdScrieSir('a');lcdScrieSir('j');E oarecum de astepatat (sunt sanse ca functiile mele sa nu fie prea optimizate), da' efectul a fost mai mare decat speram. Poti sa incerci si tu ceva de genul asta. LE Daca out (variabila din interrupt) e intre 0 si 100, de ce nu o faci pe 8 biti? S-ar putea ca intrebarea sa fie valabila si pentru alte variabile. 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