Sto avendo alcuni problemi nel gestire la comunicazione I2C tra questi due oggetti, con il PIC come master ed il CPT come slave. La comunicazione dovrebbe essere:
-Invio dell'address del CPT112
-Ricezione di 3 byte di dati
-Chiusura della comunicazione
L'inizio della comunicazione viene richiesta dal CPT settando un pin a livello logico basso. Ho scritto un programma e funziona ma ad una velocità di clock troppo bassa che non mi consente una corretta gestione del PWM delle luci ad esso collegate.
Il programma è il seguente
- Codice: Seleziona tutto
#include <xc.h>
#include <pic16f1823.h>
#include "set.h"
/*STRUCTURE*/
typedef struct MyStruct{
unsigned char Packet_Counter;
unsigned char Descriptor1;
unsigned char Descriptor2;
}CPT112_Data;
/*DEFINE*/
#define Slave_Address 0x09
__CONFIG (
FOSC_INTOSC // INTOSC oscillator: I/O function on CLKIN pin
& WDTE_OFF // WDT disabled
& PWRTE_OFF // PWRT disabled
& MCLRE_ON // MCLR/VPP pin function is MCLR
//& MCLRE_OFF // MCLR/VPP pin function is Input
& CP_OFF // Program memory code protection is disabled
& CPD_OFF // Data memory code protection is disabled
& BOREN_OFF // Brown-out Reset disabled
& CLKOUTEN_OFF // CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
& IESO_OFF // Internal/External Switchover mode is disabled
& FCMEN_OFF // Fail-Safe Clock Monitor is disabled
);
// Config Register: CONFIG2
__CONFIG (
WRT_OFF // Write protection off
//& PLLEN_OFF // 4x PLL disabled
& PLLEN_ON // 4x PLL enabled
& STVREN_ON // Stack Overflow or Underflow will cause a Reset
//& BORV_25 // Brown-out Reset Voltage (VBOR) set to 2.5 V
& LVP_OFF // High-voltage on MCLR/VPP must be used for programming
);
/*PROTOTYPES*/
void I2C_Conf();
void Start();
void Stop();
void Restart();
void ACK_S();
void NACK_S();
bit Write_byte(unsigned char bb);
unsigned char Read_byte(unsigned char ack);
void I2C_Wait();
CPT112_Data Read_CPT();
/*GLOAB VARIABLES*/
unsigned char END = 0;
void main(void) {
unsigned char i;
unsigned char PWM = 0;
unsigned char addr_send;
CPT112_Data Sensor;
/*set 32MHz osc*/
//OSCCON = 0xF0; //settato in questo modo non funziona
/*wait for pll*/
//while( !OSCSTATbits.PLLR );
I2C_Conf();
ANSELA = 0x00;
ANSELC = 0x00;
TRISCbits.TRISC2 = 1; //interrupt
TRISCbits.TRISC3 = 0; //PWM output
while(1){
for(i = 0; i < PWM; i++){
LATCbits.LATC3 = 1;
}
for(i = 0; i < (100-PWM); i++){
LATCbits.LATC3 = 0;
}
/*active low*/
if(!PORTCbits.RC2){
Sensor = Read_CPT();
}
}
}
void I2C_Conf(){
TRISC0=1; // set SCL and SDA pins as inputs 16LF1823
TRISC1=1;
SSPCON1 = 0b00101000; // I2C enabled, Master mode
SSPCON2 = 0x00;
SSPADD = 0x27; // 100Khz 32MHz
SSPSTAT = 0b10000000; // Slew rate disabled
}
void Start(){
//I2C_Wait();
SSP1CON2bits.SEN = 1;
while(SSP1CON2bits.SEN);
}
void Stop(){
//I2C_Wait();
SSP1CON2bits.PEN = 1;
while(SSPCON2bits.PEN);
}
void Restart(){
//I2C_Wait();
SSP1CON2bits.RSEN = 1;
while(SSPCON2bits.RSEN);
}
void ACK_S(){
SSPCON2bits.ACKDT = 0;
SSPCON2bits.ACKEN = 1;
//while(SSPCON2bits.ACKEN);
}
void NACK_S(){
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
//while(SSPCON2bits.ACKEN);
}
bit Write_byte(unsigned char bb){
SSPBUF = bb;
while(SSPSTATbits.BF);
//I2C_Wait();
return (~SSPCON2bits.ACKSTAT);
}
unsigned char Read_byte(unsigned char ack){
unsigned char temp;
//I2C_Wait();
RCEN = 1;
while(!SSP1STATbits.BF);
//I2C_Wait();
temp = SSPBUF;
SSP1STATbits.BF = 0;
//I2C_Wait();
SSP1CON2bits.ACKEN = 1;
while(SSP1CON2bits.ACKEN);
return temp;
}
void I2C_Wait(){
while (!END && (( SSPCON2 & 0x1F ) || ( SSPSTAT & 0x04 )));
}
CPT112_Data Read_CPT(){
unsigned char addr_send;
unsigned int counter;
CPT112_Data My_Read;
END = 0;
//T2CONbits.TMR2ON = 1;
addr_send = (Slave_Address << 1) | 1;
/*i2c seq*/
//Start();
//I2C_Wait();
Start();
SSP1BUF = addr_send;
while(SSPSTATbits.R_nW);
while(SSPCON2bits.ACKSTAT);
My_Read.Packet_Counter = Read_byte(1);
My_Read.Descriptor1 = Read_byte(1);
My_Read.Descriptor2 = Read_byte(1);
Stop();
//T2CONbits.TMR2ON = 0;
return(My_Read);
}
void Timer0_Init(){
CPSCON0bits.T0XCS = 0;
/*internal clock source*/
OPTION_REGbits.TMR0CS = 0;
/*L to H*/
OPTION_REGbits.TMR0SE = 0;
/*PSPA ON*/
OPTION_REGbits.PSA = 0;
/*256 psa*/
OPTION_REGbits.PS = 0b011;
}
void Timer2_Init(){
T2CONbits.TMR2ON = 0; //off
T2CONbits.T2OUTPS = 0x00;
T2CONbits.T2CKPS = 0b11;
PIE1bits.TMR2IE = 1;
PIR1bits.TMR2IF = 0;
}
La parte che setta i bit tramite il __CONFIG mi è stata fatta da un conoscente vario tempo fa e con QUELLA configurazione sembra funzionare. Ricevo i dati corretti. Impostando invece il clock a 32MHz non funziona nulla.
La frequenza che vorrei ottenere nella comunicazione è di 100KHz e da come viene segnato dal datasheet del PIC stesso ad una frequenza di 32MHz dovrei impostare il valore di SSPADD a 0x4F mentre a 16MHz (i 4MHz interni fatti dal mio conoscente) a 0x27.
Non riesco proprio a capire dove sbaglio, se qualcuno potesse darmi una mano sarebbe molto apprezzato. Grazie mille


Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)

