CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Program stopping in function #use delay ()
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Program stopping in function #use delay ()
PostPosted: Fri Jan 26, 2018 6:42 am     Reply with quote

Hello friends, I am writing this simple library for a DS18B20 sensor in CCS, but when running the program in debug, I realized that the same in the unsigned function int read_temperature (); when trying to call delay_ms (750), the cursor is stopped in #use delay (clock = 4000000)

Could someone help me where the error is?

Code:
/* Library for DSb80b20 sensor. To start the reading and writing it is necessary to send 0 to the sensor data pin, this reset wakes the sensor and
and informs of the need for reading */

#include <16f877a.h>
#fuses xt, nowdt, nolvp, put, brownout
#use delay (clock = 4000000)
#use fast_io(a)
#use fast_io(b)


void escreve_zero();
void escreve_um();
void reset();
char leitura();
void escreve_comando (unsigned int comando);
unsigned int ler_memoria();
unsigned int ler_temperatura();

//Funcao de tempos Delays

//void time15us();
//void time70us();
//void time500us(); // Manual indicates delay of 480us
//void time750ms();


void main()

{
    //set_tris_a(0x00);     
    set_tris_b(0x00); //TRISB = 0x00;
     set_tris_c(0x00); //TRISC = 0x00;
    output_b(0x00);
     output_c(0x00);
   
   while(1)
     {
         
          unsigned int temp = ler_temperatura();
          output_b (temp);   //PORTB= temp;
          output_c(temp>>8); //PORTC= temp>>8;
      }
}

void escreve_zero()
{

   output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (input)
 
   output_low(PIN_A4);     //PORTB_PIN_R4  = 0x00;          // Coloca zero no pino

   delay_us(70);

   output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (output)
 
Minimum timeout 1us between each command sent requested in manual DS18B20
   #asm NOP       // The function asm NOP spends one machine cycle each or 2us for 4Mhz crystal
   #endasm
   #asm NOP         
   #endasm

}

void escreve_um()

{
  output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (output)
 

 output_low(PIN_A4); //PORTB_PIN_R4  = 0x00;  // 
 #asm goto ai;          // in CCS Asm stay? #asm goto '$' + 1 to skip a line below // asm goto function spends two machine cycles GOTO needs a place to jump.
  ai:                   
 #endasm

output_float(PIN_A4); // this will set the tris bit for that pin to 1 (input)

 delay_us(70);
}

char leitura()  // lê o bit 1 ou 0

{
 char valor;

 output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (output)
 
 
 output_low(PIN_A4);//PORTB_PIN_R4  = 0x00;  // Escreve zero
 
 #asm goto '$'+1  //goto '$'+1 //#asm("goto $+1"); // Espera 2us
 #endasm
 

 output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (input)
 #asm  goto ap;              //#asm("goto $+1"); // wait for 2us
 ap:
 #endasm
 valor = PIN_A4 ;

 delay_us(70);
 
 return valor;
}

void reset()
{

 output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (output)
 output_low(PIN_A4);// PORTB_PIN_R4  = 0x00;
 delay_us(500);
 output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (input)
 delay_us(15);
 while( input(PIN_A4== 1)) ;//PORTB_PIN_R4  == 1);
 delay_us(500);
}

void escreve_comando (unsigned int comando)

{
 int x = 0x00;
 while (x<8)                     // writes the byte to the sensor
 {
  if (comando & 1) escreve_um(); // the function and (&) 1 + 1 = 1, if the first command bit is 1, then write 1
   else escreve_zero();
   comando = comando >>1;       
   x++;
 }
}

unsigned int ler_memoria()  // will read 2 byte bytes 0 and 1 of the temperature recorder
{
   unsigned int valor = 0x00;
   int x = 0x00;
    while(x <16)
      {
         if (leitura())    // se leu bit =1
            {
               valor = (valor  | (1 <<x));
            }
            x++;
       }
       
       reset();
       return valor;
}

unsigned int ler_temperatura()
{  unsigned int resultado;
   reset(); // inicia o sensor
   escreve_comando(0xCC);  // ROM boot command
   escreve_comando(0x44); // Initiate temperature conversion
   delay_ms(750);
   reset(); // inicia o sensor
   escreve_comando(0xCC); 
   escreve_comando(0xBE);  // Reading sensor memory reading
   resultado = ler_memoria();// The first 2 registers
   return result;
}

Crying or Very sad Crying or Very sad


Last edited by jacktaylor on Fri Jan 26, 2018 1:00 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Jan 26, 2018 8:21 am     Reply with quote

First thing, do you have a pull-up on pin A4?.

On this chip A4, is not a normal pin. It can only pull it's output down, not up. So to operate a reset line, there must be a pull up resistor on this, or it'll never go high...

You do realise you can get your two cycle delay with just delay_cycles(2);
This will actually code as a single jump forward.

The 80B20, uses the Maxim one wire interface, and there are drivers for this, supplied with the compiler (look for DS18B20.c), and in the code library.

Then there are some oddities with your comments:
Code:

   output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (output)


TRIS=1, is an Input. TRIS=0 implies Output.

You disagree with yourself and have the correct description later.

Now there is no mention of enabling DEBUG here. Are you using a debugger or a simulator?. If the latter a delay will take a long time. If using a debugger, what unit are you using?. What environment (CCS/MPLAB etc.)?.
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thank Friend Ttelmah
PostPosted: Fri Jan 26, 2018 12:57 pm     Reply with quote

Hi, friend Ttelmah. Thanks for the answer.
To create the program, I am using and querying the datasheet of the DS18B20 component, which indicates the use of a 4.7K resistor. My problem is only when executing delay_ms (750). I used delay_us (750000) and the program went to the next line non-stop in #use delay (clock = 4000000).

Yes I need tris TRIS = 1, is an Input. TRIS = 0 implies Output. When TRIS = 0 in the program I put Zero on the pin by the directive output_low (PIN_A4); When TRIS = 1 in the program, the pull-up resistor raises the pin level to 1. These are steps in the datasheet to configure the reading and writing of the DS18.

Yes, I realized that I can use delay_cycles(2) by reading the CCS manual, but I preferred to test by the asm code.

Friend Ttelmah, I'm in the apprenticeship phase, so I do not like at first to simply copy a library that is already ready, this slows the learning process, does not allow the programmer a reaction, because the library is ready. If it is just to copy libraries I would be using the Arduino. But the challenge is to learn.

To debug I am using the MPLAB IDE V8.92 with the CCS compiler.

This program ran perfect on another compiler, but I want to make it run on CCS I need to fix other steps. But I did not understand why I did not run the delay_ms (750).
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Jan 26, 2018 2:36 pm     Reply with quote

Thing is though that you need to start by being accurate with your comments.
Being in 'learning mode' is not an excuse to get remarks wrong. In fact it is exactly when you need to get them exactly right. Also you can see what the code does by simply looking at the listing, so doing things like goto's which are an excuse to make code go wrong, is a poor way to progress.

Now at least we have a little data. You are in MPLAB, and you do have a pull up resistor. However how are you powering the chip?. 4K7 is OK if you are powering the chip with a separate supply, but not if you are trying to power the chip off the bus. You need to be reading the data sheet.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 26, 2018 4:22 pm     Reply with quote

re:
when trying to call delay_ms (750), the cursor is stopped in #use delay (clock = 4000000)

Whenever a delay_ms(xx) or delay_us(yyy) is executed, the PIC will simply loop and decrement a counter(or 2) until the required time has elapsed.
'The cursor stopped' indicates you're using either a 'debug' or 'in circuit emulator'. Both of which slow down the PICs real speed unlike the 'release' version of the code.

As others have looked at your code, I won't comment on if it's constructed correctly, though there are some available in the Code Library here.

Jay
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Hi friend Temtronic
PostPosted: Sat Jan 27, 2018 10:56 am     Reply with quote

Hello, Temtronic friend. What happens is that even when running the program in MPLAB debug and run mode, the green cursor that indicates the line of the program being executed is stopped in #use delay (clock = 4000000), this occurs when it reaches the line delay_ms ( 750);
in function:
Code:
unsigned int ler_temperatura()
{  unsigned int resultado;
   reset(); // inicia o sensor
   escreve_comando(0xCC);  // ROM boot command
   escreve_comando(0x44); // Initiate temperature conversion
   delay_ms(750);
   reset(); // inicia o sensor
   escreve_comando(0xCC); 
   escreve_comando(0xBE);  // Reading sensor memory reading
   resultado = ler_memoria();// The first 2 registers
   return result;
}

if I put delay_us (750000) the program passes and executes all the programming.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Jan 27, 2018 11:43 am     Reply with quote

That's probably giving you a shorter delay....

Value is larger than the maximum the function supports.....

Quote:

constant 0-65535
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Thnak you friend Ttelmah
PostPosted: Sat Jan 27, 2018 12:01 pm     Reply with quote

Yes my friend Ttelmah, it is bigger, but as I mentioned the program is not running when using delay_ms (750), this would be the correct value for being at 0-65535. I will review more details in this program.

Ttelmah wrote:
That's probably giving you a shorter delay....

Value is larger than the maximum the function supports.....

Quote:

constant 0-65535
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sat Jan 27, 2018 12:18 pm     Reply with quote

By being larger, it is resulting in a shorter delay. You already know shorter delays work.

The key thing is you need to learn to do things one step at a time.
If you have a problem with debugging when delays are 750mSec, then test this:
Code:

#include <16f877a.h>
#fuses xt, nowdt, nolvp, put, brownout
#use delay (clock = 4000000)

void main(void)
{
    while(TRUE);
    {
        delay_ms(750);
        output_toggle(PIN_A0); //change to a pin OK for you
    }
}


Test your debugging. You can put a break on the toggle line and see what happens.

Now you have still not actually told us what the environment is. Yes. MPLAB, but what ICD?. What board holding the processor?. One thing that will give the behaviour you are describing is that the programmer is not erasing the fuses, and the watchdog is actually on.

What compiler version?. There was an issue with longer delays on a very old version (about 3.200ish).

As Temtronic was trying to explain, this may simply be what happens when you have a long delay:

<http://www.ccsinfo.com/forum/viewtopic.php?t=1787>
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 28, 2018 10:21 am     Reply with quote

jacktaylor wrote:

The green cursor that indicates the line of the program being executed is
stopped in #use delay (clock = 4000000), this occurs when it reaches the
line delay_ms (750);

If you change the delay to 10us, the debugger will not hang in #use delay().
Example:
Code:
delay_us(10);

This was tested with CCS vs. 5.075, MPLAB vs. 8.92, and a PicKit 3
and a 16F1847 running at 5v.
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Hi friend Ttelmah
PostPosted: Sun Jan 28, 2018 10:43 am     Reply with quote

I tested the code below. In Proteus I placed the oscilloscope in the output PIN_A0, but no oscillation occurred.

I created this function to timer.
Code:

void time750ms()
{
  for (unsigned int16 x=0 ; x<5; x++);
}

The whole program I send does not run on Proteus, not debug. The output not changed to PIN_A0 does not oscillate. But in the debug in MPLAB V8.92 it works normally runs all the lines of the program
Code:

/* Library for DSb80b20 sensor. To start the reading and writing it is necessary to send 0 to the sensor data pin, this reset wakes the sensor and
and informs of the need for reading */

#include <16f877a.h>
#fuses xt, nowdt, nolvp, put, brownout
#use delay(clock = 4000000)
#use fast_io(a)
#use fast_io(b)


void escreve_zero();
void escreve_um();
void reset();
char leitura();
void escreve_comando (unsigned int comando);
unsigned int ler_ler_memDS18();
unsigned int ler_tempDS18();

//Funcao de tempos Delays

void time15us();
void time70us();
void time500us(); // O manual pede delay de 480us
void time750ms();

void main()

{
    //set_tris_a(0x00);     
    set_tris_b(0x00); //TRISB = 0x00;
     set_tris_c(0x00); //TRISC = 0x00;
    output_b(0x00);
     output_c(0x00);
   
   while(1)
     {
          unsigned int temp = ler_tempDS18();
          output_b (temp);   //PORTB= temp;
          output_c(temp>>8); //PORTC= temp>>8;
     }
}

void escreve_zero()
{

   output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (input)
   output_low(PIN_A4);     //PORTB_PIN_R4  = 0x00;          // Coloca zero no pino
   
   time70us();
   //delay_us(70);

   output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (output)
 
   //#asm ("NOP")  uso em outro compilador xom parenteses e colchetes. Tempo de intervalo minimo 1us entre cada comando enviado pedido no manual DS18B20
   #asm NOP       // A funcao asm NOP gasta um ciclo de máquina cada uma ou 2us para cristal de 4Mhz
   #endasm
   #asm NOP         
   #endasm
}

void escreve_um()

{
 OUTPUT_DRIVE(PIN_A4);    // THIS WILL SET THE TRIS BIT FOR THAT PIN TO 0 (OUTPUT)
 OUTPUT_LOW(PIN_A4);     //PORTB_PIN_R4  = 0X00;  // 
 #ASM GOTO AI;           //NO CCS ASM FICA? #ASM GOTO '$'+1 PARA SALTAR UMA LINHA ABAIXO // FUNCAO ASM GOTO GASTA DOIS CICLOS DE MAQUINA GOTO PRECISA DE UM LOCAL PARA SALTAR.
  AI:                    // O MANUAL PEDE NO MINIMO 1US PARA MANTER O PINO=0
 #ENDASM

 OUTPUT_FLOAT(PIN_A4); // THIS WILL SET THE TRIS BIT FOR THAT PIN TO 1 (INPUT)
 time70us();
 //delay_us(70);
}

//*********Funções de tempo********

void time15us()
{
 int x = 0x00;
 while (x<1) x++;
}
void time70us()

{
 int x = 0x00;
 while (x<6) x++;
}
void time500us()
{
 int x = 0x00;
 while(x<49) x++;
}

void time750ms()
{
  for (unsigned int16 x=0 ; x<5; x++);
}

//******inicio funcao leitura***************

char leitura()  // lê bit 1 ou 0 na linha do sensor temperatura
{
 char valor;

 output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (output)
 output_low(PIN_A4);     //PORTB_PIN_R4  = 0x00;  // Escreve zero
 //delay_cycles(2);
 #asm NOP         
 #endasm
 
 output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (input)
 delay_cycles(2); // tem  a mesma fucao de NOP, 2 ciclos de maquina
 // #asm NOP <- este comando #asm saltar linha funcionou     
 // #endasm // com este-> #asm goto '$'+1, o programa nao executa a funcao leitura
 
 valor = PIN_A4 ; // Leu o pino com 0 ou 1 e armazena em valor.
 time70us();
 //delay_us(70);
 return valor;      // retorna valor 0 ou 1

}// Fim funcao leitura


//******inicio funcao reset***************
void reset()
{
 output_drive(PIN_A4);    // this will set the tris bit for that pin to 0 (output)
 output_low(PIN_A4);// PORTB_PIN_R4  = 0x00;
 time500us();
 //delay_us(500);
 output_float(PIN_A4);    // this will set the tris bit for that pin to 1 (input)
 time15us();
 //delay_us(15);
 while( input(PIN_A4== 1)) ;// fica preso neste laço enquanto pino=1, qdo sensor responder ele envia para a linha a 0.
 time500us();
 //delay_us(500);
} //****Fim fucano reset


//******inicio funcao comando***************

void escreve_comando (unsigned int comando)

{
 int x = 0x00;
 while (x<8)                     // escreve o byte no sensor
 {
  if (comando & 1) escreve_um(); // a funcao and(&) 1+1=1, se primerio bit de comando é 1, entao escreve 1
   else escreve_zero();
   comando = comando >>1;        // desloca o bit para direita
   x++;
 }
}//****Fim funcao comando


unsigned int ler_memDS18()  // vai ler 2 bytes byte 0 e 1 do registrador de temperatura
{
   unsigned int valor = 0x00;
   int x = 0x00;
    while(x <16)
      {
         if (leitura())    // se leitura tem bit = 1, Leu um bit. executa valor
            {
               valor = (valor  | (1 <<x));
            }
            x++;
      }
       
       reset();
       return valor;
} // **fim funcao comando

unsigned int ler_tempDS18()

   unsigned int resultado;
   reset(); // inicia o sensor
   escreve_comando(0xCC);  // Comando de inicio da memoria ROM
   escreve_comando(0x44);  // Inicia conversao da temperatura
   time750ms(); // tempo necsessario para conversao
   //delay_ms(750); //O compilador esta gerando erro na exucucao do progrma ao usar ms(750), nao gera erro ao usar us(750000)
   reset(); // inicia o sensor
   escreve_comando(0xCC);  // Comando de inicio da memoria ROM
   escreve_comando(0xBE);  // Comando de ler memoria do sensor
   resultado = ler_memDS18(); // Le os 2 primeros registradores
   return resultado;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 28, 2018 11:00 am     Reply with quote

I can't understand your comments. Do you still have a problem ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Sun Jan 28, 2018 11:34 am     Reply with quote

Read the 'Sticky' at the head of the forum about Proteus.

It is fundamentally flawed. Do not waste time trying to work with it for PIC emulation.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jan 28, 2018 11:39 am     Reply with quote

this...
Quote:
The whole program I send does not run on Proteus,

is WHY I've said for years to NOT use Proteus ! It's so full of 'busted code' and a HUGE time waster. See PIC101 sticky.

As for DS18B20 code, there is some in the code library, which works and I'll add that if you want to use multiple devices, it's easier to just copy the 'driver', renaming as required, for each device. These sensors are 'time critical' and this way is probably the best solution.

Jay
jacktaylor



Joined: 02 Sep 2017
Posts: 75

View user's profile Send private message Send e-mail

Friend Temtronic
PostPosted: Sun Jan 28, 2018 12:47 pm     Reply with quote

Friend the program you sent also did not run in the MPLAB IDE, ie the PIN_A0 does not change the state between 0 and 1. I did the simulation using the step into MPLBA.

temtronic wrote:
this...
Quote:
The whole program I send does not run on Proteus,

is WHY I've said for years to NOT use Proteus ! It's so full of 'busted code' and a HUGE time waster. See PIC101 sticky.

As for DS18B20 code, there is some in the code library, which works and I'll add that if you want to use multiple devices, it's easier to just copy the 'driver', renaming as required, for each device. These sensors are 'time critical' and this way is probably the best solution.

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group