|
|
View previous topic :: View next topic |
Author |
Message |
longmenok
Joined: 23 Oct 2006 Posts: 12
|
What can't work of my 18F4431 in I2c |
Posted: Thu Mar 01, 2007 7:41 pm |
|
|
hello everyone, I have some question wish to solve in there.
I have getting 2 pics to communicate via I2C. master is 16F877A,slave is 18f4431.I've modified two examples and now have working code when master and slave are both 16F877A. When slave is 18f4431, the I2c can receive , but can't send, and have sspstat= 0X30 error, why?
Now it is can work. thanks all!
code is changed
I think 18F4431 register can't be setup correctly. But where wrong in my code? Can you help me?
This is pasted straight from my working programs.
Thanks to everyone. I am say sorry to everyone for my english.
slave code
Code: |
#include <18F4431.h>
#fuses HS,PROTECT,NOLVP,NOPUT,BROWNOUT
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(slave, sda=PIN_C4 , scl=PIN_C5,address=0xa0 , FORCE_HW, SLOW)
[b]//it is for 18f4431 I think the key of problem[/b]
[b]#byte SSPBUF = 0xFC9 // Buffer for SSP data
#byte SSPADD = 0xFC8 // Slave address held here
#byte SSPSTAT= 0xFC7 // SSP status reg
#byte SSPCON = 0xFC6 // SSP control reg 1 [/b]
// SSPSTAT bits
#bit BF = SSPSTAT.0
#bit UA = SSPSTAT.1
#bit R_W = SSPSTAT.2
#bit START=SSPSTAT.3
#bit STOP= SSPSTAT.4
#bit D_A = SSPSTAT.5
#bit CKE = SSPSTAT.6 .
#bit SMP = SSPSTAT.7
// SSPCON bits it is for 4431 Slave mode 7 bits
#bit SSPM0 = SSPCON.0 // SSP mode bits 0
#bit SSPM1 = SSPCON.1 // " 1
#bit SSPM2 = SSPCON.2 // " 1
#bit SSPM3 = SSPCON.3 // " 0
#bit CKP = SSPCON.4 // Clock, 1 = enable clock, 0 = clock stretch
#bit SSPEN = SSPCON.5 // SSP enable bit
#bit SSPOV = SSPCON.6
#bit WCOL = SSPCON.7
[b]#byte PIR1 = 0xF9E[/b]
#bit SSPIF = PIR1.3 // SSP interrupt flag bit
#define BUF_LEN 5
unsigned int8 buf[BUF_LEN];
int8 buf_index;
// Possible i2c states, SSPSTAT for the four relevant bits
#define STATE1 0x09
#define STATE2 0x29
#define STATE3 0x0C
#define STATE4 0x2C
#define STATE5 0x28
#define STATE6 0x30
#int_SSP
void SSP_isr()
{
while(SSPIF==1)
{
switch (SSPSTAT & 0x2d)
{
case(STATE1):
CKP = 0; // Hold SCL low
for (buf_index = 0; buf_index <BUF_LEN>= BUF_LEN) buf_index = 0; // Wrap around
CKP = 1; // Allow master to continue by re-enabling SCL
break;
case(STATE3):
CKP = 0; // Make Master wait by holding SCL low
buf_index = 0; // Reset buffer index
do
{
WCOL=0;
SSPBUF = buf[buf_index];// Load 1st byte from data buffer
}
while(WCOL);
buf_index++;
CKP = 1; // Enable SCL for Master to shift byte out
break;
case(STATE4):
CKP = 0; // Make Master wait by holding SCL low
do
{
WCOL=0;
SSPBUF = buf[buf_index];// Get next byte from data buffer
}
while(WCOL);
buf_index++;
if (buf_index >= BUF_LEN) buf_index = 0;
CKP = 1;
break;
case(STATE5):
SSPEN=0;
SSPEN=1;
break;
default:
// while(true);
break;
}
SSPIF = 0;
}
}
void main()
{
output_float(I2C_SDA);
output_float(I2C_SCL);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(TRUE)
{
while(!command);
switch(command) {
case 0x08: duty=data;
break;
// send QEI
case 0x09: trimite_QEI();
}
command = 0;
}
} |
master code
Code: |
#include <16F877A.h>
#fuses HS,NOWDT,PROTECT,NOLVP,NOPUT,BROWNOUT
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW, SLOW)
#define SLAVE_ADDR 0xa0
short int status=0;
void trimite_I2C(unsigned int8 comanda, unsigned int8 valoare1, unsigned int8 valoare2,
unsigned int8 valoare3, unsigned int8 valoare4);
void primeste_I2C();
void main()
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE)
{
trimite_i2c(9,0,0,0,0);
delay_ms(1000);
primeste_i2c();
}
}
void primeste_I2C()
{
unsigned int8 rxbuf[5]; // Buffer for data received back from the slave pic
int8 i=0;
for(i=0;i<5;i++)
rxbuf[i] = 0;
i2c_start(); // A restart
i2c_write(SLAVE_ADDR + 1); // Slave read address
for(i=0; i<4; i++)
{
rxbuf[i] = i2c_read();
}
rxbuf[4] = i2c_read(0);
i2c_stop();
printf(" \n\rread slave ");
for(i=0; i<=4; i++)
{
printf(" %u ",rxbuf[i]);
}
}
void trimite_I2C(unsigned int8 comanda, unsigned int8 valoare1, unsigned int8 valoare2,
unsigned int8 valoare3, unsigned int8 valoare4)
{
unsigned int8 rxbuf[5]; // Buffer for data received back from the slave pic
int8 i=0;
for(i=0;i<5>> 8;
rxbuf[3]=valoare3;
rxbuf[4]=valoare4;
i2c_start();
i2c_write(SLAVE_ADDR); // Must match address of slave pic
i2c_write(comanda); //Trimite comanda
i2c_write(valoare1);
i2c_write(valoare2);
i2c_write(valoare3);
i2c_write(valoare4);
i2c_stop();
} |
|
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 02, 2007 4:47 am |
|
|
It is also possibly worth adding, that you can #use I2C, _then_ do any programming changes you want to the register setups, and still use the internal functions like I2C_ISR_STATE. This is a 'trick' that is necessary on a few chips, where the settings generated by the default code, are not quite right.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|