Ir ao conteúdo

Ajuda com "Out of ROM, A segment or the program is too large: MAIN"


Lucas Schroeder

Posts recomendados

Postado

Boa noite pessoal.

 

Estou programando um pic para ser o voltímetro e o amperímetro de uma fonte. A fonte que projetei tem uma saída variável 0-37V uma sáida fixa de 18V e outra de 5V. Preciso de um voltímetro para a saída variável e amperímetros para todas as três saídas. Os valores são mostrados em 4 displays de 4 dígitos de 7 segmentos.

 

O problema é que para mostrar os valores nos 3 primeiros displays (tensão e corrente na saída variável e corrente na saída de 18v) o programa gasta 33% do ROM, mas com mais 33 linhas de códio, praticamente iguais as anteriores, para mostrar o último display o ROM fica cheio e não compila.

 

 

 

#include <PROGRAMACAO_2.h>
#include <ADS8320.C>

float q;
int VP_1, VP_2, VP_3, VP_4;  // Dígito 1, 2, 3, 4.

// DEFINE AS SAÍDAS B PARA OS DISPLAYS

byte const digito[] = { 0b01000000   //10111111, // 0 Define cada segmento
                        0b01111001   //10000110, // 1 dos valores mostrados
                        0b00100100   //11011011, // 2 no display de LEDs
                        0b00110000   //11001111, // 3 em binário para ficar
                        0b00011001   //11100110, // 4 mais fácil de codificar
                        0b00010010   //11101101, // 5 cada dígito dos valores
                        0b00000010   //11111101, // 6 mostrados no display.
                        0b01111000   //10000111, // 7
                        0b00000000   //11111111, // 8
                        0b00011000   //11100111, // 9
                        0b11111111}; //00000000};// 10 - Apaga o digito

void main()
{
   setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8|RTCC_8_bit);      //409 us overflow
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);                  //104 ms overflow

   init_ext_adc();
   
   while(true)
   {
      delay_us(100);
      // VOLTÍMETRO PRINCIPAL
      
      //leitura do voltímetro
      set_adc_channel(0);                                 // Lê a porta A0
      delay_us(100);                                      // Tempo para trocar o canal ADC
      q=read_adc();                                       // q é Variável da tensão
      q=(q/1023)*38.355;                                  // [(Leitura ADC)/65472]*Tensão máxima
           
      if(q>=10)                                           // Separa os digitos para mostrar no display
      {
      VP_1=(int)(q/10);
      VP_2=(int)(q - (VP_1*10));
      VP_3=(int)((q - (int)q)*10);;
      VP_4=(int)(((q*10) - (int)(q*10))*10);
      }
      
      if(q<10)//seleciona os digitos dos numeros
      {
      VP_1=10;
      VP_2=(int)q;
      VP_3=(int)((q - (VP_2))*10);
      VP_4=(int)(((q*10) - (int)(q*10))*10);
      }
               
      output_high(pin_c3);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c3);
      output_b(0b00000000);
      
      output_high(pin_c2);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c2);
      output_b(0b00000000);
      
      output_high(pin_c1);
      output_b(digito[VP_2]);
      delay_us(1000);
      output_low(pin_c1);
      output_b(0b00000000);
      
      output_high(pin_c0);
      output_b(digito[VP_1]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c0);
      output_b(0b00000000);      
      
      
      // AMPERÍMETRO PRINCIPAL
      
      //leitura do amperímetro principal
      
      set_adc_channel(1);
      delay_us(100);
      q=read_adc();
      q=(q/1023)*5*0.34848485;
     
      
      VP_1=(int)q;                                  //Separa os digitos para mostrar no displays
      VP_2=(int)((q - VP_1)*10);
      VP_3=(int)(((q*10) - (int)(q*10))*10);
      VP_4=(int)(((q*100) - (int)(q*100))*10);
           
      
      output_high(pin_c7);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c7);
      output_b(0b00000000);
      
      output_high(pin_c6);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c6);
      output_b(0b00000000);
      
      output_high(pin_c5);
      output_b(digito[VP_2]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c5);
      output_b(0b00000000);
      
      output_high(pin_c4);
      output_b(digito[VP_1]);
      delay_us(1000);
      output_low(pin_c4);
      output_b(0b00000000);
      
      
      // AMPERÍMETRO 2 (18V) ATÉ AQUI, ROM=33%
      
      
      q=1.69302; // Variável da corrente 1
      
      VP_1=(int)q;                            //Separa os digitos para mostrar no displays
      VP_2=(int)((q - VP_1)*10);
      VP_3=(int)(((q*10) - (int)(q*10))*10);
      VP_4=(int)(((q*100) - (int)(q*100))*10);
      
      output_high(pin_d3);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d3);
      output_b(0b00000000);
      
      output_high(pin_d2);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d2);
      output_b(0b00000000);
      
      output_high(pin_d1);
      output_b(digito[VP_2]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d1);
      output_b(0b00000000);
      
      output_high(pin_d0);
      output_b(digito[VP_1]);
      delay_us(1000);
      output_low(pin_d0);
      output_b(0b00000000);
      
      // AMPERÍMETRO 3 (5V) A PARTIR DAQUI DÁ PROBLEMA NA ROM
      
      q=1.76931; // Variável da corrente 2
      
      VP_1=(int)q;                              //Separa os digitos para mostrar no displays
      VP_2=(int)((q - VP_1)*10);
      VP_3=(int)(((q*10) - (int)(q*10))*10);
      VP_4=(int)(((q*100) - (int)(q*100))*10);
      
      output_high(pin_d7);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d7);
      output_b(0b00000000);
      
      output_high(pin_d6);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d6);
      output_b(0b00000000);
      
      output_high(pin_d5);
      output_b(digito[VP_2]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d5);
      output_b(0b00000000);
      
      output_high(pin_d4);
      output_b(digito[VP_1]);
      delay_us(1000);
      output_low(pin_d4);
      output_b(0b00000000);
      
      }
}

 

 

 

Se precisarem posto mais detalhes.

 

Se alguém puder me ajudar ficarei muito grato!

 

 

Postado

Dentro do PROGRAMACAO_2.h tem:

 

#include <16F877A.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset

#device ICD=TRUE
#use delay(crystal=20000000)

 

Obrigado pela atenção MatheusLPS!

Postado

Lucas essa eu posso responder pois passei por ela outro dia, ocorre que ele á um Out of Rom a segment of the program is too large "MAIN"

 

Isso ocorre porque o seu codigo dentro do MAIN no caso o While(true) está muito grande, e não que a memoria acabou, ele obriga você a dividir o codigo por exemplo em varias funções. Dai você vai chamando as funções quando precisar delas..

 

o meu estourava o Rom com 41 %, dai dividi tudo em funções e vou chamando-as agora usei 65% ja sem problemas..

Postado
(...)Isso ocorre porque o seu codigo dentro do MAIN no caso o While(true) está muito grande, e não que a memoria acabou, ele obriga você a dividir o codigo por exemplo em varias funções. Dai você vai chamando as funções quando precisar delas..(...)

 

Uhmm, muito obrigado pela explicação :) , mas como faço para dividir em funções? Você poderia dar um exemplo por favor?

Postado

Exemplo, quando você quiser exibir o numero 1

 

declara função 

 

void numero_1();

 

 

função:

 

void numero_1()

 

{

  codigo que exibe o numero 1

}

 

dai quando quiser exibir o numero 1 usa isso numero_1();  você chama ela, pode fazer para todos os numeros e vai chamando...

Postado

Pperfeito!! fiz o que você disse e funcionou direitinho!

 

 

#include <PROGRAMACAO_2.h>
#include <ADS8320.C>

float q;
int VP_1, VP_2, VP_3, VP_4;  // Dígito 1, 2, 3, 4.

// DEFINE AS SAÍDAS B PARA OS DISPLAYS

byte const digito[] = { 0b01000000   //10111111, // 0 Define cada segmento
                        0b01111001   //10000110, // 1 dos valores mostrados
                        0b00100100   //11011011, // 2 no display de LEDs
                        0b00110000   //11001111, // 3 em binário para ficar
                        0b00011001   //11100110, // 4 mais fácil de codificar
                        0b00010010   //11101101, // 5 cada dígito dos valores
                        0b00000010   //11111101, // 6 mostrados no display.
                        0b01111000   //10000111, // 7
                        0b00000000   //11111111, // 8
                        0b00011000   //11100111, // 9
                        0b11111111}; //00000000};// 10 - Apaga o digito
                        
void display_1()
{

      output_high(pin_c3);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c3);
      output_b(0b00000000);
      
      output_high(pin_c2);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c2);
      output_b(0b00000000);
      
      output_high(pin_c1);
      output_b(digito[VP_2]);
      delay_us(1000);
      output_low(pin_c1);
      output_b(0b00000000);
      
      output_high(pin_c0);
      output_b(digito[VP_1]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c0);
      output_b(0b00000000);     

}

void display_2()
{
      output_high(pin_c7);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c7);
      output_b(0b00000000);
      
      output_high(pin_c6);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c6);
      output_b(0b00000000);
      
      output_high(pin_c5);
      output_b(digito[VP_2]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_c5);
      output_b(0b00000000);
      
      output_high(pin_c4);
      output_b(digito[VP_1]);
      delay_us(1000);
      output_low(pin_c4);
      output_b(0b00000000);
}

void display_3()
{
      output_high(pin_d3);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d3);
      output_b(0b00000000);
      
      output_high(pin_d2);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d2);
      output_b(0b00000000);
      
      output_high(pin_d1);
      output_b(digito[VP_2]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d1);
      output_b(0b00000000);
      
      output_high(pin_d0);
      output_b(digito[VP_1]);
      delay_us(1000);
      output_low(pin_d0);
      output_b(0b00000000);
}

void display_4()
{
      output_high(pin_d7);
      output_b(digito[VP_4]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d7);
      output_b(0b00000000);
      
      output_high(pin_d6);
      output_b(digito[VP_3]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d6);
      output_b(0b00000000);
      
      output_high(pin_d5);
      output_b(digito[VP_2]);
      output_high(pin_b7);
      delay_us(1000);
      output_low(pin_d5);
      output_b(0b00000000);
      
      output_high(pin_d4);
      output_b(digito[VP_1]);
      delay_us(1000);
      output_low(pin_d4);
      output_b(0b00000000);
}

void main()
{
   setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8|RTCC_8_bit);      //409 us overflow
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);                  //104 ms overflow

   init_ext_adc();
   
   while(true)
   {
      delay_us(100);
      // VOLTÍMETRO PRINCIPAL
      
      // Leitura do voltímetro
      set_adc_channel(0);                                 // Lê a porta A0
      delay_us(100);                                      // Tempo para trocar o canal ADC
      q=read_adc();                                       // q é Variável da tensão
      q=(q/1023)*38.355;                                  // [(Leitura ADC)/65472]*Tensão máxima
           
      if(q>=10)                                           // Separa os digitos para mostrar no display
      {
      VP_1=(int)(q/10);
      VP_2=(int)(q - (VP_1*10));
      VP_3=(int)((q - (int)q)*10);;
      VP_4=(int)(((q*10) - (int)(q*10))*10);
      }
      
      if(q<10)
      {
      VP_1=10;
      VP_2=(int)q;
      VP_3=(int)((q - (VP_2))*10);
      VP_4=(int)(((q*10) - (int)(q*10))*10);
      }
               
      display_1();                                        // Mostra valor no display 1
      
      
      // AMPERÍMETRO PRINCIPAL
      
      //leitura do amperímetro      
      set_adc_channel(1);
      delay_us(100);
      q=read_adc();
      q=(q/1023)*5*7.6666666666666666666666666666667;
      
      VP_1=(int)q;                                       // Separa os digitos para mostrar no display
      VP_2=(int)((q - VP_1)*10);
      VP_3=(int)(((q*10) - (int)(q*10))*10);
      VP_4=(int)(((q*100) - (int)(q*100))*10);
           
      
      display_2();                                       // Mostra valor no display 2
      
      
      // AMPERÍMETRO 2 (18V)
      
      q=1.69302; // Variável da corrente 1
      
      VP_1=(int)q;                                       // Separa os digitos para mostrar no display
      VP_2=(int)((q - VP_1)*10);
      VP_3=(int)(((q*10) - (int)(q*10))*10);
      VP_4=(int)(((q*100) - (int)(q*100))*10);
      
      display_3();                                       // Mostra valor no display 3
      
      // AMPERÍMETRO 3 (5V)
      
      q=1.76931; // Variável da corrente 1
      
      VP_1=(int)q;                                       // Separa os digitos para mostrar no display
      VP_2=(int)((q - VP_1)*10);
      VP_3=(int)(((q*10) - (int)(q*10))*10);
      VP_4=(int)(((q*100) - (int)(q*100))*10);
      
      display_4();                                       // Mostra valor no display 4
      }
}

 

 

Muito obrigado rodrigocirilo!!

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!