1

I am using MPLAB XC8 to program pic18f45k22 to read data from 2 thermocouples. The code showed 2 problems, The first is that during simulation, the data from the sensor is shifted (sent to the second address) for Example: if I have 2 addresses 0x0D and 0x0F, and 2 values 100 and 95, and 100 should got to 0x0D and 95 to 0x0F. However 100 goes to 0x0F and 95 to 0x0D. **The second ** appears after uploading the code to the MCU, and it is that the MCU cannot Read any data from the sensors. this is the main code:

 void main(void) { 


 //SPI configuration 

  spiInit(); 

  ANSELB = 0x00; //PORTB bits as digital 

  TRISB3 = 0; //GPIO as CS output

  TRISB4 = 0;

  TRISB5 = 0;

  LATBbits.LATB3 = 1;

  LATBbits.LATB4 = 1;

  LATBbits.LATB5 = 1;

  timer1init();  //initiate timer1

  uartinit(9600); //initiate UART

  __delay_ms(100);

  while(1){

   switch (cnt){ //timer interrupt routine every 1 second
     //thermocouple code
       case 50:
    LATB3 = 0; //turn on CS
    thercoup1 = spiRead(0)<<8; //Read first byte
    thercoup1 |= spiRead(0); //add second byte with first one
    LATB3 = 1; //turn off CS1
    thercoup1 = (thercoup1>>4);
     //thercoup1 = (thercoup1>>3)*0.25; //another method for calculating thermocouple value
    
    LATB4 = 0; //turn on CS1
    thercoup2 = spiRead(0)<<8; //Read first byte
    thercoup2 |= spiRead(0); //add second byte with first one
    LATB4 = 1; //turn off CS1
    thercoup2 = (thercoup2>>4); //right shift of the reading
   
  HMT_WriteVPN16(0x08000C, thercoup1); //send thermocouple1 data to 0x08000C
  HMT_WriteVPN16(0x08000E, thercoup2); //send thermocouple2 data to 0x08000E
    cnt = 0; //reset timer
    break; 
  }  
    
   }
     }

void __interrupt() ISR (void){
timer();
UART_Read();
}

And This is the configuration code of SPI module.

 void spiInit(void)
  {
  ANSELC = 0x00;
  SSP1STATbits.SMP = 0;  //input Data is sampled at the middle
  SSP1STATbits.CKE = 0;  //Transmission occurs from Idle to Active
//Master mode Fosc/4
SSP1CON1bits.SSPM0 = 0;
SSP1CON1bits.SSPM1 = 0;
SSP1CON1bits.SSPM2 = 0;
SSP1CON1bits.SSPM3 = 0;
//
SSP1CON1bits.CKP = 1; //clock polarity is high
SSP1CON1bits.SSPEN = 1;//Serial communication is Enabled
SSP1CON1bits.SSPOV = 0;//Overflow is off
SSP1CON1bits.WCOL = 0;//Write collision is off
TRISCbits.RC5 = 1; //SDO is Disabled
TRISCbits.RC4 = 1; //SDI is Enabled
TRISCbits.RC3 = 0; //SCK is Enabled

}

unsigned short spiRead(unsigned char dat) //REad the received data
{
SSPBUF= dat; //the data loaded on the SSPBUF are not important.
while(!SSPSTATbits.BF); //save the received data from the slave.
return(SSPBUF);
} 
  • 1
    There is not quite enough information for me to work out your first problem. I don't see addresses 0x0D and 0x0F anywhere in the code. Is it related to the `HMT_WriteVPN16()` function? What does that do? For your second problem, I am rather rusty on PIC18 stuff, but could you try modifying your `spiInit()` function? Set `SSP1CON1bits.SSPEN` to zero at the start, then set the `SSP1STATbits` and the other `SSP1CON1bits`, and then last of all, set `SSP1CON1bits.SSPEN` to one. – DavidHoadley Sep 29 '20 at 04:26
  • And indent your code, so anybody else could read it. – Mike Sep 29 '20 at 04:33
  • HMT_WriteVPN16 is just a uart code to be able to send the address byte by byte. the addresses sent are like that in the code(the first part) HMT_WriteVPN16(0x08000C, thercoup1), but I made a simple example for undersranding as I could not upload a photo. – Ayman hussien Sep 29 '20 at 09:29
  • When you say that your code cannot read any data from the sensors, do you mean that reads do not seem to take place, or that reads return zero (or some other nonsense value)? If it is the first, I would be looking at variable `cnt`, which is not being incremented anywhere. (If `cnt` _is_ being incremented, then you have not shown us all the relevant code.) – DavidHoadley Sep 30 '20 at 06:35
  • cnt is just a counter in a timer code, ant it counts according to the ISR shown in the code above. I just did not show it because it is not in the core of the problem. – Ayman hussien Sep 30 '20 at 09:13
  • Please, you still haven't shown all relevant information. If `cnt` is updated in an ISR, how have you declared this variable? Believe me, this information **really is** relevant. And my previous question - do the SPI reads take place, or not? – DavidHoadley Sep 30 '20 at 09:52
  • This is the code of the timer. unsigned int cnt; //count variable for timer1 void timer1init(void){ TMR1ON = 1; TMR1IE = 1; T1RD16 = 1; T1SYNC = 0; T1SOSCEN = 0; T1CKPS0 = 0; T1CKPS1 = 0; TMR1CS0 = 0; TMR1CS1 = 0; TMR1GE = 0; TMR1H = 0x3C; TMR1L = 0xB0; GIE = 1; PEIE = 1; } void timer(void){ if (TMR1IF){ cnt++; TMR1H = 0x3C; TMR1L = 0xB0; TMR1IF = 0; } } – Ayman hussien Sep 30 '20 at 13:36
  • And I have tested it before I start SPI interfacing. I am used to configure each module alone and after I confirm its working, I start merging them together to complete the code. – Ayman hussien Sep 30 '20 at 13:36
  • Try `volatile unsigned int cnt;`. After that, I am running out of ideas. – DavidHoadley Oct 01 '20 at 01:04
  • but why volatile? – Ayman hussien Oct 01 '20 at 01:34

0 Answers0