Jump to content
ELFORUM - Forumul electronistilor
Guest mike59

Help ! Eroare (warning) compilator mikrobasic 7.0

Recommended Posts

Guest mike59

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 to comment
Share on other sites

Guest mike59

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 to comment
Share on other sites

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 to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • 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