This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1101: CC1101读取寄存器问题,只返回状态码,不返回数据

Part Number: CC1101
Other Parts Discussed in Thread: CC2530

我搜到类似的问题,但没人解决。里面有一个链接引用,也不能访问了。只能再问一次

我想用CC2530读取CC1101的0x31寄存器(VERSION),但是逻辑分析仪的结果如下图,只返回状态码0x0F,但是不返回数据(预期0x14)



下面是CC2530的最小源文件

#include <pinDefine.h>
#include <shortTypes.h>
#include <CC1101PinDefine.h>
#include <ioCC2530.h>
#include <helpTools.h>

#define MISO P1_7 //orange
#define MOSI P1_6 //red
#define SCK  P1_5 //yellow
#define CSn  P1_4 //brown

#define WR_OP_S(addr)    ( (addr & 0x3f) | 0x00 )      //  [7, 6] = 00
#define RD_OP_S(addr)    ( (addr & 0x3f) | 0x80 )      //  [7, 6] = 10


void SPI_init(void){
    //!UART1 use alt 2 position
    PERCFG  |=  0x02;
    P1SEL   |=  0xE0;   //MISO, MOSI, SCK set to peripheral function
    P1SEL   &=  ~0x10;  //CSn, general I/O
    P1DIR   |=  0x70;   //CSn, SCK, MOSI, set to output
    P1DIR   &=  ~0x80;   //MISO set to input

    //!SPI SCK freq, clk is 32MHz, here is 1.5MHz
    U1GCR   |=  15;
    U1BAUD  |=  128;

    //!SPI mode cfg
    U1GCR   &=  ~0xC0;  //!assure that CPOL/CPHA = 0
    U1CSR   &=  ~0xA0;  //!assuure that mode = 0, namely SPI mode
    U1GCR   |=  0x20;   //!MSB
}

//by SPI, send data to CC1101
uchar SPI_send(uchar data){
    U1DBUF = data;              //write to send buffer
    while(!(U1CSR & 0x01));     //wait for send(TX)
    U1CSR &= ~0x01;             //clear flag

    return U1DBUF;              //read receive, because SPI is full-duplex
}

uchar CC1101_ReadReg(uchar addr){
    uchar value = 0x44;

    CSn = 0;    Delay(1);
    SPI_send(RD_OP_S(addr));
    value = SPI_send(0x00);
    Delay(1);   CSn = 1;

    return value;
}

void CC1101_WriteReg(uchar addr, uchar data){
    CSn = 0;    Delay(1);       //lower CSn
    SPI_send(WR_OP_S(addr));    //write addr, here bit7 = 0 means write
    SPI_send(data);             //write data
    Delay(1);   CSn = 1;        //upper CSn
}

void CC1101_SendCommand(uchar cmd){
    CSn = 0;    Delay(1);
    SPI_send(cmd);
    Delay(1);   CSn = 1;
}

void CC1101_Init(void){
    //hardware reset
    CSn = 1;    Delay(10);
    CSn = 0;    Delay(100);
    CSn = 1;    Delay(100);

    //software reset
    CC1101_SendCommand(CC1101_SRES);
    Delay(200);
}

void CLK_init(void){
    CLKCONCMD&=~0x40;
    while(CLKCONSTA & 0x40);
    CLKCONCMD&=~0x47;
}

void LED_Init(){
    P1SEL &= ~0x03;
    P1DIR |=  0x03;
    LED1 = 1;   LED2 = 1;
}

void LED1_blink(){
    LED1 = 1;   Delay(100); LED1 = 0;
}

void light_LED2(){
   LED2 = 0;
}

int main(){
    LED_Init();
    SPI_init();
    CC1101_Init();
    light_LED2();   //init finish indicator

    while(1){
        Delay(1000);
        LED1_blink();   //working indicator
        CC1101_ReadReg(CC1101_VERSION);
    }
}

  • 您好,
    已经收到了您的案例,调查需要些时间,感谢您的耐心等待。

  • 问题已经解决了,关键是CC1101 DataSheet Section 10.2/Page 32,有一句很重要的话:

    "For register addresses in the range 0x30-0x3D, the burst bit is used to select between status registers when burst bit is one, and between command strobes when burst bit is zero."

    这句话太容易忽略了,应该加粗的。

    就具体解决,只需把CC1101_ReadReg中的SPI_send(RD_OP_S(addr));,改为SPI_send(RD_OP_B(addr));

    #define RD_OP_B(addr) ( (addr & 0x3f) | 0xc0 ) // [7, 6] = 11

    这份代码也挺短小精悍的,就留给新手入门吧