Vizitator mike59 Postat August 1, 2010 Partajează Postat August 1, 2010 Rog pe cei mai experimentati in lucrul cu MCU si utilizatori ai compilatorului Mikrobasic 7.0, daca au intalnit Warning-ul 0:240 W-0 Array has been split over two banks: _floattostr_local_pref0:246 W-0 Array has been split over two banks: _floattostr_local_suff0:260 W-0 Array has been split over two banks: _floattostr_local_pref 0:268 W-0 Array has been split over two banks: _floattostr_local_pref etc.si daca au rezolvat, cum au rezolvat aparitia unei astfel de erori.Desi este vorba de un Warning, in momentul in care se doreste afisarea acelei variabile float pe un LCD, se afiseaza aiurea pitici.Stiu ca eroarea este specifica PIC16F si dispare la 18F din cauza renuntarii la alocarea memoriei in Bank-uri .Mie personal imi face figura asta un PIC16F876.Cum sa evit splitt-area definirii variabilelor pe mai multe bank-uri ?Multumesc anticipat !!! Link spre comentariu
nooob64 Postat August 1, 2010 Partajează Postat August 1, 2010 Pune codul sa vedem daca nu depasesti ceva ... Link spre comentariu
Vizitator mike59 Postat August 2, 2010 Partajează Postat August 2, 2010 Program_Circuit_protectie sub procedure citValPrag(dim byref prag as string[3]) 'Citeste praguri tensiune de la Keypad dim i as byte dim kp as byte dim ky as char for i = 0 to 2 while True kp = KeyPad_Released() select case kp case 1 ky = "1" break case 2 ky = "4" break case 3 ky = "7" break case 4 ky = "*" break case 5 ky = "2" break case 6 ky = "5" break case 7 ky = "8" break case 8 ky = "0" break case 9 ky = "3" break case 10 ky = "6" break case 11 ky = "9" break case 12 ky = "#" break end select wend Lcd_chr_CP(ky) prag = ky next i end sub sub procedure pDelayOneMin(dim limita as float, dim byref afiseaza as string[17]) 'Procedura introduce o intârziere de 1 minut. dim idisp as string[6] dim i as integer for i = 1 to 60 delay_ms(1000) ByteToStr(i,idisp) Lcd_Out(1,1,"Limita prag !") FloatToStr(limita,afiseaza) Lcd_Out(2,6,afiseaza) Lcd_Out(2,1,idisp) next i end sub sub procedure pShow(dim deafisat as float, dim byref afiseaza as string[17]) 'Procedura afiseaza o valoare tip float pe LCD FloatToStr(deafisat,afiseaza) Lcd_Out(2,6,afiseaza) delay_ms(1000) 'reduce palpairea end sub sub function pWait() as byte 'Procedura determinã asteptarea apãsãrii unei taste dim p as byte while True p = Keypad_Released() if p then break end if wend result = p end sub sub function daNu() as byte 'Functia întoarce optiunea userului 'Dacã userul apasã tasta 1 rãspunsul semnificã True adicã DA 'Dacã userul apasã tasta 0 rãspunsul semnificã False adicã NU dim p as byte While True p = KeyPad_Released() if p = 1 then 'Apasat tasta 1 Da break end if if p = 8 then 'Apasat tasta 0 Nu break end if wend result = p end sub sub procedure dPraguriVector(dim byref pInf as string[3], dim byref pSup as string[3]) 'Procedura afiseaza pragurile citite din vector pe LCD imediat dupa setare dim i as byte Lcd_Cmd(LCD_CLEAR) Lcd_Out(1,1,"Prag inf: ") For i = 0 to 2 Lcd_Chr_CP(pInf) next i Lcd_Out_CP(" V") Lcd_Out(2,1,"Prag sup: ") For i = 0 to 2 Lcd_Chr_CP(pSup) next i Lcd_Out_CP(" V") end sub sub procedure dPraguriEEPROM(dim byref pInf as string[3], dim byref pSup as string[3]) 'Procedura afiseaza pragurile scrise in EEPROM dim i as byte Lcd_Out(1,1,"Prag inf: ") For i = 0 to 2 Lcd_Chr_CP(EEprom_read(i)) pInf = EEprom_read(i) next i Lcd_Out_CP(" V") Lcd_Out(2,1,"Prag sup: ") For i = 0 to 2 Lcd_Chr_CP(EEprom_read(i+3)) pSup = EEprom_read(i+3) next i Lcd_Out_CP(" V") end sub sub procedure ScriereEEPROM(dim byref pInf as string[3], dim byref pSup as string[3]) 'Procedura de scriere in EEPROM a celor doua praguri dim i as byte for i =0 to 2 EEprom_write(i, pInf) EEprom_write(i+3, pSup) next i end sub '35 de bytes dim disp as string[17] dim pInf as string[6] dim pSup as string[6] dim idisp as string[6] '17 bytes dim rez as float dim lInfSup as float dim i as byte dim kp as byte dim flag as byte dim temp_res as word dim lInf as float dim lSup as float main: 'Conectare LCD 'D7 › portb.7 -> 28 'D6 › portb.6 -> 27 'D5 › portb.5 -> 26 'D4 › portb.4 -> 25 'E › portb.3 -> 24 'RS › portb.2 -> 23 'RW › portb.0 -> 21 'Pentru acest tip de MCU asa cum este specificat in datasheet trebuie setat LVP Off pentru cã în 'caz contrar pinul B3 nu se poate programa ca pin I/O PORTA = 0 PORTB = 0 PORTC = 0 TRISA = 0xFF TRISB = 0x00 TRISC = 0xFF CCP1CON = 0 'Comparatoare si PWM Off CCP2CON = 0 ADCON0 = 0xB0 ADCON1 = 0x80 ADRESH = 0 ADRESL = 0 pInf = " " pSup = " " Lcd_Init(PORTB) Keypad_Init(PORTC) Lcd_Cmd(LCD_CLEAR) ' Clear display Lcd_Cmd(LCD_CURSOR_OFF) ' Cursor off Lcd_Out(1,6,"Hello !") delay_ms(1000) 'Afisare praguri setate din EEPROM daca sunt, daca nu apar niste dreptunghiuri la afisare dPraguriEEPROM(pInf, pSup) 'Asteapta apasarea unei taste kp = pWait() Setare_limite: Lcd_Cmd(LCD_CLEAR) Lcd_Out(1,1,"Setare limite ?" ) Lcd_Out(2,1,"0->Nu,1->Da: ") 'Preia raspunsul utilizatorului kp = daNu( ) if kp = 1 then Setare_prag_inferior: Lcd_Cmd(LCD_CLEAR) Lcd_Out(1,1,"Prag inf: XXX V") Lcd_Out(2,1," ") citValPrag(pInf) Lcd_Cmd(LCD_CLEAR) Lcd_Out(1,1,"Prag Inf: ") For i = 0 to 2 Lcd_Chr_CP(pInf) next i Lcd_Out_CP(" V") Lcd_Cmd(LCD_CURSOR_OFF) Lcd_out(2,1,"Este corect ?") kp = daNu() if kp = 8 then goto Setare_prag_inferior end if Setare_prag_superior: Lcd_Cmd(LCD_CLEAR) Lcd_Out(1,1,"Prag sup: XXX V") Lcd_Out(2,1," ") citValPrag(pSup) Lcd_Cmd(LCD_CLEAR) Lcd_Out(1,1,"Prag sup: ") For i = 0 to 2 Lcd_Chr_CP(pSup) next i Lcd_Out_CP(" V") Lcd_Cmd(LCD_CURSOR_OFF) Lcd_out(2,1,"Este corect ?") kp = daNu() if kp = 8 then goto Setare_prag_superior end if 'Afisare praguri setate dPraguriVector(pInf, pSup) kp = pWait() 'Scriere in EEPROM a pragurilor ScriereEEPROM(pInf, pSup) end if 'Terminare setare praguri ' Vizualizare valoare prag inferior pentru depanare ' Lcd_Cmd(LCD_CLEAR) ' Lcd_Out(1,1, "TPrg. inf: ") ' Lcd_Out(2,1,pInf) ' pWait() ' Vizualizare valoare prag superior pentru depanare ' Lcd_Cmd(LCD_CLEAR) ' Lcd_Out(1,1, "TPrg. sup: ") ' Lcd_Out(2,1,pSup) ' pWait() lInf = (StrToInt(pInf)/100)+ 0.00001 'corectie eroare lSup = (StrToInt(pSup)/100)+ 0.00001 'corectie eroare ' Vizualizare valori ale pragurilor convertite la float pentru depanare Lcd_Cmd(LCD_CLEAR) FloatToStr(lInf,disp) Lcd_Out(2,6,disp) pWait() Lcd_Cmd(LCD_CLEAR) FloatToStr(lSup,disp) Lcd_Out(2,6,disp) pWait() flag = FALSE ''Partea de conversie si monitorizare propriu-zisã... start: rez = 0 temp_res = Adc_Read(0) ' Canal 0 -> pinul 2 Lcd_Cmd(Lcd_clear) Lcd_Out(1,1, "Uintrare = " ) select case ADRESH case 1 rez = (256 + ADRESL)*5/1024 case 2 rez = (512 + ADRESL)*5/1024 case 3 rez = (768 + ADRESL)*5/1024 case else rez = ADRESL*5/1024 end select pShow(rez, disp) ' goto start 'pentru depanare if rez < lInf then flag = TRUE PORTB.1 = 0 if fabs(lInf-rez) < 0.10000 then lInfSup = lInf pDelayOneMin(linfsup, disp) goto start else pShow(rez, disp) goto start end if end if if rez > lSup then flag = TRUE PORTB.1 = 0 if fabs(rez-lSup) < 0.10000 then lInfSup = lSup pDelayOneMin(linfsup, disp) goto start else pShow(rez, disp) goto start end if end if if flag = TRUE then ' intarziere reluare alimentare dupa intrerupere 60 sec. Lcd_Cmd(LCD_CLEAR) for i = 1 to 60 delay_ms(1000) ByteToStr(i,idisp) Lcd_Out(1,1,"60s TO ON!") Lcd_Out(2,6,idisp) next i PORTB.1 = 1 flag = FALSE else PORTB.1 = 1 end if pShow(rez,disp) goto start end. Asta este codul. In fapt, l-am conceput pentru protectia unor consumatori casnici (LCD, Receptor satelit, Mediabox) mai pretentiosi. In esenta, este vorba de supravegherea tensiunii de alimentare a retelei intre doua limite (praguri). Urmarirea variatiei tensiunii se face de catre MCU prin masurarea tensiunii (utilizare ADC). Daca tensiunea se situeaza in afara pragurilor setate, se intrerupe alimentarea si aceasta revine cand tensiunea se afla in parametrii corecti, evitand cuplarea brusca a alimentarii printr-o bucla de asteptare de 1 minut. O prima problema a constituit-o eroarea de Link not enough ROM, pe care am depasit-o prin modularizarea programului in sensul ca am rescris codul structurandu-l in proceduri si functii. Acum apare problema semnalata: array over two banks, care cam banui ce inseamna ( MCU-ul este 16F876 cu 4 bank-uri) dar nu prea stiu de unde sa o apuc (utilizare clauza absolute ?) Atept sugestii, pentru care multumesc anticipat. Link spre comentariu
danb1974 Postat August 3, 2010 Partajează Postat August 3, 2010 Citez de pe net, poate ajuta (http://www.mikroe.com/forum/viewtopic.php?t=10215) Some of the arrays could not fit in one memory bank. Since P16 have gaps in RAM space, there is a great danger that access to an array will be wrong. What you have to do is to open the statistics window, to open the datasheet for 16F877A and to check which arrays got split over two banks. Then, you should make changes by using the "absolute" keyword in order to move the offensive array into one bank. Probably the best solution would be that you use P18 chip, such as P18F452 which is pin to pin compatible with P16F877A. P18 family has no gaps in RAM memory and array handling is much faster. 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