Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic 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.

Register Log in

Pic16f886 using MPLAB X C8 compiler

Status
Not open for further replies.

Abhilashhegde94

Member level 1
Joined
Apr 19, 2015
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Activity points
276
Hey guys,

need help urgently on this one

i am getting garbage values in the terminal when i send a single character from controller uart to pc terminal.

The code is as follows:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <pic.h>
#include <xc.h>
#include<htc.h>
#define _XTAL_FREQ 8000000
#define baud_rate 9600
 
/* A simple demonstration of serial communications which
 * incorporates the on-board hardware USART of the Microchip
 * PIC16Fxxx series of devices. */
 
// PIC16F886 Configuration Bit Settings
 
// 'C' source line config statements
 
 
 
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
 
// CONFIG1
#pragma config "FOSC = HS"        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config "WDTE = OFF"       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config "PWRTE = OFF"      // Power-up Timer Enable bit (PWRT disabled)
#pragma config "MCLRE = OFF"      // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config "CP = OFF"         // Code Protection bit (Program memory code protection is disabled)
#pragma config "CPD = OFF"        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config "BOREN = ON"      // Brown Out Reset Selection bits (BOR disabled)
#pragma config "IESO = OFF"       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config "FCMEN = OFF"      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config "LVP = OFF"        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
 
// CONFIG2
#pragma config "BOR4V = BOR40V"   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config "WRT = OFF"        // Flash Program Memory Self Write Enable bits (Write protection off)
 
   char UART_Init(const long int baudrate)
{
  unsigned int x;
  x = (_XTAL_FREQ - baudrate*64)/(baudrate*64); //SPBRG for Low Baud Rate
  if(x>255) //If High Baud Rate required
  {
    x = (_XTAL_FREQ - baudrate*16)/(baudrate*16); //SPBRG for High Baud Rate
    BRGH = 1; //Setting High Baud Rate
  }
  if(x<256)
  {
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
    TRISC7 = 1;
    TRISC6 = 1;
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
    return 1;
  }
  return 0;
}
 
void UART_Write(char data)
{
    while(!PIR1bits.TXIF);
  while(!TRMT); //Waiting for Previous Data to Transmit completly
  TXREG = data; //Writing data to Transmit Register, Starts transmission
}
 
char UART_TX_Empty()
{
  return TRMT; //Returns Transmit Shift Status bit
}
 
void UART_Write_Text(const char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
    UART_Write(text[i]);
 
}
 
//recive part
char UART_Data_Ready()
{
  return RCIF;
}
 
char UART_Read()
{
  while(!RCIF); //Waits for Reception to complete
  return RCREG; //Returns the 8 bit data
}
 
void UART_Read_Text(char *Output, unsigned int length)
{
  int i;
  for(int i=0;i<length;i++)
    Output[i] = UART_Read();
}
 
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){
 const unsigned char arr='B';
    INTCON=0;   // purpose of disabling the interrupts.
 
     UART_Init(baud_rate);
         __delay_ms(300);// set up the USART - settings defined in usart.h
        TRISB=0x00;
    // Output a message to prompt the user for a keypress
    //printf("\rPress a key and I will echo it back:\n");
    
 
            // read a response from the user
               
                    UART_Write(arr);
                
 
 
            //    __delay_ms(1000);
            //    PORTB=0xFF;
           //     __delay_ms(1000);
           //     PORTB=0X00;
 
 
                    // echo it back
    
}



I am getting this a garbage value printed in the terminal sir,

Pls help
 
Last edited by a moderator:

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
I have not read the datasheet but I guess TRISC6 = 1; should be TRISC6 = 0; for 16F. for 18F it should be 1.

If you are using 8 MHz Clock and SYNC = 0 and BRGH = 1 then SPBRG should be 51. It is given in the table in datasheet. It is for 9600 bps baudrate.

At the PC side have you set the baudrate of the COM port being used for testing to proper baudrate as used in PIC ?
 
Last edited:

Abhilashhegde94

Member level 1
Joined
Apr 19, 2015
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Activity points
276
i have given 9600 baud rate at the pc end sir, and when i make TRISC6=0 i get no output on terminal
 

Abhilashhegde94

Member level 1
Joined
Apr 19, 2015
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Activity points
276
i have done as you have told sir, but still no proper output is shown on terminal
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,273
Trophy points
1,413
Location
Southwest, USA
Activity points
62,485
First a question, your current code implies you are clocking your design with an 8MHz external crystal or oscillator. Is this correct?

One issue you are facing is the lack of a superloop to prevent the flow of execution from exiting your code into oblivion, which is why the garbage text you received seems to continually repeat.

Original Code Main():

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void main(void){
 const unsigned char arr='B';
    INTCON=0;   // purpose of disabling the interrupts.
 
     UART_Init(baud_rate);
         __delay_ms(300);// set up the USART - settings defined in usart.h
        TRISB=0x00;
    // Output a message to prompt the user for a keypress
    //printf("\rPress a key and I will echo it back:\n");
    
 
            // read a response from the user
               
                    UART_Write(arr);
                
 
 
            //    __delay_ms(1000);
            //    PORTB=0xFF;
           //     __delay_ms(1000);
           //     PORTB=0X00;
 
 
                    // echo it back
    
}



A superloop is typically implemented with a loop structure which is always true, as below.

Modified Code Main():


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void main(void){
    const unsigned char arr='B';
    INTCON=0;   // purpose of disabling the interrupts.
 
     UART_Init(baud_rate);
     __delay_ms(300);// set up the USART - settings defined in usart.h
     TRISB=0x00;
          
         UART_Write(arr);
                
         while(1)  // Superloop
        {
                // Prevents code execution from exiting normal code flow
        }
 
 }



I've made some change to utilize the internal oscillator configure for 8MHz, removed some code, modified some code and managed to get meaningful output on a terminal set to 9600 8-N-1. The current version echos text typed into a terminal back to the user.

Modified Version of Code:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <xc.h>
#include <stdio.h>
 
 
#define _XTAL_FREQ 8000000
#define baud_rate 9600
 
/* A simple demonstration of serial communications which
 * incorporates the on-board hardware USART of the Microchip
 * PIC16Fxxx series of devices. */
 
// PIC16F886 Configuration Bit Settings
 
// 'C' source line config statements
 
 
 
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
 
// CONFIG1
#pragma config "FOSC = INTRC_NOCLKOUT"          // Oscillator Selection bits (INTRC_NOCLKOUT oscillator: Internal Oscillator with No Clock Output on Pins)
#pragma config "WDTE = OFF"                     // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config "PWRTE = OFF"                    // Power-up Timer Enable bit (PWRT disabled)
#pragma config "MCLRE = ON"                     // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config "CP = OFF"                       // Code Protection bit (Program memory code protection is disabled)
#pragma config "CPD = OFF"                      // Data Code Protection bit (Data memory code protection is disabled)
#pragma config "BOREN = ON"                     // Brown Out Reset Selection bits (BOR disabled)
#pragma config "IESO = OFF"                     // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config "FCMEN = OFF"                    // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config "LVP = OFF"                      // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
 
// CONFIG2
#pragma config "BOR4V = BOR40V"                 // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config "WRT = OFF"                      // Flash Program Memory Self Write Enable bits (Write protection off)
 
   char UART_Init(long baudrate)
{
  unsigned int x;
  x = (_XTAL_FREQ - baudrate*64)/(baudrate*64); //SPBRG for Low Baud Rate
  if(x>255) //If High Baud Rate required
  {
    x = (_XTAL_FREQ - baudrate*16)/(baudrate*16); //SPBRG for High Baud Rate
 
    BRGH = 1; //Setting High Baud Rate
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
//    TRISC7 = 1;   //Not Needed Or Recommended
//    TRISC6 = 1;   //Not Needed Or Recommended
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
  }
  if(x<256)
  {
    BRGH = 0; //Setting High Baud Rate
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
//    TRISC7 = 1;   //Not Needed Or Recommended
//    TRISC6 = 1;   //Not Needed Or Recommended
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
    return 1;
  }
  return 0;
}
 
void UART_Write(unsigned char data)
{
    while(!PIR1bits.TXIF);
  while(!TRMT); //Waiting for Previous Data to Transmit completly
  TXREG = data; //Writing data to Transmit Register, Starts transmission
}
 
char UART_TX_Empty()
{
  return TRMT; //Returns Transmit Shift Status bit
}
 
void UART_Write_Text(const char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
    UART_Write(text[i]);
 
}
 
//recive part
char UART_Data_Ready()
{
  return RCIF;
}
 
char UART_Read()
{
  while(!RCIF); //Waits for Reception to complete
  return RCREG; //Returns the 8 bit data
}
 
void UART_Read_Text(char *Output, unsigned int length)
{
  int i;
  for(int i=0;i<length;i++)
    Output[i] = UART_Read();
}
 
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){
 
    const unsigned char * arr = "Enter Some Text: ";
 
    OSCCONbits.IRCF = 0x07;  // Configure Internal OSC for 8MHz Clock
 
 
 
    while(!OSCCONbits.HTS);   // Wait Until Internal Osc is Stable
 
    INTCON=0;   // purpose of disabling the interrupts.
 
    UART_Init(baud_rate);
 
    
    UART_Write_Text(arr);  // Send Intial Message
 
    while(1)
    {
        // read a response from the user and echo it back
        UART_Write(UART_Read());
    }
 
}

 

Abhilashhegde94

Member level 1
Joined
Apr 19, 2015
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Activity points
276
Pic16f886 using MPLAB X C8 compiler -UART problem sending strings

here is the code,
Code:
/* 
 * File:   Mastercode1.c
 * Author: Toufique
 *
 * Created on April 20, 2015, 3:53 PM
 */

#include <stdio.h>
#include <stdlib.h>
#include "uartw.h"
#include "i2c.h"

#define _XTAL_FREQ 8000000
#define baud_rate 9600
/*
 * 
 */

void main(void){

    const unsigned char * arr = "taking in the text ";
    const unsigned char * arr1 = "sent ";
    unsigned char is;

    OSCCONbits.IRCF = 0x07;  // Configure Internal OSC for 8MHz Clock



    while(!OSCCONbits.HTS);   // Wait Until Internal Osc is Stable

    INTCON=0;   // purpose of disabling the interrupts.
    
    UART_Init(baud_rate);
    __delay_ms(500);
    UART_Write_Text(arr);
    i2c_Free();
   i2c_Start();
     i2c_Free();
     i2c_SendAddress(0x00,0);
     while(1)
     {
         UART_Write_Text(UART_Read_Text());
         i2c_SendByte(UART_Read());
     
      //   if(i2c_ReadAcknowledge())
    // {
         
    // }
     UART_Write_Text(arr1);
     i2c_SendAcknowledge(I2C_LAST);
     i2c_Stop();
     }

}
i am just trying to echo a string which i entered in my terminal.
I am getting initial text as in code but string i enter is not outputted in terminal.

uartw.h is as follows:

Code:
/* 
 * File:   uartw.h
 * Author: Toufique
 *
 * Created on April 20, 2015, 5:15 PM
 */
#include<xc.h>


#ifndef UARTW_H
#define	UARTW_H

#define _XTAL_FREQ 8000000
#define baud_rate 9600

#ifdef	__cplusplus
extern "C" {
#endif


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

// PIC16F886 Configuration Bit Settings

// 'C' source line config statements



// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config "FOSC = INTRC_NOCLKOUT"          // Oscillator Selection bits (INTRC_NOCLKOUT oscillator: Internal Oscillator with No Clock Output on Pins)
#pragma config "WDTE = OFF"                     // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config "PWRTE = OFF"                    // Power-up Timer Enable bit (PWRT disabled)
#pragma config "MCLRE = ON"                     // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config "CP = OFF"                       // Code Protection bit (Program memory code protection is disabled)
#pragma config "CPD = OFF"                      // Data Code Protection bit (Data memory code protection is disabled)
#pragma config "BOREN = ON"                     // Brown Out Reset Selection bits (BOR disabled)
#pragma config "IESO = OFF"                     // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config "FCMEN = OFF"                    // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config "LVP = OFF"                      // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config "BOR4V = BOR40V"                 // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config "WRT = OFF"                      // Flash Program Memory Self Write Enable bits (Write protection off)

   char UART_Init(long baudrate)
{
  unsigned int x;
  x = (_XTAL_FREQ - baudrate*64)/(baudrate*64); //SPBRG for Low Baud Rate
  if(x>255) //If High Baud Rate required
  {
    x = (_XTAL_FREQ - baudrate*16)/(baudrate*16); //SPBRG for High Baud Rate

    BRGH = 1; //Setting High Baud Rate
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
//    TRISC7 = 1;   //Not Needed Or Recommended
//    TRISC6 = 1;   //Not Needed Or Recommended
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
  }
  if(x<256)
  {
    BRGH = 0; //Setting High Baud Rate
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
//    TRISC7 = 1;   //Not Needed Or Recommended
//    TRISC6 = 1;   //Not Needed Or Recommended
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
    return 1;
  }
  return 0;
}

void UART_Write(unsigned char data)
{
    while(!PIR1bits.TXIF);
  while(!TRMT); //Waiting for Previous Data to Transmit completly
  TXREG = data; //Writing data to Transmit Register, Starts transmission
}

char UART_TX_Empty()
{
  return TRMT; //Returns Transmit Shift Status bit
}

void UART_Write_Text(const char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
    UART_Write(text[i]);

}

//recive part
char UART_Data_Ready()
{
  return RCIF;
}

char UART_Read()
{
  while(!RCIF); //Waits for Reception to complete
  return RCREG; //Returns the 8 bit data
}

unsigned char * UART_Read_Text()
{
 unsigned char *string, x, i = 0;

//receive the characters until ENTER is pressed (ASCII for ENTER = 13)
while((x = UART_Read()) != 13)
{
 //and store the received characters into the array string[] one-by-one
string[i++] = x;
}

//insert NULL to terminate the string
string[i] = '\0';

//return the received string
return(string);
}

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;
}






#ifdef	__cplusplus
}
#endif

#endif	/* UARTW_H */

Pls help me guys ASAP.Project deadline approaching

- - - Updated - - -

My i2c.h code is as follows:

Code:
#include	<htc.h>
#include<xc.h>
#include 	"i2c.h"
#define _XTAL_FREQ 8000000
#define baud_rate 9600

/*
 *	I2C functions for HI-TECH PIC C - master mode only
 */

/*
 * 	TIMING - see Philips document: THE I2C-BUS SPECIFICATION
 */


/*
 * 	Send stop condition
 * 	  - data low-high while clock high
 */

void
i2c_Stop(void)
{
	/* don't assume SCL is high on entry */

	SDA_LOW();					/* ensure data is low first */
	SCL_HIGH();
	
	__delay_us(I2C_TM_DATA_SU);
	SCL_DIR = I2C_INPUT;		/* float clock high */
	__delay_us(I2C_TM_STOP_SU);
	SDA_HIGH();					/* the low->high data transistion */
	__delay_us(I2C_TM_BUS_FREE);	/* bus free time before next start */
	SDA_DIR = I2C_INPUT;		/* float data high */

	return;
}

/*
 * 	Send (re)start condition
 * 	  - ensure data is high then issue a start condition
 * 	  - see also i2c_Start() macro
 */

void
i2c_Restart(void)
{
	SCL_LOW();					/* ensure clock is low */
	SDA_HIGH();					/* ensure data is high */

	__delay_us(I2C_TM_DATA_SU);

	SCL_DIR = I2C_INPUT;		/* clock pulse high */
	__delay_us(I2C_TM_SCL_HIGH);

	SDA_LOW();					/* the high->low transition */
	__delay_us(I2C_TM_START_HD);
	return;
}

/*
 * 	Send a byte to the slave
 * 	  - returns true on error
 */
unsigned char
i2c_SendByte(unsigned char byte)
{
	signed char i;

	for(i=7; i>=0; i--)
	{
		SCL_LOW();					/* drive clock low */
		
		/* data hold time = 0, send data now */
        SDA_DIR = ((byte>>i)&0x01);
        if ((byte>>i)&0x01) {		/* bit to send */
			SDA_HIGH();
        }else {
			SDA_LOW();
        }
		__delay_us(I2C_TM_DATA_SU);
		SCL_DIR = I2C_INPUT;		/* float clock high */

		if(i2c_WaitForSCL())		/* wait for clock release */
			return TRUE;			/* bus error */

		__delay_us(I2C_TM_SCL_HIGH);	/* clock high time */
	}
	
	return FALSE;
}

/*
 * 	send an address and data direction to the slave
 * 	  - 7-bit address (lsb ignored)
 * 	  - direction (FALSE = write )
 */
unsigned char
i2c_SendAddress(unsigned char address, unsigned char rw)
{
	return i2c_SendByte(address | (rw?1:0));
}

/*
 * 	Check for an acknowledge
 * 	  - returns ack or ~ack, or ERROR if a bus error
 */
signed char
i2c_ReadAcknowledge(void)
{
	unsigned char ack;

	SCL_LOW();						/* make clock is low */
	SDA_DIR = I2C_INPUT;			/* disable data line - listen for ack */
	__delay_us(I2C_TM_SCL_TO_DATA);	/* SCL low to data out valid */
	SCL_DIR = I2C_INPUT;			/* float clock high */
	__delay_us(I2C_TM_DATA_SU);
	ack = SDA;						/* read the acknowledge */

	/* wait for slave to release clock line after processing byte */
	if(i2c_WaitForSCL())
		return I2C_ERROR;
	return ack;
}

/*
 * 	Read a byte from the slave
 * 	  - returns the byte, or I2C_ERROR if a bus error
 */
int
i2c_ReadByte(void)
{
	unsigned char i;
	unsigned char byte = 0;

	for(i=0; i<8; i++)
	{
		SCL_LOW();					/* drive clock low */
		__delay_us(I2C_TM_SCL_LOW);	/* min clock low  period */
		SDA_DIR = I2C_INPUT;		/* release data line */

		SCL_DIR = I2C_INPUT;		/* float clock high */
		if(i2c_WaitForSCL())
			return I2C_ERROR;
		__delay_us(I2C_TM_SCL_HIGH);
		byte = byte << 1;		/* read the next bit */
		byte |= SDA;
	}
	return (int)byte;
}

/*
 * 	Send an (~)acknowledge to the slave
 * 	  - status of I2C_LAST implies this is the last byte to be sent
 */
void
i2c_SendAcknowledge(unsigned char status)
{
	SCL_LOW();
	if ( status & 0x01) {
		SDA_LOW();				/* drive line low -> more to come */
	}else { 
		SDA_HIGH();
	}
	__delay_us(I2C_TM_DATA_SU);
	SCL_DIR = I2C_INPUT;		/* float clock high */
	__delay_us(I2C_TM_SCL_HIGH);
	return;
}

/*
 * 	Send a byte to the slave and acknowledges the transfer
 * 	  - returns I2C_ERROR, ack or ~ack
 */
signed char
i2c_PutByte(unsigned char data)
{
	if(i2c_SendByte(data))
		return I2C_ERROR;
	return i2c_ReadAcknowledge();	/* returns ack, ~ack */
}

/*
 * 	Get a byte from the slave and acknowledges the transfer
 * 	  - returns true on I2C_ERROR or byte
 */
int
i2c_GetByte(unsigned char more)
{
	int byte;

	if((byte = i2c_ReadByte()) == I2C_ERROR)
		return I2C_ERROR;

	i2c_SendAcknowledge(more);

	return byte;
}

/*
 * 	Send an array of bytes to the slave and acknowledges the transfer
 * 	  - returns number of bytes not successfully transmitted
 */
int
i2c_PutString(const unsigned char *str, unsigned char length)
{
	signed char error;

	while(length)
	{
		if((error = i2c_PutByte(*str)) == I2C_ERROR)
			return -(int)length;					/* bus error */
		else
			if(error)
				return (int)length;					/* non acknowledge */
		str++;
		length--;
	}

	return FALSE;									/* everything OK */
}

/*
 * 	Reads number bytes from the slave, stores them at str and acknowledges the transfer
 * 	  - returns number of bytes not successfully read in
 */
unsigned char
i2c_GetString(unsigned char *str, unsigned char number)
{
	int byte;

	while(number)
	{
		if((byte = i2c_GetByte(number-1)) == I2C_ERROR)
			return number;								/* bus error */
		else
			*str = (unsigned char)byte;
		str++;
		number--;
	}

	return FALSE;										/* everything OK */
}

/*
 * 	Opens communication with a device at address. mode
 * 	indicates I2C_READ or I2C_WRITE.
 * 	  - returns TRUE if address is not acknowledged
 */
unsigned char
i2c_Open(unsigned char address, unsigned char mode)
{
	i2c_Start();
	i2c_SendAddress(address, mode);
	if(i2c_ReadAcknowledge()) 
		return TRUE;

	return FALSE;
}

/*
 * 	wait for the clock line to be released by slow slaves
 * 	  - returns TRUE if SCL was not released after the
 * 	    time out period.
 * 	  - returns FALSE if and when SCL released
 */
unsigned char
i2c_WaitForSCL(void)
{
	/* SCL_DIR should be input here */
	if(!SCL)
	{
		__delay_us(I2C_TM_SCL_TMO);
		/* if the clock is still low -> bus error */
		if(!SCL)
			return TRUE;
	}
	return FALSE;
}

void
i2c_Free()
{
	unsigned char ucI;

	SDA_DIR=I2C_INPUT;
	for(ucI=0;ucI!=9;ucI++)
	{
		SCL_HIGH();
		__delay_us(5);
		SCL_LOW();
		__delay_us(5);
	}
}

unsigned char i2c_read(unsigned char ucAdr)
{
	unsigned char ucDat;

	if (i2c_ReadFrom(ucAdr)==0)
	{
		ucDat=i2c_GetByte(I2C_MORE);
		i2c_Stop();

	}

	return(ucDat);
}
and i2c.h file which i include in main file is as follows:

Code:
#ifndef	_I2C_H_
#define _I2C_H_

/*
 *	SDA (data) and SCL (clock) bits
 *	
 *	Special note!!!
 *	
 *	If the clock and data lines are in the same port, you will need
 *	to beware of the Read/Modify/Write issue in the PIC - since
 *	a bit set or clear on any one bit in a port will read and write
 *	back all other bits. 
 */


/* Uncomment the next line to use the PIC's SSP Module*/
#define I2C_MODULE 1

#ifdef I2C_MODULE
/* I2C module uses PORT C */
#define SCL             RC3             /* clock on port C bit 2 */
#define SCL_DIR         TRISC3
#define SDA     RC4                     /* data on port C bit 1 */
#define SDA_DIR         TRISC4
#define I2CTRIS TRISC
#define MASTER_MODE     0B1011          /* I2C firmware controlled Master Mode (slave idle) */
#define SSPMode(val)   SSPCON &=0xF0; SSPCON|=(val & 0xf)

#else
/* Change port as required - defaults to port b */
#define	SCL		RB2		/* clock on port B bit 2 */
#define	SCL_DIR		TRISB2

#define SDA             RB1             /* data on port B bit 1 */
#define	SDA_DIR		TRISB1
#define I2CTRIS TRISB

#endif

#define M_SDA_INP	0x02
#define M_SDA_OUT   0xFD
#define M_SCL_INP   0x04
#define M_SCL_OUT	0xFB

#define I2C_INPUT	1		/* data direction input */
#define I2C_OUTPUT	0		/* data direction output */

#define I2C_READ	0x01		/* read bit used with address */
#define I2C_WRITE	0x00		/* write bit used with address */

#define FALSE		0
#define TRUE		!FALSE

#define I2C_ERROR	(-1)
#define I2C_LAST	FALSE		/* SendAck: no more bytes to send */
#define I2C_MORE	TRUE		/* SendAck: more bytes to send */

#define i2c_Start()		i2c_Restart()
#define i2c_WriteTo(address)	i2c_Open((address), I2C_WRITE)
#define i2c_ReadFrom(address)	i2c_Open((address), I2C_READ)

#ifdef I2C_MODULE
#define SCL_HIGH() SCL_DIR = I2C_INPUT
#define SCL_LOW()  SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA_DIR = I2C_INPUT
#define SDA_LOW()  SDA_DIR = I2C_OUTPUT
#else
#define SCL_HIGH() SCL = 1; SCL_DIR = I2C_OUTPUT
#define SCL_LOW()  SCL = 0; SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA = 1; SDA_DIR = I2C_OUTPUT
#define SDA_LOW()  SDA = 0; SDA_DIR = I2C_OUTPUT
#endif

/*
 * Timings for the i2c bus. Times are rounded up to the nearest
 * micro second.
 */

#define I2C_TM_BUS_FREE		10
#define	I2C_TM_START_SU		10
#define I2C_TM_START_HD		8
#define I2C_TM_SCL_LOW		10
#define	I2C_TM_SCL_HIGH		8
#define I2C_TM_DATA_SU		2
#define I2C_TM_DATA_HD          0
#define I2C_TM_SCL_TO_DATA	8	/* SCL low to data valid */
#define	I2C_TM_STOP_SU		8
#define I2C_TM_SCL_TMO		20	/* clock time out */

extern signed char	i2c_ReadAcknowledge(void);
extern unsigned char	i2c_SendAddress(unsigned char, unsigned char);
extern unsigned char	i2c_SendByte(unsigned char);
extern int		i2c_ReadByte(void);
extern void		i2c_Restart(void);
extern void		i2c_Stop(void);
extern void		i2c_SendAcknowledge(unsigned char);
extern signed char	i2c_PutByte(unsigned char);
extern int		i2c_GetByte(unsigned char);
extern unsigned char	i2c_Open(unsigned char, unsigned char);
extern unsigned char	i2c_GetString(unsigned char *, unsigned char);
extern int		i2c_PutString(const unsigned char *, unsigned char);
extern unsigned char	i2c_WaitForSCL(void);
extern void 		i2c_Free(void);
extern unsigned char	i2c_read(unsigned char);
#endif			/* _I2C_H_ */
Pls help
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,273
Trophy points
1,413
Location
Southwest, USA
Activity points
62,485
Small progressive steps, wins the day!

The first rule when coding or debugging is to make small incremental changes and then test those changes, rather than attempt to introduce many new features and then attempt to determine why the code is not functioning as expected.

Therefore, set aside the I2C interface routines and concentrate on the UART routines.

Also, it is quite evident you do not fully understand the function of the superloop.

I suggest you study the following comments concerning the superloop stucture and rewrite your code leaving out the I2C routines for the time being.

void main(void)
{
// Code area to setup, initialize and configure various system features.
// Statements and Routines located here are ran only once!


while(1)
{
// Code area for statements and routines to be ran repeatedly
// Once the superloop is entered it is only exited by system reset
// Or to service an interrupt by ISR

}

// In principle code following the superloop will never be executed.
// Any code statements or routines called, will can be treated as nonexistent


}
 

Abhilashhegde94

Member level 1
Joined
Apr 19, 2015
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Activity points
276
I am still not able to get it right sir,Should i call in UART_Read_Text and UART_write_Text inside the superloop or outside so that i get the correct output.
I have commented all i2c codes sir

- - - Updated - - -

i executed in the way wht u told and i pretty sure that :whatever i read through the keyboard gets stored in some memory.
could u pls tel me one thing.
When i return a pointer from a function after manipulating it (incrementing it and storing values in subsequent addresses),wil it return the base address of the point or will it return the last address where it stored its value in.

this is important since after reading a string i am not able to output the same through another memory where the returned string from UART_Read_Text() is stored inside another memory(character pointer) in the calling function i.e main.
 

Abhilashhegde94

Member level 1
Joined
Apr 19, 2015
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
India
Activity points
276
Code:
#include <stdio.h>
#include <stdlib.h>
#include "uartw.h"
#include "i2c.h"

#define _XTAL_FREQ 8000000
#define baud_rate 9600
/*
 * 
 */

void main(void){

    const unsigned char * arr = "taking in the text ";
   const unsigned char * arr1 = "abhilash";
    unsigned char *is;

    OSCCONbits.IRCF = 0x07;  // Configure Internal OSC for 8MHz Clock



    while(!OSCCONbits.HTS);   // Wait Until Internal Osc is Stable

    INTCON=0;   // purpose of disabling the interrupts.
    
    UART_Init(baud_rate);
    __delay_ms(500);
    UART_Write_Text(arr);
   // i2c_Free();
 //  i2c_Start();
     //i2c_Free();
   //  i2c_SendAddress(0x00,0);

//receive the characters until ENTER is pressed (ASCII for ENTER = 13)
    
    is=UART_Read_Text();
    UART_Write_Text(arr1);
    UART_Write_Text(is);
    while(1)
    {


    }


      //   i2c_SendByte(UART_Read());
     
      //   if(i2c_ReadAcknowledge())
    // {
         
    // 
    // i2c_SendAcknowledge(I2C_LAST);
    // i2c_Stop();



}
The UART_Read_TExt() function return the string pointer read.

- - - Updated - - -

Thank you sir , i finally found out the flaw ,it turned out that my UART_Read_Text() function was a bit wrong , i just made the locally declared string in the function an array which was before declared as pointer.
THAT SOLVED IT.Rest all code which i posted above remains the same except for that Read funtion being changed as followed:
Code:
unsigned char * UART_Read_Text()
{
    unsigned const char *a="Keyed in stopped";
  unsigned char string[];
          unsigned char x, i = 0;

//receive the characters until ENTER is pressed (ASCII for ENTER = 13)
while((x = UART_Read()) != 13)
{
 //and store the received characters into the array string[] one-by-one
string[i++] = x;
}

//insert NULL to terminate the string
string[i] = '\0';
UART_Write_Text(a);

//return the received string
return(string);
}
Next on the scanner is I2C master communication :D
 
Last edited:

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,273
Trophy points
1,413
Location
Southwest, USA
Activity points
62,485
The first issue is the string buffer, is, which is only declared, not defined.

When you utilize a buffer like, is, you must define a length or size of the buffer.

Instead of the following:

Code:
   unsigned char *is;
try:

Code:
   unsigned char is[25];  // Defines a string buffer for a maximum of 24 characters and a null terminator
You will also need to modify the string buffer in the UART_Read_Text() routine by passing the pointer of string buffer is to the routine.

I have modified the code according and tested it:

uart.h

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * File:   uart.h
 * Author: Toufique
 *
 * Created on April 20, 2015, 5:15 PM
 */
 
 
 
#ifndef UART_H
#define UART_H
 
 
#ifdef  __cplusplus
extern "C" {
#endif
 
#include <xc.h>
 
#define _XTAL_FREQ 8000000
#define baud_rate 9600
 
 
/* A simple demonstration of serial communications which
 * incorporates the on-board hardware USART of the Microchip
 * PIC16Fxxx series of devices. */
 
 
 
   char UART_Init(long baudrate)
{
  unsigned int x;
  x = (_XTAL_FREQ - baudrate*64)/(baudrate*64); //SPBRG for Low Baud Rate
  if(x>255) //If High Baud Rate required
  {
    x = (_XTAL_FREQ - baudrate*16)/(baudrate*16); //SPBRG for High Baud Rate
 
    BRGH = 1; //Setting High Baud Rate
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
//    TRISC7 = 1;   //Not Needed Or Recommended
//    TRISC6 = 1;   //Not Needed Or Recommended
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
  }
  if(x<256)
  {
    BRGH = 0; //Setting High Baud Rate
    SPBRG = x; //Writing SPBRG register
    SYNC = 0; //Selecting Asynchronous Mode
    SPEN = 1; //Enables Serial Port
//    TRISC7 = 1;   //Not Needed Or Recommended
//    TRISC6 = 1;   //Not Needed Or Recommended
    CREN = 1; //Enables Continuous Reception
    TXEN = 1; //Enables Transmission
    return 1;
  }
  return 0;
}
 
void UART_Write(const unsigned char data)
{
    while(!PIR1bits.TXIF);
  while(!TRMT); //Waiting for Previous Data to Transmit completly
  TXREG = data; //Writing data to Transmit Register, Starts transmission
}
 
char UART_TX_Empty()
{
  return TRMT; //Returns Transmit Shift Status bit
}
 
void UART_Write_Text(const unsigned char *text)
{
  int i;
  for(i=0;text[i]!='\0';i++)
    UART_Write(text[i]);
 
}
 
//recive part
char UART_Data_Ready()
{
  return RCIF;
}
 
char UART_Read()
{
  while(!RCIF); //Waits for Reception to complete
  return RCREG; //Returns the 8 bit data
}
 
void UART_Read_Text(unsigned char *string)
{
 unsigned char  x, i = 0;
 
//receive the characters until ENTER is pressed (ASCII for ENTER = 13)
while((x = UART_Read()) != '\r')
{
 //and store the received characters into the array string[] one-by-one
string[i++] = x;
}
 
//insert NULL to terminate the string
string[i] = '\0';
 
}
 
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;
}
 
 
 
 
 
 
#ifdef  __cplusplus
}
#endif
 
#endif  /* UART_H */



config.h

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/* 
 * File:   config.h
 * Author: ssmith
 *
 * Created on April 20, 2015, 12:04 AM
 */
 
#ifndef CONFIG_H
#define CONFIG_H
 
#ifdef  __cplusplus
extern "C" {
#endif
 
// PIC16F886 Configuration Bit Settings
 
// 'C' source line config statements
 
 
 
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
 
// CONFIG1
#pragma config "FOSC = INTRC_NOCLKOUT"          // Oscillator Selection bits (INTRC_NOCLKOUT oscillator: Internal Oscillator with No Clock Output on Pins)
#pragma config "WDTE = OFF"                     // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config "PWRTE = OFF"                    // Power-up Timer Enable bit (PWRT disabled)
#pragma config "MCLRE = ON"                     // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config "CP = OFF"                       // Code Protection bit (Program memory code protection is disabled)
#pragma config "CPD = OFF"                      // Data Code Protection bit (Data memory code protection is disabled)
#pragma config "BOREN = ON"                     // Brown Out Reset Selection bits (BOR disabled)
#pragma config "IESO = OFF"                     // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config "FCMEN = OFF"                    // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config "LVP = OFF"                      // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
 
// CONFIG2
#pragma config "BOR4V = BOR40V"                 // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config "WRT = OFF"                      // Flash Program Memory Self Write Enable bits (Write protection off)
 
 
#ifdef  __cplusplus
}
#endif
 
#endif  /* CONFIG_H */





main.c

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <xc.h>
#include <stdio.h>
#include "config.h"
#include "uart.h"
 
 
 
 
void main(void){
 
    const unsigned char * arr = "Enter Some Text and Hit Return: \n\r";
    unsigned char buf[25];
 
    OSCCONbits.IRCF = 0x07;  // Configure Internal OSC for 8MHz Clock
 
 
 
    while(!OSCCONbits.HTS);   // Wait Until Internal Osc is Stable
 
    INTCON=0;   // purpose of disabling the interrupts.
 
    UART_Init(baud_rate);
 
    UART_Write_Text(arr);  // Send Intial Message
 
    while(1)
    {
        // read a response from the user and store in string buffer
       UART_Read_Text(buf);
       
       // echo string in buffer back to user
       UART_Write_Text((const unsigned char *)buf);
 
       // append newline and return
       UART_Write_Text("\n\r");
 
    }
 
}



Notice the call to routine:
Code:
 UART_Write_Text(arr);  // Send Intial Message
Is outside the superloop and only occurs once and hence the initial message is only sent to the user terminal once, before code execution flow enters the superloop.

Once the code execution flow enters the superloop the calls to the routines contained within continually repeat until the microcontroller is reset.

The call to the routine:
Code:
UART_Read_Text(buf);
Accepts characters until the carriage return (Enter - '\r') is received and then returns code execution back to main, where the two calls to the routine:
Code:
UART_Write_Text(buf);
Are made echoing the received text back to the user and sending a newline and carriage return to move the terminal cursor to the next line.

Good Luck with your endeavors,

BigDog

- - - Updated - - -

Update:

I've reviewed your latest version of the code and there are serious issues which should be addressed.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unsigned char * UART_Read_Text()
{
    unsigned const char *a="Keyed in stopped";
  unsigned char string[];
          unsigned char x, i = 0;
 
//receive the characters until ENTER is pressed (ASCII for ENTER = 13)
while((x = UART_Read()) != 13)
{
 //and store the received characters into the array string[] one-by-one
string[i++] = x;
}
 
//insert NULL to terminate the string
string[i] = '\0';
UART_Write_Text(a);
 
//return the received string
return(string);
}



The string buffer:
Code:
unsigned char string[];
Should be declared within main(), not within the routine and you need to specify its size as I have done in my previous examples.

All "automatic variables" declared within a code block or routine/function are removed from the stack upon code execution exiting, returning from the routine back to main() and essentially are lost.

Therefore you need to defined the string buffer within main() along with its size:
Code:
unsigned char string[25];
You were just lucky nothing within your code overwrote the previous contents of string[] and corrupted the text.
 
Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top