|
|
View previous topic :: View next topic |
Author |
Message |
respected
Joined: 16 May 2006 Posts: 95
|
CC1101 and PIC18F4520 |
Posted: Fri Mar 04, 2016 5:36 pm |
|
|
Hi Dear;
I used PIC18F4520 and CC1101 RF Transceiver.
I wrote this code but it wrong answered. Sometimes 15 decimal sometimes 47 decimal.
where is my mistake?
Thanks.
Code: |
#include <18F4520.h>
#FUSES HS,NOWDT,WDT128,NOBROWNOUT,NOPBADEN,NOLVP,NOXINST
#use delay(clock=20000000)
#use spi(Master, SPI1, Mode=0)
#include <string.h>
#include <math.h>
#include "LCD.C"
#define CSN_PIN PIN_A5
#define READ_SINGLE 0x80
///////////////////////////////////
#define CC1101_PARTNUM 0x30
#define CC1101_VERSION 0x31
#define CC1101_FREQEST 0x32
#define CC1101_LQI 0x33
#define CC1101_RSSI 0x34
#define CC1101_MARCSTATE 0x35
int8 CC1101ReadReg( int8 addr )
{
int8 value;
output_low(CSN_PIN);
while(spi_data_is_in());
spi_write(addr|READ_SINGLE);
value=spi_read(0);
output_high(CSN_PIN);
return value;
}
void main()
{
setup_spi(spi_master| spi_l_to_h | spi_clk_div_4);
lcd_init();
delay_ms(100);
lcd_gotoxy(1,1);
printf(lcd_putc,"RECEIVER");
delay_ms(500);
output_high(CSN_PIN);
while(TRUE)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"CODE:%03u",CC1101ReadReg(CC1101_PARTNUM ));
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 04, 2016 6:25 pm |
|
|
In this line, you use Mode 0 (which is correct), but you left off the BITS=8.
Quote: | #use spi(Master, SPI1, Mode=0) |
But then you use setup_spi() and set it for Mode 1. Why ?
Quote: | setup_spi(spi_master| spi_l_to_h | spi_clk_div_4); |
Here is part of the .LST file that shows the effect of using both the
lines above:
Quote: |
.................... void main()
*
02CC: CLRF TBLPTRU
02CE: BCF RCON.IPEN
02D0: BCF SSPCON1.SSPEN
This is the setup code from #use spi(). It sets up for SPI Mode 0:
02D2: MOVLW 40
02D4: MOVWF SSPSTAT
02D6: MOVLW 20
02D8: MOVWF SSPCON1
02DA: BCF TRISC.5
02DC: BSF TRISC.4
02DE: BCF TRISC.3
02E0: CLRF @sprintf_string+1
02E2: CLRF @sprintf_string
02E4: MOVF ADCON1,W
02E6: ANDLW C0
02E8: IORLW 0F
02EA: MOVWF ADCON1
02EC: MOVLW 07
02EE: MOVWF CMCON
.... {
.... setup_spi(spi_master| spi_l_to_h | spi_clk_div_4);
02F0: BCF SSPCON1.SSPEN
02F2: BCF TRISC.5
02F4: BSF TRISC.4
02F6: BCF TRISC.3
// This is the Mode setup code for setup_spi(). It occurs after the
// #use spi() code and it overwrites the registers with Mode 1.
02F8: MOVLW 20
02FA: MOVWF SSPCON1
02FC: MOVLW 00
02FE: MOVWF SSPSTAT |
Also, you should only use one method for SPI setup.
1. #use spi() -- use spi_xfer() to transfer bytes.
or
2. setup_spi() -- use spi_write() and spi_read() to transfer bytes. |
|
|
respected
Joined: 16 May 2006 Posts: 95
|
|
Posted: Sat Mar 05, 2016 3:47 am |
|
|
Quote: | Also, you should only use one method for SPI setup.
1. #use spi() -- use spi_xfer() to transfer bytes.
or
2. setup_spi() -- use spi_write() and spi_read() to transfer bytes. |
is not OK.
But this is Ok.
Code: |
#include <18F4520.h>
#FUSES HS,NOWDT,WDT128,NOBROWNOUT,NOPBADEN,NOLVP,NOXINST
#use delay(clock=20000000)
#use spi(Master, stream=SPI1, Mode=0)
#include <string.h>
#include <math.h>
#include "LCD.C"
#define CSN_PIN PIN_A5
#define READ_SINGLE 0x80
///////////////////////////////////
#define CC1101_PARTNUM 0x30
#define CC1101_VERSION 0x31
#define CC1101_FREQEST 0x32
#define CC1101_LQI 0x33
#define CC1101_RSSI 0x34
#define CC1101_MARCSTATE 0x35
int8 CC1101ReadReg( int8 addr )
{
int8 value;
output_low(CSN_PIN);
while(spi_data_is_in());
spi_write(addr|READ_SINGLE);
value=spi_read(0);
output_high(CSN_PIN);
return value;
}
void main()
{
lcd_init();
delay_ms(100);
lcd_gotoxy(1,1);
printf(lcd_putc,"RECEIVER");
delay_ms(500);
output_high(CSN_PIN);
while(TRUE)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"CODE:%03X",CC1101ReadReg(CC1101_PARTNUM));
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sat Mar 05, 2016 4:05 am |
|
|
What you have 'works by accident'. It is _wrong_.
If you read the manual, you will find that 'setup_spi', refers you to spi_read, and spi_write. This was the 'old' CCS way of configuring the SPI, and using the SPI, which only offered hardware SPI.
Then if you read the #USE SPI entry, you will find it only refers you to spi_xfer.
You are not meant to use 'half and half'.
The correct way is:
Code: |
#include <18F4520.h>
#FUSES HS,NOWDT,WDT128,NOBROWNOUT,NOPBADEN,NOLVP,NOXINST
#use delay(clock=20000000)
#use spi(SPI1, MASTER, MODE=0, BITS=8)
#include <string.h>
#include <math.h>
#include "LCD.C"
#define CSN_PIN PIN_A5
#define READ_SINGLE 0x80
///////////////////////////////////
#define CC1101_PARTNUM 0x30
#define CC1101_VERSION 0x31
#define CC1101_FREQEST 0x32
#define CC1101_LQI 0x33
#define CC1101_RSSI 0x34
#define CC1101_MARCSTATE 0x35
int8 CC1101ReadReg( int8 addr )
{
int8 value;
output_low(CSN_PIN);
spi_xfer(addr|READ_SINGLE);
value=spi_xfer(0);
output_high(CSN_PIN);
return value;
}
void main()
{
output_high(CSN_PIN); //ensure the pin is high before starting
//might as well be done much earlier
lcd_init();
delay_ms(100);
lcd_gotoxy(1,1);
printf(lcd_putc,"RECEIVER");
delay_ms(500);
while(TRUE)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"CODE:%03X",CC1101ReadReg(CC1101_PARTNUM));
}
}
|
What you are doing, works because the #USE sets up the hardware, which is then available for the old read and write. It'll 'go wrong', if you try to use more than one port or do anything more complex, because it will then not be accessing the part correctly. You'd normally also want to specify a baud rate, but the chip you are using supports up to 6MHz, which is higher than the SPI can generate with your clock.
Your call to spi_data_is_in, will result in the code hanging forever, if anything has already been received (it should not have, at this point). |
|
|
respected
Joined: 16 May 2006 Posts: 95
|
|
Posted: Sat Mar 05, 2016 6:04 am |
|
|
Thanks. Code is ok. But i didn't understand what does it mean?
spi_xfer(0); why we use 0(zero); |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sat Mar 05, 2016 9:01 am |
|
|
Same reason you were using 0....
Just clocking out a dummy byte.
On SPI, the master clocks everything. You send a control byte to select the register (and ignore what is returned), then send a dummy byte (can be anything), and read what comes back. |
|
|
respected
Joined: 16 May 2006 Posts: 95
|
|
Posted: Sat Mar 05, 2016 4:32 pm |
|
|
Thanks. I understood. I used for clock. in fact spi_read and spi_xfer are same command is it true?
OK. thanks for your helping. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|