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.

Something wrong with PIC18F4620??

Status
Not open for further replies.

insaniac

Newbie level 6
Joined
Sep 6, 2005
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Argentina
Activity points
1,441
sspcon2bits.ackstat stuck

I'm migrating my PIC18F452 code to a PIC18F4620 and I'm stuck with the I2C code. What was working fine in the 452 now is not in the 4620.
Does anybody encountered with this sort of problems.

It is prety much important for me to make this thing work so any kind of help would be appreciated.

Thank you all.
 

lcd pic18f4620 ccs

I had the same problem when I ported an I2C slave code from 18F452 to 18F6520.

PM me your code and I will take a look at it if you like.

best regards
 

pic18f4620 lcd

The functions of my i2c code are these, the whole code is a little more complex but there are only functions calling these functions shown above.
I certainly don't know what could be wrong, every call to the send or receive functions waits for the bus to be idle, I'm checking the right bits everywhere, and the rising and falling times of my clock are within the data sheet's values.

void Init_i2c(void)
{
char x;

TRIS_SDA = INPUT;
TRIS_SCL = INPUT;

SSPSTAT = 0b10000000;
SSPCON1 = 0b00111000;
SSPCON2 = 0b00000000;
SSPADD = 0x63; // low clk freq --> 25[KHz]

x = SSPBUF; // dummy read clears BF

SSPIE = 0;
SSPIP = 0;
SSPIF = 0;
PEIE = 1;
}


void I2CIdle (void)
{
while ( (SSPCON2 & 0x1F) | (RW) )
{
if (SSPIF)
SSPIF = 0;
continue;
}
}

void Send_i2c (char datoX)
{
char ackflag = 0;

do
{
while ((SSPCON2 & 0X1F)| RW)// == i2c_idle();
continue;
Data_Buf = datoX;
while (BF);
SSPIF = 0;
if (ACKDT)
{
ackflag = 1;
}
}while(ackflag);
}

char Receive_i2c (char ack)
{
char d;
I2CIdle(); // Make sure the bus is idle
RCEN = 1; // Enable Reception
while(RCEN && BF); // Wait for the BF flag to be set.
if (ACKSTAT == 0)
I2CAck();
else
I2CNack();
return (SSPBUF); // Return the value.
}

void Start_i2c (void)
{
I2CIdle(); // Make sure the bus is idle
SEN = 1; // Send start bit
while(SEN); // wait for it to clear
}

void Restart_i2c (void)
{
I2CIdle(); // Make sure the bus is idle
RSEN = 1; // Send restart bit
while (RSEN); // wait for it to clear
}

void Stop_i2c (void)
{
I2CIdle(); // Make sure the bus is idle
ACKDT = 1; // set to Nack
ACKEN = 1; // send Nack
PEN = 1; // send stop bit
while(PEN); // wait for it to clear
if (SSPIF)
SSPIF = 0; // Clear the interrupt flag
}

void I2CAck(void)
{
if (SSPIF)
SSPIF = 0;
ACKDT = 0; // set to Ack
ACKEN = 1; // Send Ack
}

void I2CNack(void)
{
if (SSPIF)
SSPIF = 0;
ACKDT = 1; // set to Nack
ACKEN = 1; // send Nack
}

Thanks for the help! I really need a hand with this

Added after 1 hours 17 minutes:

Sorry, the code shown before has several errors, it was an early an plenty of bugs version of the code.
The corrected version of the i2c functions are these. Sorry for the inconvenient


void Init_i2c(void)
{
char x;
TRIS_SDA = INPUT;
TRIS_SCL = INPUT;

SSPSTAT = 0b10000000;
SSPCON1 = 0b00111000;
SSPCON2 = 0b00000000;
SSPADD = 0x63;
x = SSPBUF; // dummy read clears BF

SSPIE = 0;
SSPIP = 0;
SSPIF = 0;
PEIE = 1;
}

void I2CIdle (void)
{
while ( (SSPCON2 & 0x1F) | (RW) )
{
if (SSPIF)
SSPIF = 0;
}
}

void Send_i2c (char datoX)
{
char ackflag = 0;

do
{
while ((SSPCON2 & 0X1F)| RW)// == i2c_idle();
{
if (SSPIF)
SSPIF = 0;
}
Data_Buf = datoX;
while (BF);
inte = 0;
if (ACK_recep)
{
ackflag = 1;
}
}while(ackflag);
}

char Receive_i2c (char ack)
{
char d;
I2CIdle(); // Make sure the bus is idle
RCEN = 1; // Enable Receive
while(RCEN); // Wait for the rcen flag to be cleared.
SSPIF = 0;
if (ack == 0)
{
ACKDT = 0;
ACKEN = 1;
}
else
{
ACKDT = 1;
ACKEN = 1;
}
d = SSPBUF;
return (d); // Return the value.
}

void Start_i2c (void)
{
I2CIdle(); // Make sure the bus is idle
SEN = 1; // Send start bit
while(SEN); // wait for it to clear
}

void Restart_i2c (void)
{
I2CIdle(); // Make sure the bus is idle
RSEN = 1; // Send restart bit
while (RSEN); // wait for it to clear
}

void Stop_i2c (void)
{
I2CIdle(); // Make sure the bus is idle
PEN = 1; // send stop bit
while(PEN); // wait for it to clear
}

Thanks again!!!
 

/*********************************************************************
* Filename: lcddemo.c *
* Date: 10/19/2002 *
* Edit by Yamato View ,Goldenchip Electronic Co. ,Ltd. *
* *
* TEL: 86-0591-3375855-721 *
* *
*********************************************************************/
#include <p18f458.h>
//#include <stdio.h>原来有此头文件,估计是用CCS或HITECH-C调试的
#include "lcd.h"
#include "i2c.h"
#include "stdlib.h"
#include "usart.h"

#define uchar unsigned char
#define uint unsigned int


extern void Init_Lcd(void);
extern void Line_1(void);
extern void Line_2(void);
extern void Write_Lcd_Data(unsigned char);
extern void Write_Lcd_Cmd(unsigned char);

static volatile unsigned char remdata;
void InterruptHandlerHigh(void);


#pragma code InterruptVectorHigh=0x08
void InterruptVectorHigh(void)
{
_asm
goto InterruptHandlerHigh
_endasm
}
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh()
{
while(PIR1bits.RCIF==1)
{
remdata=RCREG;
}
}

void Initialize_I2C_Master(void);
void EE_Page_Write(unsigned char,unsigned char,unsigned char,unsigned char *);
void EE_SEQU_Read(unsigned char,unsigned char,unsigned char,unsigned char *);
void EEPROM_Write(unsigned char,unsigned char,unsigned char);
void EEPROM_ACK(unsigned char);
unsigned char EEPROM_Read(unsigned char,unsigned char);
void I2C_Done(void);
void Initialize_Timer2(void);
void isr_high_direct(void);
void isr_high(void);

//***********************串口初始化************************
void initial(void)
{
SPBRG=0x19;
TXSTA=0x04;
RCSTA=0x80;
// TRISC=0x80;
TXSTAbits.TXEN=1;
RCSTAbits.CREN=1;
PIE1bits.RCIE=1;
INTCON=0xc0;
}

//***********************************************
//* Write a Byte to EEPROM *
//* - ctrl : Control Byte of EEPROM *
//* - addr : Location of EEPROM *
//* - data : Data Byte of EEPROM *
//***********************************************
void EEPROM_Write(unsigned char ctrl,unsigned char addr,unsigned char data)
{
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed and clear SSPIF flag

WriteI2C(ctrl); // Write Control+Write to EEPROM & Check BF flag
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); // Clear SSPIF flag

WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done();

WriteI2C(data); // Write Data to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done();

StopI2C(); // Stop condition
I2C_Done(); // Wait the Stop condition completed
}

//***********************************************
//* Pae Write to EEPROM
//*
//* - ctrl : Control Byte of EEPROM
//* - addr : Location of EEPROM
//* - length : Write counter
//* - *dptr : RAM point --> EEPROM
//*
//***********************************************
void EE_Page_Write(unsigned char ctrl,unsigned char addr,unsigned char length,unsigned char *dptr)
{
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed

WriteI2C(ctrl); // Write Control+Write to EEPROM & Check BF flag
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); // Clear SSPIF flag

WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done();

while (length!=0) // Check write completed ?
{
WriteI2C(*dptr); // Write data to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done();
dptr++; // Point to next byte
length--;
}

StopI2C(); // Stop condition
I2C_Done(); // Wait the Stop condition completed
}

//***********************************************
//* EEPROM Acknowledge Polling *
//* -- The routine will polling the ACK *
//* response from EEPROM *
//* -- ACK=0 return *
//* -- ACK=1 send Restart & loop check *
//***********************************************
void EEPROM_ACK(unsigned char ctrl)
{
unsigned char i;

IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed

WriteI2C(ctrl); // Write Control to EEPROM (WRITE)
I2C_Done(); // Clear SSPIF flag

while (SSPCON2bits.ACKSTAT) // test for Acknowledge from EEPROM
{
for (i=100;i>0;i--); // Delay for next Repet-Start

RestartI2C(); // initiate Repet-Start condition
I2C_Done(); // Wait Repet-Start condition completed

WriteI2C(ctrl); // Write Control to EEPROM (WRITE)
I2C_Done(); // Clear SSPIF flag
}
StopI2C(); // send STOP condition
I2C_Done(); // wait until stop condition is over
}

//***********************************************
//* Random Read a Byte from EEPROM *
//* - ctrl : Control Byte of EEPROM (Write) *
//* (Ctrl +1 ) : Read Command *
//* - addr : Address Byte of EEPROM *
//* - Return : Read Data from EEPROM *
//***********************************************
unsigned char EEPROM_Read(unsigned char ctrl,unsigned char addr)
{
unsigned char f;

IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed

WriteI2C(ctrl); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag

WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag

RestartI2C(); // initiate Restart condition
I2C_Done();

WriteI2C(ctrl+1); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag

f=ReadI2C(); // Enable I2C Receiver & wait BF=1 until received data
I2C_Done(); // Clear SSPIF flag

NotAckI2C(); // Genarate Non_Acknowledge to EEPROM
I2C_Done();

StopI2C(); // send STOP condition
I2C_Done(); // wait until stop condition is over

return(f); // Return Data from EEPROM
}

//***********************************************
//* Sequential Read from EEPROM
//*
//* - ctrl : Control Byte of EEPROM
//* - addr : Location of EEPROM
//* - length : Read counter
//* - *dptr : Store EEPROM data to RAM
//*
//***********************************************
void EE_SEQU_Read(unsigned char ctrl,unsigned char addr,unsigned char length,unsigned char *dptr)
{
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed

WriteI2C(ctrl); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag

WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag

RestartI2C(); // initiate Restart condition
I2C_Done();

WriteI2C(ctrl+1); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // Test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag

while (length!=0)
{
*dptr=ReadI2C(); // Enable I2C Receiver & Store EEPROM data to Point buffer
I2C_Done();
dptr++;
length--;

if (length==0) NotAckI2C();
else AckI2C(); // Continue read next data, send a acknowledge to EEPROM

I2C_Done();
}

StopI2C(); // send STOP condition
I2C_Done(); // wait until stop condition is over
}

//***********************************************
//* Check I2C action that is completed *
//***********************************************
void I2C_Done(void)
{
while (!PIR1bits.SSPIF); // Completed the action when the SSPIF is Hi.
PIR1bits.SSPIF=0; // Clear SSPIF
}

//************************************************
//* Initial I2C Master Mode with 7 bits Address *
//* Clock Speed : 100KHz @4MHz *
//************************************************
void Initialize_I2C_Master(void)
{
OpenI2C(MASTER,SLEW_ON);
SSPADD= 9;
}



void putch(unsigned char data)
{
Write_Lcd_Data(data);
}
void Init_System(void)
{
Init_Lcd();
INTCONbits.GIE = 0;
}



void main( void )
{
float fx;
float fy;
float fz;
long fl;
uchar fcount;
unsigned char sbuf[20];
uchar *pram;
unsigned char read_data;

TRISC = 0xdb;

Init_System();
initial();

Initialize_I2C_Master( );

while(1)
{
switch (remdata){
case 0x50:
TXREG=0x90;
do{
;
}while(BusyUSART());
TXREG=0x89;
do{
;
}while(BusyUSART());
TXREG=0x88;
do{
;
}while(BusyUSART());
TXREG=0x87;
break;
case 0x60:
TXREG=0x91;
break;
}
remdata=0x00;

//=========================
/*
EEPROM_Write(0xa0,1,1);
EEPROM_ACK(0xa0);
EEPROM_Write(0xa0,2,2);
EEPROM_ACK(0xa0);
EEPROM_Write(0xa0,3,3);
EEPROM_ACK(0xa0);
read_data=0;
read_data=EEPROM_Read(0xa0,3);
*/

for(fcount=0;fcount<20;fcount++)
sbuf[fcount]=0x30;

fl=123456789;
ltoa(fl,sbuf);
EE_Page_Write(0xa0,1,9,sbuf);
EEPROM_ACK(0xa0);
EE_SEQU_Read(0xa0,1,9,sbuf);

Line_1();


putch(0x35);putch(0x30);//原为PRINTF语句,调试不通,改为PUTCH

Line_2();



putch(sbuf[0]);
putch(sbuf[1]);
putch(sbuf[2]);
putch(sbuf[3]);
putch(sbuf[4]);
putch(sbuf[5]);
putch(sbuf[6]);
putch(sbuf[7]);
putch(sbuf[8]);
}
}


I'm a chinese,so my english is poor.
There is some idea about I2C in the code above.And,the compiler is Microchip C compiler V2.20B.

You can care the code about I2C,don't care the other code(for example ,lcd).

best regards!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top