Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

USART with PIC 16F877a and Hitech C

Status
Not open for further replies.

varunme

Advanced Member level 3
Joined
Aug 10, 2011
Messages
741
Helped
17
Reputation
36
Reaction score
17
Trophy points
1,318
Activity points
5,764
How can i modify the below code for hitech c?

rxbyte=RCREG;
switch(rxbyte)
{
case 0x01:
PORTC=0b00000001; //code to do what you need on portb when command 0x01 is received;
break;
and so on
}
 

but when i compile , gives an error

Error [192] C:\Documents and Settings\Administrator\My Documents\MPLAB2\USAT using cases\main.c; 57.1 undefined identifier "rxbyte"
 

The below code doesnt working , what can be the cause ?

Code:
#include <stdio.h>
 #include <htc.h>
 #include "usart.h"

#ifndef _XTAL_FREQ
// Unless specified elsewhere, 4MHz system frequency is assumed
#define _XTAL_FREQ 20000000
#endif

__CONFIG( HS & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & DEBUGDIS & UNPROTECT);

 
 /* A simple demonstration of serial communications which
  * incorporates the on-board hardware USART of the Microchip
  * PIC16Fxxx series of devices. */




 void putch(unsigned char byte) 
 {
	/* output one byte */
	while(!TXIF)	/* set when register is empty */
		continue;
	TXREG = byte;
}
 
unsigned char 
getch() {
	/* retrieve one byte */
	while(!RCIF)	/* set when register is not empty */
		continue;
	return RCREG;	
}

unsigned char
getche(void)
{
	unsigned char c;
	putch(c = getch());
	return c;
}





void main(void){

 	 TRISB = 0;
	 PORTB=0;
     unsigned char input;

     INTCON=0;    // purpose of disabling the interrupts.
 
     init_comms();    // set up the USART - settings defined in usart.h
 
     while(1){
        
		char rxbyte= getch();
		switch(rxbyte)
		{
			case '1':
			PORTB=0xFF;
			putch("hhh");
			__delay_ms(3000);
			break;

			case 'b':
			PORTB=0x00;
			putch("hhh");
			__delay_ms(3000);
			break;
		
			default :
			break;


	
		}

     }
 }
 

not like that.


You need to declare the variable rxbyte (char type). So , above main function,
just declare it as below..

Code:
char rxbyte;

this will reserve an 8 bit in RAM for variable rxbyte.


after that, just use rxbyte= getch(); or like that....Dont use "char" there...
 

I modified the code for PORTD as

Code:
#include <stdio.h>
 #include <htc.h>
 #include "usart.h"

#ifndef _XTAL_FREQ
// Unless specified elsewhere, 4MHz system frequency is assumed
#define _XTAL_FREQ 20000000
#endif

__CONFIG( HS & WDTDIS & PWRTDIS & BORDIS & LVPDIS & WRTEN & DEBUGDIS & UNPROTECT);

 
 /* A simple demonstration of serial communications which
  * incorporates the on-board hardware USART of the Microchip
  * PIC16Fxxx series of devices. */




 void putch(unsigned char byte) 
 {
	/* output one byte */
	while(!TXIF)	/* set when register is empty */
		continue;
	TXREG = byte;
}
 
unsigned char 
getch() {
	/* retrieve one byte */
	while(!RCIF)	/* set when register is not empty */
		continue;
	return RCREG;	
}

unsigned char
getche(void)
{
	unsigned char c;
	putch(c = getch());
	return c;
}





void main(void){

 	 TRISD=0;
	 PORTD=0;
     unsigned char input;

     INTCON=0;    // purpose of disabling the interrupts.
 
     init_comms();    // set up the USART - settings defined in usart.h
 
     while(1){

		char rxbyte;
        
		rxbyte= getch();
		switch(rxbyte)
		{
			case '1':
			PORTD=0xFF;
			putch("hhh");
			__delay_ms(20);
			break;

			case 'b':
			PORTD=0x00;
			putch("hhh");
			__delay_ms(20);
			break;
		
			default :
			break;


	
		}

     }
 }
but the PORTD pins are high when i switchon the circuit and not blinking or not responding to the character i gave.
Earlier with PORTB , the pins are at low
what can be the problem ?
 

In asynchronous communication, the two devices should have a mutual understanding. For that we need to set same baud rate in both device...
So in your case, first thing you have to confirm is the baud rate....

---------- Post added at 12:10 ---------- Previous post was at 11:57 ----------

try this link:
**broken link removed**
 

baud is correct with 9600

usart.h

Code:
#ifndef _SERIAL_H_
#define _SERIAL_H_

#define BAUD 9600      
#define FOSC 20000000L
#define NINE 0     /* Use 9bit communication? FALSE=8bit */

#define DIVIDER ((int)(FOSC/(16UL * BAUD) -1))
#define HIGH_SPEED 1

#if NINE == 1
#define NINE_BITS 0x40
#else
#define NINE_BITS 0
#endif

#if HIGH_SPEED == 1
#define SPEED 0x4
#else
#define SPEED 0
#endif

#if defined(_16F87) || defined(_16F88)
	#define RX_PIN TRISB2
	#define TX_PIN TRISB5
#else
	#define RX_PIN TRISC7
	#define TX_PIN TRISC6
#endif

/* Serial initialization */
#define init_comms()\
	RX_PIN = 1;	\
	TX_PIN = 1;		  \
	SPBRG = DIVIDER;     	\
	RCSTA = (NINE_BITS|0x90);	\
	TXSTA = (SPEED|NINE_BITS|0x20)

void putch(unsigned char);
unsigned char getch(void);
unsigned char getche(void);

#endif
 

TRY THIS:
PHP:
TRY THIS CODE:
[CODE]
#include<pic.h>
#define _XTAL_FREQ 20e6
__CONFIG(0x3F3A);


void usrt_init()
{
	TRISC6=0;
	TXSTA=0b00100100;	//CHECK THE DATA SHEET FOR TXSTA
	RCSTA=0b10010000;	//SEE THE DATA SHEET FOR RCSTA
	BRGH=0;			//  low baud rate 
	SPBRG=129;      //baud rate 2400
}

void interrupt_enable()
{
	GIE=1;
	PEIE=1;
	RCIE=1;
}

void interrupt UART()  //interrupt service routine
{	
if(RCREG == '1'){PORTD=0xff;}
else if(RCREG == '2'){PORTD = 0x00;}
}

void txd(char write_data)
{
	TXREG = write_data;
	while(!TRMT);
}


main()
{	
	TRISD=0;
	usrt_init();
	interrupt_enable();
	txd('H');	txd('E');	txd('L');	txd('L');	txd('O');
	while(1);	//WAITING FOR INTERRUPT (SEE RESULT ON PORT D)
	
}
 

can I use switch case as below for modifying the above code ?

Code:
#include<htc.h>
#define _XTAL_FREQ 20e6
__CONFIG(0x3F3A);


void usrt_init()
{
    TRISC6=0;
    TXSTA=0b00100100;    //CHECK THE DATA SHEET FOR TXSTA
    RCSTA=0b10010000;    //SEE THE DATA SHEET FOR RCSTA
    BRGH=0;            //  low baud rate 
    SPBRG=129;      //baud rate 2400
}

void interrupt_enable()
{
    GIE=1;
    PEIE=1;
    RCIE=1;
}

void interrupt UART()  //interrupt service routine
{    
switch(RCREG)
		{
			case '1':
			PORTD=0xFF;
			putch("hhh");			 
			break;

			case 'b':
			PORTD=0x00;
			putch("hhh");
			 break;
		
			default :
			break;


	
		}



//if(RCREG == '1'){PORTD=0xff;}
//else if(RCREG == '2'){PORTD = 0x00;}
}

void txd(char write_data)
{
    TXREG = write_data;
    while(!TRMT);
}


main()
{    
    TRISD=0;
    usrt_init();
    interrupt_enable();
    txd('H');    txd('E');    txd('L');    txd('L');    txd('O');
    while(1);    //WAITING FOR INTERRUPT (SEE RESULT ON PORT D)
    
}
 

There is no "putch" function in the code. Also there is no header files...So you cannot used putch...
Instead you can use txd function defined in the program...
But it is not to send string but just characters... like

txd('H');

Also, you need to move the function txd above the interrupt service routine...
as below:

PHP:
#include<htc.h>
#define _XTAL_FREQ 20e6
__CONFIG(0x3F3A);


void usrt_init()
{
    TRISC6=0;
    TXSTA=0b00100100;    //CHECK THE DATA SHEET FOR TXSTA
    RCSTA=0b10010000;    //SEE THE DATA SHEET FOR RCSTA
    BRGH=0;            //  low baud rate 
    SPBRG=129;      //baud rate 2400
}

void interrupt_enable()
{
    GIE=1;
    PEIE=1;
    RCIE=1;
}

void txd(char write_data)
{
    TXREG = write_data;
    while(!TRMT);
}

void interrupt UART()  //interrupt service routine
{    
switch(RCREG)
		{
			case '1':
			PORTD=0xFF;
			txd('h');			 
			break;

			case 'b':
			PORTD=0x00;
			txd('E');
			 break;
		
			default :
			break;


	
		}



//if(RCREG == '1'){PORTD=0xff;}
//else if(RCREG == '2'){PORTD = 0x00;}
}



main()
{    
    TRISD=0;
    usrt_init();
    interrupt_enable();
    txd('H');    txd('E');    txd('L');    txd('L');    txd('O');
    while(1);    //WAITING FOR INTERRUPT (SEE RESULT ON PORT D)
    
}

but any way, keep this in mind, ISR should be as small as possible....
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
can i use 20 cases in ISR ?
 

anyone having example for read the state of a port pin and send the data to the PC ?
 

just use some thing like this in above code:


if(RD0==1){txd('1');}

(but you need to make the RD0 as input bit using TRISD0 = 1)
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
I believe I should mention a couple of important issues.

The first point I would like to make, when declaring a variable, always ask yourself the question, "Will this variable ever need to store a negative number?" If the answer is "No" or you are not sure declare the variable as a "unsigned" type.

For example the variable discussed in this thread:

char rxbyte;

should most likely be declared,

unsigned char rxbyte;

If you follow this simple rule, you will save yourself countless hours of debugging elusive errors.


The other point is be careful of overloading the Interrupt Service Routine (ISR), the routines themselves should be kept to an absolute minimum. As your application become more complex, avoid the temptation to insert more of the workload into the ISR code. Instead, handling the less time sensitive tasks outside of the ISR will help avoid conflicting and overlapping interrupts.

BigDog
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top