View previous topic :: View next topic |
Author |
Message |
tn88test
Joined: 26 Feb 2013 Posts: 3
|
Problem with hardware i2c pic16f877a |
Posted: Tue Feb 26, 2013 9:45 pm |
|
|
I had been successful with software i2c to display timer with ds1307. Now I try with hardware i2c and there is a problem. The i2c bits doesn't automatically cleared by hardware.
example:
My program will stuck here because SSPIF is always 0. If I replace it with delay. The program passed through but displaying wrong result.
Code: | void WaitMSSP(void){
while(!SSPIF); // Wait to complete
SSPIF = 0;
} |
The same problem with other SEN, PEN , .... It doesn't automatically cleared by hardware. I check bit SEN, PEN bit to lcd. It's always 1 and not cleared to 0.
Here is my code
Code: | #ifndef _TWI_INCLUDED_
#define _TWI_INCLUDED_
#BYTE SSPSTAT = 0x094
#BIT BF = SSPSTAT.0
#BIT UA = SSPSTAT.1
#BIT R_W = SSPSTAT.2
#BIT CKE = SSPSTAT.6
#BIT SMP = SSPSTAT.7
#BYTE SSPCON0 = 0x014
#BIT SSPM0 = SSPCON0.0
#BIT SSPM1 = SSPCON0.1
#BIT SSPM2 = SSPCON0.2
#BIT SSPM3 = SSPCON0.3
#BIT CKP = SSPCON0.4
#BIT SSPEN = SSPCON0.5
#BIT SSPOV = SSPCON0.6
#BIT WCOL = SSPCON0.7
#BYTE SSPCON2 = 0x091
#BIT SEN = SSPCON2.0
#BIT RSEN = SSPCON2.1
#BIT PEN = SSPCON2.2
#BIT RCEN = SSPCON2.3
#BIT ACKEN = SSPCON2.4
#BIT ACKDT = SSPCON2.5
#BIT ACKSTAT = SSPCON2.6
#BIT GCEN = SSPCON2.7
#BYTE PIR1 = 0x0c
#BIT TMR1IF = PIR1.0
#BIT TMR2IF = PIR1.1
#BIT CCP1IF = PIR1.2
#BIT SSPIF = PIR1.3
#BIT TXIF = PIR1.4
#BIT RCIF = PIR1.5
#BIT ADIF = PIR1.6
#BIT PSPIF = PIR1.7
#BYTE SSPBUF = 0x13
#BYTE SSPADD = 0x93
void WaitMSSP(void){
while(!SSPIF); // Wait to complete
SSPIF = 0;
}
void twi_init(void){
SSPCON0 = ((1 << SSPEN) | (1 << SSPM3)); // Synchronous Serial Port Enable bit, Master mode
SSPSTAT = (1 << SMP); // Standard speed mode (100 kHz and 1 MHz)
SSPADD = 0x12; // clock = 100Khz
}
void twi_start(void){
SEN = 1; // Send START condition
WaitMSSP();
}
void twi_stop(void){
PEN = 1; //Send STOP condition
WaitMSSP();
}
void twi_write(int8 tData){
SSPBUF = tData; // Send Data
WaitMSSP();
}
int8 twi_read(int8 ack){
RCEN = 1; // Receive Mode
WaitMSSP();
if (ack != 0){
ACKDT = 0;
ACKEN = 1;
WaitMSSP();
}else{
ACKDT = 1;
ACKEN = 1;
WaitMSSP();
}
return SSPBUF;
}
#endif |
|
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Feb 26, 2013 11:23 pm |
|
|
Hi,
What is your compiler version?
John |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Wed Feb 27, 2013 12:53 am |
|
|
Er...
What on earth are you trying to do with the instructions like:
SSPCON0 = ((1 << SSPEN) | (1 << SSPM3));
I think you misunderstand how bit variables work in CCS. They are not a reference to the bit 'in' a byte, but a direct reference to a single bit variable. As such SSPEN, will be just 0 or 1, according to what the value in the hardware is at this point. The same with SSPM3. To enable the SSP, just requires:
SSPEN=TRUE;
As such, the port won't be setup as you expect.....
Best Wishes |
|
|
tn88test
Joined: 26 Feb 2013 Posts: 3
|
|
Posted: Wed Feb 27, 2013 2:12 am |
|
|
I used PCWHD version 4.104
I have change my code as you suggested. I can see the SEN, PEN bits are cleared by hardware, but SSPIF is not set to 1. My program still stuck at while(!SSPIF);
Code: | void WaitMSSP(void){
while(!SSPIF); // Wait to complete
SSPIF = 0;
} |
Here is my new code
Code: | #ifndef _TWI_INCLUDED_
#define _TWI_INCLUDED_
#BYTE SSPSTAT = 0x094
#BIT BF = SSPSTAT.0
#BIT UA = SSPSTAT.1
#BIT R_W = SSPSTAT.2
#BIT CKE = SSPSTAT.6
#BIT SMP = SSPSTAT.7
#BYTE SSPCON0 = 0x014
#BIT SSPM0 = SSPCON0.0
#BIT SSPM1 = SSPCON0.1
#BIT SSPM2 = SSPCON0.2
#BIT SSPM3 = SSPCON0.3
#BIT CKP = SSPCON0.4
#BIT SSPEN = SSPCON0.5
#BIT SSPOV = SSPCON0.6
#BIT WCOL = SSPCON0.7
#BYTE SSPCON2 = 0x091
#BIT SEN = SSPCON2.0
#BIT RSEN = SSPCON2.1
#BIT PEN = SSPCON2.2
#BIT RCEN = SSPCON2.3
#BIT ACKEN = SSPCON2.4
#BIT ACKDT = SSPCON2.5
#BIT ACKSTAT = SSPCON2.6
#BIT GCEN = SSPCON2.7
#BYTE PIR1 = 0x0c
#BIT TMR1IF = PIR1.0
#BIT TMR2IF = PIR1.1
#BIT CCP1IF = PIR1.2
#BIT SSPIF = PIR1.3
#BIT TXIF = PIR1.4
#BIT RCIF = PIR1.5
#BIT ADIF = PIR1.6
#BIT PSPIF = PIR1.7
#BYTE SSPBUF = 0x13
#BYTE SSPADD = 0x93
void WaitMSSP(void){
while(!SSPIF); // Wait to complete
SSPIF = 0;
}
void twi_init(void){
SSPEN = 1; // Synchronous Serial Port Enable bit,
SSPM3 = 1; // Master mode
SMP = 1; // Standard speed mode (100 kHz and 1 MHz)
SSPADD = 0x12; // clock = 100KHz
}
void twi_start(void){
SEN = 1; // Send START condition
WaitMSSP();
}
void twi_stop(void){
PEN = 1; //Send STOP condition
WaitMSSP();
}
void twi_write(int8 tData){
SSPBUF = tData; // Send Data
WaitMSSP();
}
int8 twi_read(int8 ack){
RCEN = 1; // Receive Mode
WaitMSSP();
if (ack != 0){
ACKDT = 0;
ACKEN = 1;
WaitMSSP();
}else{
ACKDT = 1;
ACKEN = 1;
WaitMSSP();
}
return SSPBUF;
}
#endif |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 27, 2013 9:23 pm |
|
|
Why are you doing this ? CCS has built-in hardware i2c routines, which
can be enabled with this statement:
Code: |
#use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
|
Then use the i2c routines listed in the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Also look at examples of how to use the CCS i2c routines with i2c chips
such as eeproms. The driver files are in this directory:
c:\program files\picc\drivers
Example of eeprom driver file:
24256.c
Make sure you have a 4.7K pull-up resistor on each i2c bus line, sda and scl. |
|
|
tn88test
Joined: 26 Feb 2013 Posts: 3
|
|
Posted: Wed Feb 27, 2013 10:11 pm |
|
|
PCM programmer wrote: | Why are you doing this ? CCS has built-in hardware i2c routines, which
can be enabled with this statement:
Code: |
#use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
|
Then use the i2c routines listed in the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Also look at examples of how to use the CCS i2c routines with i2c chips
such as eeproms. The driver files are in this directory:
c:\program files\picc\drivers
Example of eeprom driver file:
24256.c
Make sure you have a 4.7K pull-up resistor on each i2c bus line, sda and scl. |
Thanks! The CCS hardware i2c worked perfectly. |
|
|
|