Helpful ReplyHot!SPI with PIC16F18345

Page: 12345.. > >> Showing page 1 of 6
Author
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
2018/01/23 00:37:58 (permalink)
0

SPI with PIC16F18345

I am newbie to PIC. I have been working on PIC16F18345. I tried to configure the ADXL345 with pic but i failed to get the output i will share my code please help me where i am doing the mistake. I studied all the registers and configured bit by bit.
/**
Generated Main Source File
Company:
Microchip Technology Inc.
File Name:
main.c
Summary:
This is the main file generated using MPLAB(c) Code Configurator
Description:
This header file provides implementations for driver APIs for all modules selected in the GUI.
Generation Information :
Product Revision : MPLAB(c) Code Configurator - 4.0
Device : PIC16F18345
Driver Version : 2.00
The generated drivers are tested against the following:
Compiler : XC8 1.35
MPLAB : MPLAB X 3.40
*/
/*
(c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
software and any derivatives exclusively with Microchip products.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
TERMS.
*/
#include "mcc_generated_files/mcc.h"
/*
Main application
*/
#define ss PORTCbits.RC6
void ADC_init(void);
void SPI_init(void);
unsigned char spi_read(void);
void main(void)
{

SYSTEM_Initialize();
 

printf("Serial started \n");
SPI_init();
while (1)
{

printf("spi read\n\r");
printf("%c\n\r" , spi_read());
}
}
void SPI_init()
{


/********SSPxSTAT*******/
//SSP1STATbits.BF = 0; // BUFFER STATUS BIT
SSP1STATbits.CKE = 1; // CLOCK FROM ACTIVE TO IDLE
//SSP1STATbits.D_nA =
// SSP1STATbits.P =
// SSP1STATbits.R_nW =
//SSP1STATbits.S =
SSP1STATbits.SMP = 1; // SAMPLED AT THE END
// SSP1STATbits.UA =
/*********SSPxSTAT*******/

/*********SSPxCON1*******/
SSP1CON1bits.CKP = 1; // IDLE STATE FOR CLOCK IS A HIGH LEVEL
SSP1CON1bits.SSPEN = 0;
// SSP1CON1bits.SSPM =
SSP1CON1bits.SSPM0 = 0;
SSP1CON1bits.SSPM1 = 0;
SSP1CON1bits.SSPM2 = 0;
SSP1CON1bits.SSPM3 = 0; /// SPI MASTER MODE CLOCK = Fosc/4
SSP1CON1bits.SSPOV = 0;
// SSP1CON1bits.WCOL = 0; // NO COLLISION TRANSMIT MODE ONLY

/*********SSPxCON1*******/
// SSP1CON3bits.ACKTIM =
//SSP1CON3bits.AHEN =
// SSP1CON3bits.BOEN =
//SSP1CON3bits.DHEN =
//SSP1CON3bits.PCIE =
//SSP1CON3bits.SBCDE =
// SSP1CON3bits.SCIE =
//SSP1CON3bits.SDAHT =
/*********SSPxBUF*******/

/*********SSPxBUF*******/
/*********SSPxADD*******/

//SSP1ADD = 0X0C; // I2C MODE

/*********SSPxADD*******/
SSP1CON1bits.SSPEN = 1;
}
unsigned char spi_read()
{
unsigned char temp;
ss= 0;

PORTBbits.RB6 = 1;
while(!SSP1STATbits.BF)
printf("spi readING\n\r");
temp=SSPBUF;
PORTBbits.RB6 = 0;
ss = 1;
return temp;
}
/**
End of File
*/
PIC as SPI master
MPLAB XIde v4.05 xc8 compiler

'//'A'lone Employee'
#1
katela
Super Member
  • Total Posts : 956
  • Reward points : 0
  • Joined: 2013/06/11 05:25:18
  • Location: South Africa
  • Status: online
Re: SPI with PIC16F18345 2018/01/23 13:03:58 (permalink)
+2 (2)
What are you trying to achieve?
You seem to be mixing stuff here. Why not use MCC generated functions? Why reinitialize your peripherals in the main.C code while they are already in MCC generated files if configured correctly graphically with MCC?
What are you trying to read? The only thing you are sending is printf("..."); and this is sent to serial I presume. 

Free online Microcontroller Tutorials and Projects for Hobbyists and students. From beginners to advanced. Website: www.studentcompanion.co.za
YouTube Tutorials: https://www.youtube.com/user/StudentCompanionSA
#2
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2670
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 15:52:05 (permalink)
+1 (1)
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS"
Like mplab x.
 
read() is wrong.  You are waiting for the spi exchange to complete but you have not loaded the buffer.
Data must be in the Master and Slave buffers so that they can be exchanged.
 
You can put in a dummy value like 0xff.  Read and Write are very similar.
 
Load the buffer with dummy, check the status then read the buffer.
RD:
SPIxBUF=0xff;
while (!SPIxSTATbits.SPIRBF);
data=SPIxBUF;

WR:
SPIxBUF=data;
while (!SPIxSTATbits.SPIRBF);
SPIxBUF;

post edited by Gort2015 - 2018/01/23 15:58:00

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#3
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 15:59:26 (permalink)
+1 (1)
As Gort said, it is writing to SSPBUF that actually causes the SSP peripheral to do the exchange.
Try this:
unsigned char spi_read(void)
{
        ss= 0;    //assert SS pin
        LATBbits.LATB6 = 1;     //? is this extra debugging? Use LATB, not PORTB
        SSPBUF; //dummy read to ensure BF is low
        SSPBUF = 0;     //trigger an SPI exchange
        while(!SSP1STATbits.BF) //wait for the exchange to complete
        printf("spi readING\n\r");
        LATBbits.LATB6 = 0;     //?? debugging?
        ss = 1; //de-assert SS
        return SSPBUF;
}


This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#4
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 18:49:00 (permalink)
0
Forget about the printf. Here I configured adxl345 with my PIC using spi communication. I have been trying to get the data from ADXL345. i am not getting any data from adxl345. Is there any problem with my code?
#5
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 18:51:14 (permalink)
0
I will try and let you know
#6
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 21:06:18 (permalink)
0
when I put
SSPBUF;
SSPBUFI =0;

i am getting ' 229 ' continuously what does it mean. I am expecting values from adxl345

when I put
SSPBUF;
SSPBUFI =0xFF;

I am getting 0 continuously.
I am very confused. Is there any wrong with the clock or oscillator.
post edited by ram1723 - 2018/01/23 21:22:46
#7
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 21:17:33 (permalink)
+1 (1)
Actually, that means your chip is working!
You are reading from register 0x00, which is the "ID" register, which contains 0b11100101 = 0xE5 = 229
 
Have you actually read the ADXL345 datasheet, and how to access its registers?
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#8
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 21:38:24 (permalink)
0
Clearing the
SPI bit (Bit D6) in the DATA_FORMAT register (Address 0x31)
selects 4-wire mode, whereas setting the SPI bit selects 3-wire
mode. The maximum SPI clock speed is 5 MHz with 100 pF
maximum loading, and the timing scheme follows clock polarity
(CPOL) = 1 and clock phase (CPHA) = 1
" This is from ADXL345 datasheet . How to access this "
#9
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 21:43:42 (permalink)
+1 (1)
You have skipped a couple of steps.
You have to start talking to the registers before you can do that.
Page 23 of the datasheet tells you that register 31 powers up containing 00000000, so that bit is clear, so it is already in 4-wire mode.
Have a look at "Figure 37. SPI 4-Wire Write" and "Figure 38. SPI 4-Wire Read" on page 16.
They indicate that you must send an address byte first, then do at least one more transfer (to read or write one byte) without pulling CS high until you are done.

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#10
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/23 21:49:06 (permalink)
0
n.b. I had not read the ADXL345 datasheet when I posted the code in post#4, I just cleaned up your code.
Always writing zero to SSPBUF, and only doing a single 8 bit transfer are both wrong for the ADXL345.
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#11
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 00:34:29 (permalink)
0
void main(void)
{
SPI_init();

SYSTEM_Initialize();
 
printf("Serial started \n");
spi_write();
while (1)
{
printf("%d\n\r" , spi_read());
__delay_ms(100);
}
}
unsigned int spi_read()
{

ss= 0;

///PORTBbits.RB6 = 1;

LATBbits.LATB6 = 1;


SSPBUF;
while(!SSP1STATbits.BF)
{
// printf("spi readING\n\r");
///__delay_ms(100);
// SSPxSR = 'C';
}
//while(!SSP1STATbits.BF);
temp=SSPBUF;
LATBbits.LATB6 = 0; // DEBUGGING
ss = 1;
return temp;
}
void spi_write()
{
unsigned char temp;
ss = 0;
SSPBUF = 0x31;
temp = spi_read();
}
still i am not getting any response
post edited by ram1723 - 2018/01/24 00:42:28
#12
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 00:47:02 (permalink)
+1 (1)
You still have not quite got the concept that
"every SPI transaction is triggered by a write to the SSPBUF register".
 
And "Every SPI transaction is a simultaneous read and write".
 
Even if you don't care about what is read or written, you must do both on EVERY transaction.
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#13
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 00:57:56 (permalink)
0
Thank you, I got your point. So you want me to call write and read fun simultaneously.
while (1)
{
printf("%d\n\r" , spi_read());
__delay_ms(100);
spi_write();

i changed into this way calling write fun after read. no change in the output
#14
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 02:10:44 (permalink)
+1 (1)
No, that's not it.
I'd do it something like this. Note I have discarded your printf() and toggling LATB6, assuming that is just debugging.
 
unsigned char spi_xfer(unsigned char datout)
{
    SSPBUF = datout;
    while(!SSP1STATbits.BF) //wait for the exchange to complete
    return SSPBUF
}
 
//call me to write one register
void write_reg(unsigned char reg, unsigned char dat)
{
    SSPBUF; //dummy read to ensure BF is low
    reg &= 0b00111111;  //ensure WR and MB are both low
    ss= 0;    //assert SS pin
    spi_xfer(reg);  //write register, discard received data
    spi_xfer(dat);    
    ss = 1; //release SS
}
 
//call me to read one register
unsigned char read_reg(unsigned char reg)
{
    unsigned char temp;
    SSPBUF; //dummy read to ensure BF is low
    reg |= 0b10000000;  //ensure RD/WR bit is high
    ss= 0;    //assert SS pin
    spi_xfer(reg);  //write register, discard received data
    temp = spi_xfer(0); //write dummy data, and save what we receive      
    ss = 1; //release SS
    return temp;
}




This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#15
andre
Starting Member
  • Total Posts : 82
  • Reward points : 0
  • Joined: 2009/03/23 02:48:42
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 05:07:28 (permalink)
0
just wondering qyb, does the line
SSPBUF; //dummy read to ensure BF is low

 
wait for a byte to be shifted in when no data was available?
 
I am in the process of trying to understand how SPI exactly works on a PIC32: I am not sure what exactly triggers a initiate an SPI transfer
 
Cheers
post edited by andre - 2018/01/24 05:09:23

-- breaking something that works is a lot easier than the other way around
-- using MPLAB 8.92 + Microstick II +  PIC32MX250F128B
#16
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 05:14:49 (permalink)
+1 (1)
andre
just wondering qyb, does the line
SSPBUF; //dummy read to ensure BF is low

 
wait for a byte to be shifted in when no data was available?

No.
All it does it read out of the SSPBUF register, which ensures the BF bit is clear.
No register read ever forces a wait (excluding the EEPROM access peripheral)
 

I am in the process of trying to understand how SPI exactly works on a PIC32: I am not sure what exactly triggers a initiate an SPI transfer

Note, PIC32 SPI is a bit more powerful than PIC16F/PIC18F. It has FIFO buffers, and separate flags for Receive Full and Transmit full (needed because of the FIFO)
The PIC32 Family Reference manual has a chapter dedicated to SPI.
 
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#17
andre
Starting Member
  • Total Posts : 82
  • Reward points : 0
  • Joined: 2009/03/23 02:48:42
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 06:44:31 (permalink)
0
-snip-
post edited by andre - 2018/01/24 07:52:27

-- breaking something that works is a lot easier than the other way around
-- using MPLAB 8.92 + Microstick II +  PIC32MX250F128B
#18
andre
Starting Member
  • Total Posts : 82
  • Reward points : 0
  • Joined: 2009/03/23 02:48:42
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 06:52:58 (permalink)
0
-snip-
 
post edited by andre - 2018/01/24 07:51:08

-- breaking something that works is a lot easier than the other way around
-- using MPLAB 8.92 + Microstick II +  PIC32MX250F128B
#19
ram1723
Starting Member
  • Total Posts : 60
  • Reward points : 0
  • Joined: 2018/01/16 22:27:23
  • Location: 0
  • Status: offline
Re: SPI with PIC16F18345 2018/01/24 07:36:56 (permalink)
0
void main(void)
{
unsigned char reg;
SPI_init();
SYSTEM_Initialize();
 
printf("Serial started \n");
while (1)
{
spi_write(reg , 0b00110001);
printf("%d\n\r" , spi_read(reg));
__delay_ms(100);
}
}
 
unsigned char spi_read(unsigned char reg)
{
unsigned char temp;
SSPBUF;
reg | = 0b10000000;
ss= 0;
LATBbits.LATB6 = 1;
spi_xhng(reg);
temp=spi_xhng(0);
LATBbits.LATB6 = 0; // DEBUGGING
ss = 1;
return temp;
}
void spi_write(unsigned char reg, unsigned char dat)
{
LATBbits.LATB6 = 1;
SSPBUF;
reg & = 0b00111111;
ss = 0;
spi_xhng(reg);
spi_xhng(dat);
ss =1; // dasserting
LATBbits.LATB6 = 0;
}
unsigned char spi_xhng(unsigned char datout)
{
SSPBUF = datout;
while(!SSP1STATbits.BF) //wait for the exchange to complete
return SSPBUF;
}
 
 
am i correct?
#20
Page: 12345.. > >> Showing page 1 of 6
Jump to:
© 2018 APG vNext Commercial Version 4.5