Help with MC9S12DT256 IIC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help with MC9S12DT256 IIC

767 Views
simon375
Contributor I

I am using a MC9S12DT256 microprocessor. I need to communicate with a chip using IIC. The code that I have I believe was written by looking at online samples. It seems very simmilar to others I have seen online. Once the "EnableInterupts" command has ben run, the IIC function crashes the program. Using Codewarrior, in the True Time Simulator & Debugger, when it crashes, no code is highlighted in the "Source" window and if single stepped, it runs Assembly code line by line in the "Assembly" window. If I remove "EnableInterupts" from the program, it runs without crashing. I have verified with an oscilloscope that the correct waveform is being transmitted over the IIC but the instructions are still not getting through. Does anyone know why “EnableInterupts” which is in Codewarrior by default, is crashing my program? Below is my code for the IIC function.

 

void IIC_writeByte(unsigned char device__address, unsigned char registeraddress, unsigned char data)

{   

    int temp;

    IBCR_MS_SL=1;        //Generate start signal

    IBCR_TX_RX=1;           

    temp=device__address<<1;

    IBDR=temp;           //Device address shifted left one position & LSB=0

    while(!IBSR_IBIF);   //Wait untill IBIF is HIGH

    IBSR_IBIF=1;         //Clear interrupt event flag

    //while(IBSR_RXAK);  //Check for acknowledge from device

    IBDR=registeraddress;

    while(!IBSR_IBIF);   //Wait untill IBIF is HIGH

    IBSR_IBIF=1;         //Clear interrupt event flag

    //while(IBSR_RXAK);  //Check for acknowledge from device

    IBDR=data;             

    while(!IBSR_IBIF);   //Wait untill IBIF is HIGH

    IBSR_IBIF=1;         //Clear interrupt event flag

    //while(IBSR_RXAK);  //Check for acknowledge from device

    IBCR_MS_SL=0;        //Generate stop signal

    delay_50us(1);

}

Labels (1)
Tags (2)
0 Kudos
Reply
1 Reply

504 Views
Lundin
Senior Contributor IV

"EnableInterrupts" is merely a macro equal to the assembler instruction CLI, which clears the global interrupt mask (the i bit in the CCR) and allows interrupts to occur in the MCU.

If you get a crash when that instruction is called, it is most likely because a hardware interrupt occurred, which has no corresponding interrupt service routine (isr) mapped into the interrupt vector table. The MCU will then execute whatever it finds there, and most likely jump into an invalid address. For every interrupt you use, you need to ensure that there is an interrupt vector containing the address of the specific isr. The interrupt vector table can be altered in several ways: either you can add a line in the .prm file, or you can declare the whole vector table as an array of function pointers, allocated at the correct address (0xFF** something).

Note: an interrupt service routine cannot be placed in banked memory! You must place all such routines in one of the non-banked 16kb areas, starting from either 0x4000 or from 0xC000. The PPAGE register which selects memory banks is ignored when an isr is called, it only uses a 16 bit address. So if you place your isr at lets say address 0x308000, the MCU will call the code at address 0x8000, ignoring the page 30 part of the address. This will likely cause the same kind of crash as when you have no isr mapped at all.