当我使用CC2640的SPI发送数据时,发现每发送一个字节,SPI的片选线就会出现一次上升沿。但是我传输的每一帧,都包含多个字节,这就导致SPI的片选线出现多个上升沿。如何配置SPI的片选线,使其能够在低电平时传输多个字节?
1、我的SPI的配置,CC2640配置为master模式。我的全部代码可从附件中下载。
(1)SPI的管脚配置
#define CC2640R2_LAUNCHXL_SPI0_MISOIOID_6/* RF1.20 */ #define CC2640R2_LAUNCHXL_SPI0_MOSIIOID_7/* RF1.18 */ #define CC2640R2_LAUNCHXL_SPI0_CLKIOID_10/* RF1.16 */ #define CC2640R2_LAUNCHXL_SPI0_CSNIOID_20 //PIN_UNASSIGNED const PIN_Config BoardGpioInitTable[] = {CC2640R2_LAUNCHXL_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low */CC2640R2_LAUNCHXL_PIN_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low *///CC2640R2_LAUNCHXL_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN, /* External flash chip select */CC2640R2_LAUNCHXL_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN,/* UART RX via debugger back channel *//*-----当不使用UART时,应该将UART TX拉低,避免漏电 -----*/CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,/*CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,*//* UART TX via debugger back channel */CC2640R2_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master out - slave in */CC2640R2_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master in - slave out */CC2640R2_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI clock */CC2640R2_LAUNCHXL_SPI0_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,/*-----这里的配置是多余的,在ccfg.c中配置bootloader back door就足够 -----*/ /*BOOTLOADER_BACKDOOR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH,*/PIN_TERMINATE };
(2)SPI的函数配置
SPI_Handle handle; SPI_Params params; uint8_t txBuffer[] = { 0x5A ,0x5A ,0xA5 ,0xA5 ,0x01 ,0xFF ,0x00 ,0x16 ,0x33 ,0x44 ,0x55 ,0x66 ,0x33 ,0x44 ,0x55 ,0x66 ,0x33 ,0x44 ,0x55 ,0x66 ,0x33 ,0x44 ,0x55 ,0x66 ,0x33 ,0x44 ,0x55 ,0x66 ,0x33 ,0x44 ,0x00 ,0xDB}; static void Spi_task_init(void) {SPI_init(); // Initialize the SPI driver// Init SPI and specify non-default parametersSPI_Params_init(¶ms);params.bitRate= 1000000;params.dataSize= 8;// 8-bit data sizeparams.frameFormat = SPI_POL0_PHA0;params.mode= SPI_MASTER;params.transferMode= SPI_MODE_BLOCKING;// Configure the transactiontransaction.count = sizeof(signature);transaction.txBuf = (void *)signature;transaction.rxBuf = NULL;// Open the SPI and perform the transferhandle = SPI_open(Board_SPI0, ¶ms); } uint8_t SPI_transfer_frame_write(SPI_Handle handle, SPI_Transaction *transaction,uint8_t *buffer, size_t size) {uint8_t uint8t_ret = 0;bool bool_ret = true;transaction->count = size;transaction->txBuf = buffer;transaction->rxBuf = NULL;bool_ret = SPI_transfer(handle, transaction);if(bool_ret == true){uint8t_ret = 1;}else{uint8t_ret = 0;}return uint8t_ret; } static void Spi_taskFxn(UArg a0, UArg a1) {Spi_task_init();SPI_transfer_frame_write(handle, &transaction,txBuffer, 32); }
2、我传输一帧数据的波形图,如图1所示。每一个字节对应一个上升沿。
图1
3、我想实现的波形图,如图2所示。每一帧数据对应一个上升沿。
图2
4、附件
(1)SPI MASTER的源代码可在这里下载:
source_code.rar
(3)simplelink_cc2640r2_sdk_1_40_00_45 可从如下路径下载:
(4)CC2640R2 launchpad 可从这里购买:
5、我的开发环境
CCS:Code Composer Studio 7.2.0
SDK:simplelink_cc2640r2_sdk_1_40_00_45
hardware:CC26640R2 launchpad develop kit
VS: Microsoft Visual C++ 2010 Express
系统:win7 64 位
heng fu:
回复 Barbara Wu:
非常感谢你的建议!但是按照你的建议,无法发送数据。请问还有没有别的办法?
1、根据你的建议做的代码的修改(1)更改IO口的配置
#define CC2640R2_LAUNCHXL_SPI0_MISOIOID_6/* RF1.20 */ #define CC2640R2_LAUNCHXL_SPI0_MOSIIOID_7/* RF1.18 */ #define CC2640R2_LAUNCHXL_SPI0_CLKIOID_10/* RF1.16 */ #define CC2640R2_LAUNCHXL_SPI0_CSNPIN_UNASSIGNED//IOID_20 #define CC2640R2_LAUNCHXL_SPI0_CSN_MANUALIOID_20(2)在spi_task.c中添加IO口的调用函数
#include <ti/drivers/PIN.h> #include <ti/drivers/pin/PINCC26XX.h>PIN_Handle hPins; PIN_Handle hButtons;PIN_Config SPI_CSN_PinTable[] = {CC2640R2_LAUNCHXL_SPI0_CSN_MANUAL | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,PIN_TERMINATE };static void Spi_task_init(void) {SPI_init();// Initialize the SPI driver// Init SPI and specify non-default parametersSPI_Params_init(¶ms);params.bitRate= 1000000;params.dataSize= 8;// 8-bit data sizeparams.frameFormat = SPI_POL0_PHA0;params.mode= SPI_MASTER;params.transferMode= SPI_MODE_BLOCKING;// Configure the transactiontransaction.count = sizeof(signature);transaction.txBuf = (void *)signature;transaction.rxBuf = NULL;transaction.arg= NULL;// Open the SPI and perform the transferhandle = SPI_open(Board_SPI0, ¶ms);interrupt_event_init();mcu_msg_fifo_init();PIN_init(SPI_CSN_PinTable);hPins = PIN_open(&SPI_CSN_PinState, SPI_CSN_PinTable);}(3)在SPI发送函数中,添加片选信号的拉低和拉高
uint8_t SPI_transfer_frame_write(PIN_Handle pin_handle,SPI_Handle handle,SPI_Transaction *transaction,uint8_t *buffer, size_t size) {uint8_t uint8t_ret = 0;bool bool_ret = true;transaction->count = size;transaction->txBuf = buffer;transaction->rxBuf = NULL;PIN_setOutputValue(pin_handle, CC2640R2_LAUNCHXL_SPI0_CSN_MANUAL, 0);delay_us(1);bool_ret = SPI_transfer(handle, transaction);if(bool_ret == true){uint8t_ret = 1;}else{uint8t_ret = 0;}PIN_setOutputValue(pin_handle, CC2640R2_LAUNCHXL_SPI0_CSN_MANUAL, 1);delay_us(1);return uint8t_ret;}static void Spi_taskFxn(UArg a0, UArg a1) {Spi_task_init();//SPI_transfer_frame_write(handle, &transaction,txBuffer, 32);SPI_transfer_frame_write(hPins,handle, &transaction,signature, 51);}
2、运行程序后,发现CC2640无法发送数据。如图1所示。发送失败的原因是片选信号拉低之后,CLK依旧保持高电平。
3、调整片选信号拉低和拉高后的延时时间,无论使用delay_us(1)还是delay_us(2),都会发送失败
请问还有没有别的方法?
heng fu:
回复 Barbara Wu:
我已经将master配置成功,但是slave配置失败,导致SPI通信失败
参照上述帖子中的内容,成功配置master。但是slave的片选管脚该如何配置?
1、slave节点的配置代码如下所示(1)slave节点的片选信号设为IOID-20
#define CC2640R2_LAUNCHXL_SPI0_MISOIOID_6/* RF1.20 */ #define CC2640R2_LAUNCHXL_SPI0_MOSIIOID_7/* RF1.18 */ #define CC2640R2_LAUNCHXL_SPI0_CLKIOID_10/* RF1.16 */ #define CC2640R2_LAUNCHXL_SPI0_CSNIOID_20(2)在IO口的初始化列表中初始化slave节点的IO口
const PIN_Config BoardGpioInitTable[] = {CC2640R2_LAUNCHXL_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low */CC2640R2_LAUNCHXL_PIN_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low *///CC2640R2_LAUNCHXL_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,/* External flash chip select */CC2640R2_LAUNCHXL_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN,/* UART RX via debugger back channel *//*-----当不使用UART时,应该将UART TX拉低,避免漏电 -----*/CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,/*CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,*//* UART TX via debugger back channel */CC2640R2_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master out - slave in */CC2640R2_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master in - slave out */CC2640R2_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI clock */CC2640R2_LAUNCHXL_SPI0_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,/*-----这里的配置是多余的,在ccfg.c中配置bootloader back door就足够 -----*//*BOOTLOADER_BACKDOOR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH,*/PIN_TERMINATE };2、slave节点的SPI初始化函数如下所示
static void Spi_task_init(void) {SPI_init();// Initialize the SPI driver// Init SPI and specify non-default parametersSPI_Params_init(¶ms);params.bitRate= 1000000;params.dataSize= 8;// 8-bit data sizeparams.frameFormat = SPI_POL0_PHA0;params.mode= SPI_SLAVE;params.transferMode= SPI_MODE_BLOCKING;// Configure the transactiontransaction.count = sizeof(signature);transaction.txBuf = (void *)signature;transaction.rxBuf = NULL;// Open the SPI and perform the transferhandle = SPI_open(Board_SPI0, ¶ms);}3、slave节点的SPI接收函数如下所示
uint8_t frame_total_dummy[32]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};uint8_t SPI_transfer_frame_read_head(SPI_Handle handle, SPI_Transaction *transaction) {uint8_t uint8t_ret = 0;bool bool_ret = true;transaction->count = 8;transaction->rxBuf = &frame_total_dummy[0];transaction->txBuf = NULL;bool_ret = SPI_transfer(handle, transaction);if(bool_ret == false){return 0;}/*帧头长度为8,帧尾长度为数据域长度加上校验域长度*/uint8t_ret = frame_total_dummy[7]+2;return uint8t_ret; }4、当master节点发送一帧数据后,slave节点仅能接收到第一个字节,然后CC2640就处于block状态,且蓝牙广播信号消失。master节点发送的一帧数据如图1所示
Barbara Wu:
回复 heng fu:
Hi Heng,
我看了一下代码,感觉这两个地方配错了
CC2640R2_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN,
这个应该是output
CC2640R2_LAUNCHXL_SPI0_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
这个应该是Input
heng fu:
回复 heng fu:
重新配置CC2640R2_LAUNCHXL_SPI0_CSN,将其配置为输入模式,SPI通信依旧失败。
CC2640R2_LAUNCHXL_SPI0_CSN的配置代码如下所示:
const PIN_Config BoardGpioInitTable[] = {CC2640R2_LAUNCHXL_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low */CC2640R2_LAUNCHXL_PIN_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low *///CC2640R2_LAUNCHXL_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,/* External flash chip select */CC2640R2_LAUNCHXL_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN,/* UART RX via debugger back channel *//*-----当不使用UART时,应该将UART TX拉低,避免漏电 -----*/CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,/*CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,*//* UART TX via debugger back channel */CC2640R2_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master out - slave in */CC2640R2_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master in - slave out */CC2640R2_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI clock */CC2640R2_LAUNCHXL_SPI0_CSN | PIN_BM_INPUT_EN | PIN_PULLDOWN,/*-----这里的配置是多余的,在ccfg.c中配置bootloader back door就足够 -----*//*BOOTLOADER_BACKDOOR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH,*/PIN_TERMINATE };
heng fu:
回复 heng fu:
将MISO和CSN管脚都更改后,依旧通信失败。slave节点还是只能接收到第一个字节。代码配置如下:
const PIN_Config BoardGpioInitTable[] = {CC2640R2_LAUNCHXL_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,/* LED initially off */CC2640R2_LAUNCHXL_PIN_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low */CC2640R2_LAUNCHXL_PIN_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,/* Button is active low *///CC2640R2_LAUNCHXL_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,/* External flash chip select */CC2640R2_LAUNCHXL_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN,/* UART RX via debugger back channel *//*-----当不使用UART时,应该将UART TX拉低,避免漏电 -----*/CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,/*CC2640R2_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,*//* UART TX via debugger back channel */CC2640R2_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI master out - slave in */CC2640R2_LAUNCHXL_SPI0_MISO | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,/* SPI master in - slave out */CC2640R2_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN,/* SPI clock */CC2640R2_LAUNCHXL_SPI0_CSN | PIN_BM_INPUT_EN | PIN_PULLDOWN,/*-----这里的配置是多余的,在ccfg.c中配置bootloader back door就足够 -----*//*BOOTLOADER_BACKDOOR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH,*/PIN_TERMINATE };
Barbara Wu:
回复 heng fu:
看起来没有问题, 唯一我能想到的原因,1.transaction->count = 8;
transaction->rxBuf = &frame_total_dummy[0]; 这两个把长度写一样试试
2. 不知道CSN脚的修改是不是对Slave有影响。
user3496832:
已经参加