Jump to content
Sign in to follow this  
Steve Prior

Need Basic Soft Serial Example For 12f629

Recommended Posts

I've been looking through the provided serial code and just don't understand how to set up software serial port emulation for a chip like the 12F629. How do I pick the addresses used for sw_SPBRG, sw_RCREG, sw_TXREG, sw_TXSTA, sw_RCSTA, sw_TXIF_PIR, sw_RCIF_PIR, and the for the #defines? Does anyone have some really simple code which sets up the serial port for maybe a 12F629 at some stable port speed and simply outputs a "Hello World" message to the port on startup?

Share this post


Link to post
Share on other sites
BTW, when I said basic in the title I meant simple, I'm looking for the example to be in BoostC.

I'm not sure if you can with the 12f629.

To find the registers you need to look at the data sheet. Here's the one for your PIC -- http://ww1.microchip.com/downloads/en/DeviceDoc/41190E.pdf I can't see any mention (in quickly searching and reading), of USART or UART. Could you get another PIC? Line 11 of "rs232_driver.h":

// emulation for the PIC 16F87x, PIC18F2xx and 18F4xx processors.
. Try one of those if you can. I think it can work with the 16F627 (and probably more), too. It probably could work with your PIC with work though. I'm no expert, however.

Share this post


Link to post
Share on other sites

Like any programming language if the function you want is not available then roll you own.

 

I use a 12F629 in a battery operated remote temperature sensor. Every 1 minute I power up from sleep, read the temperature from a Dallas DS75 I2C sensor, send serial data to a 433MHz transmitter, powerdown and go to sleep again.

 

The reciver is another PIC (16F687) which has a real UART. It checks the data integrity and then emulated the DS75 using I2C to the master controller.

 

I transmit 5 byte of data using a simple bit-bash method.

 

void TransmitData(U16 temp) {
.
.
.
// Get ready to transmit.
xmitDataPtr = transData.transArray;
xmitByteCount = sizeof(transData.transArray);
xmitState = 0;
xmitBit = true;										// set up xmit data for a start bit (1).
xmitBusy = true;									// say we are busy.

tmr1h = (T1_05MS_RELOAD >> 8);						// preload timer 1 count.
tmr1l = T1_05MS_RELOAD & 0xff;
t1con.TMR1ON = true;								// start timer again.
pie1.TMR1IE = true;									// enable timer 1 interrupts.
}

/****************************************************************
*	Interrupt Service Routine Entry Point.						*
****************************************************************/
void interrupt (void) {
union {
	U16	timerWord;
	U8	timerByte[2];
} timer;

if (pir1.TMR1IF)	{							// timer 1 interrupt ?
	pir1.TMR1IF = false;
	t1con.TMR1ON = false;						// stop timer.
	timer.timerByte[1] = tmr1h;
	timer.timerByte[0] = tmr1l;
	timer.timerWord += T1_05MS_RELOAD;
	tmr1h = timer.timerByte[1];					// preload timer 1 count.
	tmr1l = timer.timerByte[0];
	t1con.TMR1ON = true;						// start timer again.
	TransmitIsr();
}
}

/****************************************************************
*	Transmit Interrupt Service Routine.							*
*	Only to be called from the ISR in Kernel.c					*
****************************************************************/
void TransmitIsr(void) {
if (xmitBit) {										// output serial data bit.
	portOutput |= XMIT_PORT_BIT;					// set output = 1.
} else {
	portOutput &= ~XMIT_PORT_BIT;					// set output = 0.
}
gpio = portOutput;									// update output port.

switch (xmitState) {
case 0:		// output start bit.
	xmitByte = *xmitDataPtr++;
	xmitBitCount = 8;								// set data bit counter.
	xmitBit = (xmitByte & 0x01) ? false : true;
	xmitByte >>= 1;
	++xmitState;
	break;

case 1:		// output data bits.
	if (--xmitBitCount > 0) {
		xmitBit = (xmitByte & 0x01) ? false : true;
		xmitByte >>= 1;
	} else {
		xmitBit = false;							// output stop bit next.
		++xmitState;
	}
	break;

case 2:		// output stop bit.
	if (--xmitByteCount > 0) {						// any more data to send ?
		xmitBit = true;								// yes, output another start bit.
		xmitState = 0;								// back to state 0;
	} else {
		++xmitState;
	}
	break;

case 3:		// stop bit complete.
	xmitBusy = false;								// transmit no longer busy.
	t1con.TMR1ON = false;							// stop the timer.
	pie1.TMR1IE = false;							// stop timer 1 interrupts.
	break;
} // end switch.
}

 

Change the timer 1 reload value to change baud rate. I use 0.5ms per bit.

 

My application is transmit only so if you want to recieve as well you will need to detect the start bit and do centre bit sampling. Half duplex as well.

 

It may not be the best code, but food for thought.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. 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.

Loading...
Sign in to follow this  

×
×
  • Create New...