Jump to content


Photo

Convert From Hitech Pic16 Compiler To Boostc


4 replies to this topic

#1 MrNobody

MrNobody

    Newbrie

  • Members
  • 6 posts

Posted 19 May 2007 - 03:39 AM

Hi..
Can somebody please teach me how to convert the code below into BoostC..?
I have some basic knowledge on BoostC but I totally have no knowledge of HITECH PIC16 compiler..
So, I don't even know how to begin..

Thanks in advance..

Here is the code

////////////////////////////////////////////////////////////////////////////////
//
//	 PIC16F877 + SRF05 + LCD03 example
//	 Written October 2005 by Gerald Coe, using HITECH PIC16 compiler
// 
//		 Performs ranging using just a single pin on the PIC16F877 (RB0)
//
//		 Note - assumes a 20MHz crystal, which is 5MHz timer clock
//		 A 1:4 prescaler is used to give a 1.25MHz timer count (0.8uS per tick)
//
//	 This code is Freeware - Use it for any purpose you like.
//
///////////////////////////////////////////////////////////////////////////////


#include <pic.h>
#include <stdio.h>
	 
__CONFIG&#40;0x3b32&#41;;								// configuration register - see PIC data sheet for details		

#define TrgEch			RB0
#define TrgDir			TRISB0

void clrscn&#40;void&#41;;							// prototypes
void cursor&#40;char pos&#41;;
void print&#40;char *p&#41;;
void setup&#40;void&#41;;
unsigned int get_srf05&#40;void&#41;;

char s&#91;21&#93;;										// buffer used to hold text to print

void main&#40;void&#41;
{
unsigned int range;

	setup&#40;&#41;;										// sets up the PIC16F877 I2C port
	clrscn&#40;&#41;;									// clears the LCD03 disply
	cursor&#40;2&#41;;									// sets cursor to 1st row of LCD03
	sprintf&#40;s,&#34;SRF05 Ranger Test&#34;&#41;;		// text, printed into our buffer
	print&#40;s&#41;;									// send it to the LCD03

	while&#40;1&#41; {									// loop forever
		range = get_srf05&#40;&#41;;					// get range from srf05 &#40;round trip flight time in 0.8uS units&#41;
		cursor&#40;24&#41;;								// sets cursor to 2nd row of LCD03
		sprintf&#40;s,&#34;Range = %dcm  &#34;, range/72&#41;;	// convert to cm
		print&#40;s&#41;;								// send it to the LCD03	
		cursor&#40;44&#41;;								// sets cursor to 3rd row of LCD03
		sprintf&#40;s,&#34;Range = %dinch  &#34;, range/185&#41;;	// convert to inches
		print&#40;s&#41;;								// send it to the LCD03	

		TMR1H = 0;								// 52mS delay - this is so that the srf05 ranging is not too rapid
		TMR1L = 0;								// and the previous pulse has faded away before we start the next one
		T1CON = 0x21;							// 1&#58;4 prescale and running
		TMR1IF = 0;
		while&#40;!TMR1IF&#41;;						// wait for delay time
		TMR1ON = 0;								// stop timer	
	}
}

unsigned int get_srf05&#40;void&#41;
{
	TMR1H = 0xff;								// prepare timer for 10uS pulse
	TMR1L = -14;
	T1CON = 0x21;								// 1&#58;4 prescale and running
	TMR1IF = 0;
	TrgDir = 0;									// make trigger/echo pin an output	
	TrgEch = 1;									// start trigger pulse
	while&#40;!TMR1IF&#41;;							// wait 10uS
	TrgEch = 0;									// end trigger pulse
	TMR1ON = 0;									// stop timer
	TrgDir = 1;									// make trigger/echo pin an input
		
	TMR1H = 0;									// prepare timer to measure echo pulse
	TMR1L = 0;	
	T1CON = 0x20;								// 1&#58;4 prescale but not running yet
	TMR1IF = 0;
	while&#40;!TrgEch && !TMR1IF&#41;;				// wait for echo pulse to start &#40;go high&#41;
	TMR1ON = 1;									// start timer to measure pulse
	while&#40;TrgEch && !TMR1IF&#41;;				// wait for echo pulse to stop &#40;go low&#41;
	TMR1ON = 0;									// stop timer
	TrgDir = 0;									// make trigger/echo pin an output again	
	return &#40;TMR1H<<8&#41;+TMR1L;				// TMR1H&#58;TMR1L contains flight time of the pulse in 0.8uS units
}

void clrscn&#40;void&#41;
{
	SEN = 1;								// send start bit
	while&#40;SEN&#41;;							// and wait for it to clear

	SSPIF = 0;
	SSPBUF = 0xc6;						// LCD02 I2C address
	while&#40;!SSPIF&#41;;						// wait for interrupt
	SSPIF = 0;							// then clear it.

	SSPBUF = 0;							// address of register to write to 
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//

	SSPBUF = 12;						// clear screen 
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//

	SSPBUF = 4;							// cursor off 
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//
	 
	PEN = 1;								// send stop bit
	while&#40;PEN&#41;;							//
}

		
void cursor&#40;char pos&#41;
{
	SEN = 1;								// send start bit
	while&#40;SEN&#41;;							// and wait for it to clear

	SSPIF = 0;
	SSPBUF = 0xc6;						// LCD02 I2C address
	while&#40;!SSPIF&#41;;						// wait for interrupt
	SSPIF = 0;							// then clear it.

	SSPBUF = 0;							// address of register to write to 
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//

	SSPBUF = 2;							// set cursor 
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//
	SSPBUF = pos;						//  
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//
	 
	PEN = 1;								// send stop bit
	while&#40;PEN&#41;;							//
}

		
void print&#40;char *p&#41;
{
	SEN = 1;								// send start bit
	while&#40;SEN&#41;;							// and wait for it to clear

	SSPIF = 0;
	SSPBUF = 0xc6;						// LCD02 I2C address
	while&#40;!SSPIF&#41;;						// wait for interrupt
	SSPIF = 0;							// then clear it.

	SSPBUF = 0;							// address of register to write to 
	while&#40;!SSPIF&#41;;						// 
	SSPIF = 0;							//

	while&#40;*p&#41; {
		SSPBUF = *p++;					// write the data 
		while&#40;!SSPIF&#41;;					// 
		SSPIF = 0;						// 
	}

	PEN = 1;								// send stop bit
	while&#40;PEN&#41;;							//
}


void setup&#40;void&#41;
{
unsigned long x;

	PORTB = 0xfe;						// RB0 &#40;trig&#41; is output
	TRISB = 0xfe;						// and starts low

	TRISC = 0xff;
	PORTC = 0xff;

	SSPSTAT = 0x80;
	SSPCON = 0x38;
	SSPCON2 = 0x00;
	SSPADD = 50;						// SCL = 91khz with 20Mhz Osc

	for&#40;x=0; x<300000L; x++&#41;;		// wait for LCD03 to initialise		
}


#2 joli

joli

    Regular

  • EstablishedMember
  • Pip
  • 81 posts
  • Gender:Male
  • Location:Portugal

Posted 22 September 2015 - 01:34 PM

This is a delayed answer but in any case maybe it could be usefull to the ones that start trying to do it, also because i saw several guests seeing this thread.

 

as far i can see the changes that should be made, are:

 

includes:
replace both by
#include <system.h>

 

__CONFIG
replace it by:
#pragma DATA _CONFIG, 0x3b32

note: this is an oggly way to do it, in the future try to replace literal 0x3b32 by the fuse names you want to set, separated by  commas (edit pic16f877.h under "c:\.....\sourceboost\include" to see what correct names are defined.

ex: #pragma DATA _CONFIG, _WRT_ENABLE_ON & _WDT_ON .... whatever you want.. this is just an example

This is more readable to see what fuses are defined at a first glance.

 

pic registers:
all them should be in lower case... ex: use tmr1h instead of TMR1H.

pic register bits:
use "intcon.TMR1IF = 0;" instead of "TMR1IF = 0;" (the same to all others you use)

 

side comments:
As this old pic is one of many that have the rmw issue (read modify write), i recomend you use the below methode to change

ports:

unsigned char portb_mirror = 0xfe;
portb = portb_mirror;

instead of: portb = 0xfe;

 

 

br


Edited by joli, 22 September 2015 - 01:45 PM.


#3 Pavel

Pavel

    Super Maniac

  • Administrators
  • PipPipPipPipPip
  • 1,441 posts
  • Gender:Male
  • Location:Melbourne, Australia

Posted 25 September 2015 - 04:26 AM

As this old pic is one of many that have the rmw issue (read modify write), i recomend you use the below methode to change

ports:

unsigned char portb_mirror = 0xfe;
portb = portb_mirror;

instead of: portb = 0xfe;

 

Please explain why your method is more preferable?

 

Regards,

Pavel



#4 joli

joli

    Regular

  • EstablishedMember
  • Pip
  • 81 posts
  • Gender:Male
  • Location:Portugal

Posted 27 September 2015 - 12:27 AM

 

As this old pic is one of many that have the rmw issue (read modify write), i recomend you use the below methode to change

ports:

unsigned char portb_mirror = 0xfe;
portb = portb_mirror;

instead of: portb = 0xfe;

 

Please explain why your method is more preferable?

 

Regards,

Pavel

 

In the particular case where he just write the entire port and he do nothing more, its irrelevant the use of a port shadow.

I point it just a general rule to follow just in case.

 

Actually in some load circumstancies pic12/16/18 all them have this issue, the difference is that the pic18 and new pic16 have the lat(x).

 

google for "microchip DS31009A" pag 9

 

br


Edited by joli, 27 September 2015 - 12:28 AM.


#5 JorgeF

JorgeF

    Super Enthusiast

  • EstablishedMember
  • PipPipPip
  • 274 posts
  • Gender:Male
  • Location:ES @ Europe, third rock from the Sun

Posted 28 September 2015 - 01:42 PM

Hi

 

All microcontroler program can suffer the R-M-W issue whenever the loading of one output pin is over the limits. This is valid for PICs and for all others.

But the R-M-W efect is only an issue when we are using an "r-m-w" instruction, wich is not the case in this sample.

 

"portb = 0xfe"
compiles to ...

movlw 0xfe
movwf  portb

none of the above is an r-m-w instruction so there is no point in using a ghost register.

 

In PICs, only the "bit" instructions have an r-m-w behaviour, the byte instructions don't.

 

 

Just my 2 cents....

 

 

Best regards

Jorge


Edited by JorgeF, 28 September 2015 - 02:03 PM.




Reply to this topic



  


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users