2017-10-22 25 views
0

불편을 끼쳐 드려서 죄송하지만 시간이 많이 흘렀습니다. I2C1 포트에서 아무 것도 얻을 수 없습니다! 나는 틀린 일을해야 할 것 같아요. 아니면 컨피규레이션 비트에서 뭔가 바꾸기를 깜박했는데, 그걸 알아낼 수 없어요. ...PIC32MX270F256B와 작동하도록 I2C를 가져올 수 없습니다.

코드의 목적은 실시간 클럭을 읽는 것입니다 (PCF8583)이 I2C에 연결되어 있습니다. 나는 8 비트 PIC18F45K50을위한 라이브러리를 썼다. 그리고 그것은 잘 동작한다. 그리고 이제 그것을 PIC32MX로 옮기고 싶다. 이것이 PIC32에 관한 저의 첫 프로젝트입니다.

#pragma config PMDL1WAY = ON // Peripheral Module Disable Configuration->Allow only one reconfiguration 
#pragma config IOL1WAY = ON // Peripheral Pin Select Configuration->Allow only one reconfiguration 
#pragma config FUSBIDIO = ON // USB USID Selection->Controlled by the USB Module 
#pragma config FVBUSONIO = ON // USB VBUS ON Selection->Controlled by USB Module 

// DEVCFG2 
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider->2x Divider 
#pragma config FPLLMUL = MUL_20 // PLL Multiplier->20x Multiplier 
#pragma config UPLLIDIV = DIV_12 // USB PLL Input Divider->12x Divider 
#pragma config UPLLEN = OFF // USB PLL Enable->Disabled and Bypassed 
#pragma config FPLLODIV = DIV_2 // System PLL Output Clock Divider->PLL Divide by 2 

// DEVCFG1 
#pragma config FNOSC = FRCPLL // Oscillator Selection Bits->Fast RC Osc with PLL 
#pragma config FSOSCEN = ON // Secondary Oscillator Enable->Enabled 
#pragma config IESO = ON // Internal/External Switch Over->Enabled 
#pragma config POSCMOD = OFF // Primary Oscillator Configuration->Primary osc disabled 
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin->Disabled 
#pragma config FPBDIV = DIV_4 // Peripheral Clock Divisor->Pb_Clk is Sys_Clk/4 
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection->Clock Switch Disable, FSCM Disabled 
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler->1:1048576 
#pragma config WINDIS = OFF // Watchdog Timer Window Enable->Watchdog Timer is in Non-Window Mode 
#pragma config FWDTEN = OFF // Watchdog Timer Enable->WDT Disabled (SWDTEN Bit Controls) 
#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size->Window Size is 25% 

// DEVCFG0 
#pragma config DEBUG = OFF // Background Debugger Enable->Debugger is Disabled 
#pragma config JTAGEN = ON // JTAG Enable->JTAG Port Enabled 
#pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select->Communicate on PGEC1/PGED1 
#pragma config PWP = OFF // Program Flash Write Protect->Disable 
#pragma config BWP = OFF // Boot Flash Write Protect bit->Protection Disabled 
#pragma config CP = OFF // Code Protect->Protection Disabled 

#include "mcc.h" 

/** 
    @Summary 
    Indicates the exception cause. 

    @Description 
    This array identifies the cause for exception. 
*/ 

static char *cause[] = 
{ 
    "Interrupt", "Undefined", "Undefined", "Undefined", 
    "Load/fetch address error", "Store address error", 
    "Instruction bus error", "Data bus error", "Syscall", 
    "Breakpoint", "Reserved instruction", "Coprocessor unusable", 
    "Arithmetic overflow", "Trap", "Reserved", "Reserved", 
    "Reserved", "Reserved", "Reserved" 
}; 

void SYSTEM_Initialize(void) 
{ 
    PIN_MANAGER_Initialize(); 
    OSCILLATOR_Initialize(); 
    SPI1_Initialize(); 
    I2C1_Initialize(); 
    INTERRUPT_Initialize(); 

} 

void SYSTEM_RegUnlock(void) 
{ 
    SYSKEY = 0x12345678; 
    SYSKEY = 0xAA996655; 
    SYSKEY = 0x556699AA; 
} 

void SYSTEM_RegLock(void) 
{ 
    SYSKEY = 0x00000000; 
} 

void OSCILLATOR_Initialize(void) 
{ 
    SYSTEM_RegUnlock(); 
    // CF no clock failure; COSC FRCPLL; PLLODIV DIV_2; PBDIVRDY disabled; SLOCK out of lock; FRCDIV FRC/256; SLPEN Idle on WAIT instruction; NOSC FRCPLL; PLLMULT MUL_20; SOSCEN disabled; PBDIV DIV_4; CLKLOCK unlocked; OSWEN Switch is Complete; SOSCRDY disabled; 
    OSCCON = 0xF151100; 
    SYSTEM_RegLock(); 
    // TUN Center Frequency; 
    OSCTUN = 0x0; 
    // DIVSWEN disabled; RSLP disabled; ACTIVE Active; ROSEL SYSCLK; OE Not Driven out on REFCLKO pin; SIDL disabled; RODIV 0; ON disabled; 
    REFOCON = 0x100; 
    // ROTRIM 0; 
    REFOTRIM = 0x0; 
} 

void _general_exception_handler() 
{ 
    /* Mask off the ExcCode Field from the Cause Register 
    Refer to the MIPs Software User's manual */ 
    uint8_t _excep_code; 
    uint8_t _excep_addr; 
    uint8_t *_cause_str; 
    _excep_code = (_CP0_GET_CAUSE() & 0x0000007C) >> 2; 
    _excep_addr = _CP0_GET_EPC(); 
    _cause_str = cause[_excep_code]; 

    while(1) 
    { 
     ; 
    } 
} 

Main.c 파일은 여기 (간체) : 다음 PCF8583에 대한

#include "mcc_generated_files/mcc.h" 
#include <stdio.h> 
#include "Nokia5510.h" 
#include "PCF8583.h" 

int main(void) 
{ 
    // initialize the device 
    SYSTEM_Initialize(); 

    while (1) 
    { 
     // Read values from PCF8583 
     unsigned char buf; 
     MasterStart(); 
     MasterAddress(PCF8583_ADDRESS, 0); // WRITE 
     // Start writing at the PCF8583_100S_REG address 
     buf = PCF8583_100S_REG; 
     MasterWriteData(1, &buf); 
     MasterStart(); 
     MasterAddress(PCF8583_ADDRESS, 1); // READ 
     MasterReadData(size, data); 
     MasterStop(); 
    } 
} 

기능이 PCF8583.c 여기에 정의되어 있습니다

여기 (MCC 생성) 내 구성이다

#include "PCF8583.h" 

void myDelay() 
{ 
    int i; 
    for (i=0; i<1000; i++) 
    { 
     Nop(); 
    } 
} 

void extractWeekday(char _data, char* str) 
{ 
    // Extract the 3 MSBs 
    _data = _data>>5; 
    if(_data == SUNDAY) 
     sprintf(str, "Sunday"); 
    else if(_data == MONDAY) 
      sprintf(str, "Monday"); 
    else if(_data == TUESDAY) 
      sprintf(str, "Tuesday"); 
    else if(_data == WEDNESDAY) 
      sprintf(str, "Wednesday"); 
    else if(_data == THURSDAY) 
      sprintf(str, "Thursday"); 
    else if(_data == FRIDAY) 
      sprintf(str, "Friday"); 
    else if(_data == SATURDAY) 
      sprintf(str, "Saturday"); 
} 

void MasterStart() 
{ 
    I2C1CONbits.ON = 1; 
    // Generate a START condition by setting Start Enable bit 
    I2C1CONbits.SEN = 1; 
    // Wait for START to be completed 
    while(IFS1bits.I2C1MIF); 
    // Clear flag 
    IFS1bits.I2C1MIF = 0; 
} 

void MasterAddress(uint8_t _address, bool _RnW) 
{ 
    // Load the address + RW byte in SSP1BUF 
    // READ -> LSB=1 ; WRITE -> LSB=0 
    if (_RnW) 
     I2C1TRN = (_address<<1)+1; 
    else 
     I2C1TRN = _address<<1; 
    // Wait for ack 
    while (I2C1STATbits.ACKSTAT); 
    // Wait for MSSP interrupt 
    while (!IFS1bits.I2C1MIF); 
    // Clear flag 
    IFS1bits.I2C1MIF = 0; 
} 

void MasterWriteData(char _size, char* _data) 
{ 
    int i; 
    for (i=0; i<_size; i++) 
    { 
     // Load data in SSP1BUF 
     I2C1TRN = *(_data+i); 
     // Wait for ack 
     while (I2C1STATbits.ACKSTAT); 
     // Wait for MSSP interrupt 
     while (!IFS1bits.I2C1MIF); 
     // Clear flag 
     IFS1bits.I2C1MIF = 0; 
    } 
} 

void MasterReadData(char _size, char* _data) 
{ 
    int i; 
    for (i=0; i<size; i++) 
    { 
     // Enable reception 
     I2C1CONbits.RCEN = 1; 
     // Wait for MSSP interrupt flag and for the rx buffer to be full 
     while(!IFS1bits.I2C1MIF && !I2C1STATbits.RBF); 
     // Clear flag 
     IFS1bits.I2C1MIF = 0; 
     // Read the received byte 
     *(_data+i) = I2C1RCV; 
     // Clear BF to let MSSP know that we've read the buffer 
     I2C1STATbits.RBF = 0; 
     // Set ACK/NACK value to be sent slave 
     if (i != (size-1)) 
      I2C1CONbits.ACKDT = 0; // ACK 
     else 
      I2C1CONbits.ACKDT = 1; // NACK for the last byte 
     // Initiate the ACK/NACK 
     I2C1CONbits.ACKEN = 1; 
     // Wait for ACK/NACK to be completed -> INT 
     while(!IFS1bits.I2C1MIF);  
     // Clear flag 
     IFS1bits.I2C1MIF = 0;  
    } 
} 

void MasterStop() 
{ 
    // Generate a STOP condition 
    I2C1CONbits.PEN = 1; 
    // Wait for STOP to be completed 
    while(!IFS1bits.I2C1MIF); 
    // Clear flag 
    IFS1bits.I2C1MIF = 0; 
} 

void PCF8583_init(char* _data) 
{ 
    *(_data) = CURRENT_100s; 
    *(_data+1) = CURRENT_SEC; 
    *(_data+2) = CURRENT_MIN; 
    *(_data+3) = CURRENT_HOURS; 
    *(_data+4) = CURRENT_DATE | (((CURRENT_YEAR-2016)%4)<<6); 
    *(_data+5) = CURRENT_MONTH | (CURRENT_WEEKDAY<<5); 
    *(_data+6) = CURRENT_TIMER; 

    // Start the counter 
    unsigned char buf; 
    MasterStart(); 
    MasterAddress(PCF8583_ADDRESS, 0); // WRITE 
    // Register address in PCF8583 
    buf = PCF8583_CTRL_STATUS_REG; 
    MasterWriteData(1, &buf); 
    // Value PCF8583_START_COUNTING to make it start 
    buf = PCF8583_START_COUNTING; 
    MasterWriteData(1, &buf); 
    MasterStop(); 
    myDelay(); 

    // Set the date/month/time/... 
    MasterStart(); 
    MasterAddress(PCF8583_ADDRESS, 0); // WRITE 
    // Start writing at the PCF8583_100S_REG address 
    buf = PCF8583_100S_REG; 
    MasterWriteData(1, &buf); 
    // Shove the datas in it 
    MasterWriteData(size, _data); 
    MasterStop(); 
    myDelay(); 
} 

해당 헤더 PCF8583.h :

#include "PCF8583.h" 

void myDelay() 
{ 
    int i; 
    for (i=0; i<1000; i++) 
    { 
     Nop(); 
    } 
} 

void extractWeekday(char _data, char* str) 
{ 
    // Extract the 3 MSBs 
    _data = _data>>5; 
    if(_data == SUNDAY) 
     sprintf(str, "Sunday"); 
    else if(_data == MONDAY) 
      sprintf(str, "Monday"); 
    else if(_data == TUESDAY) 
      sprintf(str, "Tuesday"); 
    else if(_data == WEDNESDAY) 
      sprintf(str, "Wednesday"); 
    else if(_data == THURSDAY) 
      sprintf(str, "Thursday"); 
    else if(_data == FRIDAY) 
      sprintf(str, "Friday"); 
    else if(_data == SATURDAY) 
      sprintf(str, "Saturday"); 
} 

void MasterStart() 
{ 
    I2C1CONbits.ON = 1; 
    // Generate a START condition by setting Start Enable bit 
    I2C1CONbits.SEN = 1; 
    // Wait for START to be completed 
    while(IFS1bits.I2C1MIF); 
    // Clear flag 
    IFS1bits.I2C1MIF = 0; 
} 

void MasterAddress(uint8_t _address, bool _RnW) 
{ 
    // Load the address + RW byte in SSP1BUF 
    // READ -> LSB=1 ; WRITE -> LSB=0 
    if (_RnW) 
     I2C1TRN = (_address<<1)+1; 
    else 
     I2C1TRN = _address<<1; 
    // Wait for ack 
    while (I2C1STATbits.ACKSTAT); 
    // Wait for MSSP interrupt 
    while (!IFS1bits.I2C1MIF); 
    // Clear flag 
    IFS1bits.I2C1MIF = 0; 
} 

void MasterWriteData(char _size, char* _data) 
{ 
    int i; 
    for (i=0; i<_size; i++) 
    { 
     // Load data in SSP1BUF 
     I2C1TRN = *(_data+i); 
     // Wait for ack 
     while (I2C1STATbits.ACKSTAT); 
     // Wait for MSSP interrupt 
     while (!IFS1bits.I2C1MIF); 
     // Clear flag 
     IFS1bits.I2C1MIF = 0; 
    } 
} 

void MasterReadData(char _size, char* _data) 
{ 
    int i; 
    for (i=0; i<size; i++) 
    { 
     // Enable reception 
     I2C1CONbits.RCEN = 1; 
     // Wait for MSSP interrupt flag and for the rx buffer to be full 
     while(!IFS1bits.I2C1MIF && !I2C1STATbits.RBF); 
     // Clear flag 
     IFS1bits.I2C1MIF = 0; 
     // Read the received byte 
     *(_data+i) = I2C1RCV; 
     // Clear BF to let MSSP know that we've read the buffer 
     I2C1STATbits.RBF = 0; 
     // Set ACK/NACK value to be sent slave 
     if (i != (size-1)) 
      I2C1CONbits.ACKDT = 0; // ACK 
     else 
      I2C1CONbits.ACKDT = 1; // NACK for the last byte 
     // Initiate the ACK/NACK 
     I2C1CONbits.ACKEN = 1; 
     // Wait for ACK/NACK to be completed -> INT 
     while(!IFS1bits.I2C1MIF);  
     // Clear flag 
     IFS1bits.I2C1MIF = 0;  
    } 
} 

void MasterStop() 
{ 
    // Generate a STOP condition 
    I2C1CONbits.PEN = 1; 
    // Wait for STOP to be completed 
    while(!IFS1bits.I2C1MIF); 
    // Clear flag 
    IFS1bits.I2C1MIF = 0; 
} 

void PCF8583_init(char* _data) 
{ 
    *(_data) = CURRENT_100s; 
    *(_data+1) = CURRENT_SEC; 
    *(_data+2) = CURRENT_MIN; 
    *(_data+3) = CURRENT_HOURS; 
    *(_data+4) = CURRENT_DATE | (((CURRENT_YEAR-2016)%4)<<6); 
    *(_data+5) = CURRENT_MONTH | (CURRENT_WEEKDAY<<5); 
    *(_data+6) = CURRENT_TIMER; 

    // Start the counter 
    unsigned char buf; 
    MasterStart(); 
    MasterAddress(PCF8583_ADDRESS, 0); // WRITE 
    // Register address in PCF8583 
    buf = PCF8583_CTRL_STATUS_REG; 
    MasterWriteData(1, &buf); 
    // Value PCF8583_START_COUNTING to make it start 
    buf = PCF8583_START_COUNTING; 
    MasterWriteData(1, &buf); 
    MasterStop(); 
    myDelay(); 

    // Set the date/month/time/... 
    MasterStart(); 
    MasterAddress(PCF8583_ADDRESS, 0); // WRITE 
    // Start writing at the PCF8583_100S_REG address 
    buf = PCF8583_100S_REG; 
    MasterWriteData(1, &buf); 
    // Shove the datas in it 
    MasterWriteData(size, _data); 
    MasterStop(); 
    myDelay(); 
} 

결과 : SCL1/SDA1에서 아무 일도 일어나지 않습니다! 필자는 2k 풀업을 추가하고 로직 분석기로 모니터링했습니다. 로직 애널라이저를 시작한 다음 시작시 PIC가 수행중인 작업을 모니터링 할 수 있도록 회로를 시작합니다.

도움이나 단서가 있으면 감사하겠습니다.

고맙습니다!

감사합니다.

에릭

답변

1

당신이 구성 비트에서 JTAG이 이유가 있나요? 일반 PICKIT3 등을 사용하고 있다면 아마도 JTAG을 사용할 필요가 없을 것입니다. 또한, 정말 열심히 보이지 않았지만 ANALOG 핀 기능을 해제 했습니까? 이 두 가지 모두 디지털 IO를 작동시키지 않는 것입니다.

AD1PCFGbits.PCFG = 0xFFFF;

+0

안녕하세요, 답변 주셔서 대단히 감사합니다. JTAG가 실제로 문제였습니다! 이제 시작할 수 있습니다. 결과는 또 다른 질문으로 이어집니다. I2C의 각 단계 (START, STOP 또는 바이트 전송) 사이에 약간의 지연을 추가해야했습니다. START 및 STOP 만 보내지 않으면 SCL이 시작되지 않습니다. 마치 인터럽트 플래그 폴링이 작동하지 않는 것처럼 행동합니다. 깃발 자체가 예상대로 작동하지 않을 수 있습니까? 감사합니다. Eric – ricothebrol

+0

파트에 대한 데이터 시트를 살펴보고 여기에서 인터럽트를 사용하지는 않습니다. 귀하의 읽기/쓰기 방법이 올바른 순서가 아닌 것 같습니다. 다시 한 번 데이터 시트를보고 의심을 확인해 보겠습니다. – blsmit5728

+0

고맙습니다! 올바른 순서로 무엇을 의미합니까? WRITE는 나에게 꽤 직설적 인 것처럼 보일 것입니다. : WRITE BUF - WAIT ACK - IF - CLEAR IF ... IF (flag)가 설정되지 않으면 excepted가 될 수있는 것을 보지 못합니다. .. – ricothebrol