Other Parts Discussed in Thread: CC2640
主题中讨论的其他器件:CC2640
工具/软件:Code Composer Studio
尊敬的 TI 支持团队
您好!
我的项目有问题、希望您能帮我解决。 我的项目是在一个 CC2640 Launchpad 和一个 C2000系列 Launchpad (例如 F28379d)之间的 SPI 的帮助下发送和接收数据。
遗憾的是、我是一名初学者、我正在做一些小步骤来学习如何使用微控制器。 为了达到最终目标、我从 spislave_CC2640R2_LAUNCHXL_tirtos_ccs 和 spimaster_CC2640R2_LAUNCHXL_tirtos_ccs 示例开始、在两个 CC2640微控制器之间进行通信、该示例运行得很好。 下一步是用两个简单的数字(该数字应在 ADC 值范围内、例如、我希望发送此对[3000、3001])替换字符串(从器件的 Hello、msg#:")。 第一个问题是如何以最小变化量修改代码? (请向我展示我需要如何更改代码的哪一部分以及需要更改的代码。 我尝试自己更改它,但结果不是我所期望的,毕竟我是一个初学者)。
第二个问题是、在下一步中、如果我想在 CC2640和 F28379d 之间进行通信、是否可能由于 RTOS 和裸机之间的差异而面临问题?
这是原始示例代码。 如果您向我展示如何更改它、我们将不胜感激。
%%%%%%%%%%%%%%%%%%
SPI 主器件:
%%%%%%%%%%%%%%%%%%
/*示例/板头文件*/
#include "Board.h"
#define THREADSTACKSIZE (1024)
#define SPI_MSG_LENGTH (30)
#define MASTER_MSG ("Hello from master、msg#:")
#define MAX_LOOP (10)
静态 Display_Handle 显示;
unsigned char masterRxBuffer[SPI_MSG_LENG];
unsigned char masterTxBuffer[SPI_MSG_LENG];
//在从器件准备好传输之前阻止主器件的信号量*/
SEM_t masterSem;
/*
*=== slaveReadyFxn ===
* Board_SPI_SLAVE_READY 上 GPIO 中断的回调函数。
*/
void slaveReadyFxn (uint_least8_t index)
{
SEM_post (&masterSem);
}
/*
=== masterThread ======
*主器件 SPI 在向从器件发送消息的同时从
从器件接收*消息。
//
void * masterThread (void * arg0)
{
SPI_Handle 主 Spi;
SPI_Params Parspiams;
SPI_Transaction 事务;
uint32_t 一;
布尔 转让;
内部32_t 状态;
/*
* Board_SPI_MASTER_READY 和 Board_SPI_SLAVE_READY 是连接的 GPIO 引脚
主器件和从器件之间的*。 这些引脚用于同步
*通过一个小的"握手"来控制主器件和从器件应用。 引脚
*稍后用于同步传输并确保主设备不会
*开始传输、直至从设备就绪。 这些引脚的行为
*不同的 spimaster 和 spislave 示例:
*
* spimaster 示例:
* * Board_SPI_MASTER_READY 配置为输出引脚。 期间
* "握手"此引脚从低电平更改为高电平输出。 这种情况
* 通知从器件主器件已准备好运行应用程序。
* 之后、主器件使用该引脚通知从器件
* 已打开 Board_SPI_master。 当 BOARD_SPI_MASTER 打开时、即会执行此操作
* 引脚将被拉低。
*
* * Board_SPI_SLAVE_READY 配置为输入引脚。 期间
* "握手"读取此引脚、高电平值将指示从器件
* 已准备好运行应用程序。 然后、一个下降沿中断
* 将在该引脚上配置。 当从设备准备好执行时
* 传输、它会将该引脚拉低。
*
*下面我们设置 Board_SPI_MASTER_READY 和 Board_SPI_SLAVE_READY 初始值
*"握手"的条件。
*
GPIO_setConfig (Board_SPI_MASTER_READY、GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_setConfig (Board_SPI_SLAVE_READY、GPIO_CFG_INPUT);
/*
*握手-将 Board_SPI_MASTER_READY 设置为高电平以指示主器件已就绪
*以运行。 等待 Board_SPI_SLAVE_READY 变为高电平。
*
GPIO_WRITE (Board_SPI_MASTER_READY、1);
while (GPIO_Read (Board_SPI_SLAVE_READY)= 0){}
//握手完成;现在在 Board_SPI_SLAVE_READY 上配置中断*/
GPIO_setConfig (Board_SPI_SLAVE_READY、GPIO_CFG_IN_pu | GPIO_CFG_IN_INT_INT_FALLING);
GPIO_setCallback (Board_SPI_SLAVE_READY、slaveReadyFxn);
GPIO_enableInt (Board_SPI_SLAVE_READY);
/*
*创建同步信标;主器件将在此信标上等待
*直到从设备就绪。
*
状态= SEM_INIT (&masterSem、0、0);
if (status!= 0){
display_printf (display、0、0、"创建 masterSem\n"error creating masterSem\n");
while (1);
}
/*将 SPI 作为主器件打开(默认)*/
SPI_Params_init (&spiParams);
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.bitrate = 4000000;
masterSpi = SPI_open (Board_SPI_master、&spiParams);
if (masterSpi == NULL){
Display_printf (display、0、0、"初始化主器件 SPI\n"时出错);
while (1);
}
否则{
display_printf (display、0、0、"Master SPI initialized");
}
/*
*主器件已打开 Board_SPI_MASTER;将 Board_SPI_MASTER_READY 设置为高电平
*通知从属方。
*
GPIO_WRITE (Board_SPI_MASTER_READY、0);
/*将消息复制到发送缓冲区*/
strncpy ((char *) masterTxBuffer、master_MSG、SPI_MSG_LENGTH);
对于(I = 0;I < MAX_LOOP;I++){
/*
*等待从器件准备好传输;从器件将拉取
* Board_SPI_SLAVE_READY 低电平。
*
SEM_WAIT (masterSem);
/*初始化主 SPI 事务结构*/
masterTxBuffer[sizeof (master_MSG)- 1]=(i % 10)+'0';
memset ((void *) masterRxBuffer、0、SPI_MSG_LENGTH);
transaction.count = SPI_MSG_length;
transaction.txBuf =(void *) masterTxBuffer;
transaction.rxBuf =(void *) masterRxBuffer;
/*切换用户 LED、指示正在进行 SPI 传输*/
GPIO_TOGGLE (Board_GPIO_LED1);
/*执行 SPI 传输*/
transferOK = SPI_transfer (masterSpi、事务);
if (transferOK){
Display_printf (display、0、0、"主设备已接收:%s"、masterRxBuffer);
}
否则{
display_printf (display、0、0、"主 SPI 传输失败");
}
/*在开始下一个 SPI 传输前睡眠一位*/
睡眠(3);
}
SPI_CLOSE (masterSpi);
/*示例完成-将引脚设置为已知状态*/
GPIO_DisableInt (Board_SPI_SLAVE_READY);
GPIO_setConfig (Board_SPI_SLAVE_READY、GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_WRITE (Board_SPI_MASTER_READY、0);
display_printf (display、0、0、"\nDone");
返回(NULL);
}
/*
==== mainThread ====
//
void * mainThread (void * arg0)
{
pthread_t 线程0;
pthread_attr_t attrs;
struct sched_param primParam;
内部 REC;
内部 detachState;
/*调用驱动程序初始化函数。 *
display_init();
GPIO_init();
spi_init();
/*配置 LED 引脚*/
GPIO_setConfig (Board_GPIO_LED0、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_setConfig (Board_GPIO_LED1、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/*打开输出的显示屏*/
Display = Display_open (Display_Type_UART、NULL);
if (display =NULL){
/*无法打开显示驱动程序*/
while (1);
}
/*打开用户 LED */
GPIO_WRITE (Board_GPIO_LED0、Board_GPIO_LED_ON);
display_printf (display、0、0、"启动 SPI 主设备示例");
display_printf (display、0、0、"此示例要求外部电线为"
"已连接至接头引脚。 有关详细信息、请参阅 Board.html。\n");
/*创建应用程序线程*/
pthread_attr_init (atttrs);
detachState = pthread_create_detached;
/*设置优先级和堆栈大小属性*/
retc = pthread_attr_setdetachstate (&attrs、detachState);
如果(retc!= 0){
/* pthread_attr_setdetachstate()失败*/
while (1);
}
retc |= pthread_attr_setstacksize (&attrs、THREADSTACKSIZE);
如果(retc!= 0){
/* pthread_attr_setstacksize()失败*/
while (1);
}
/*创建主线程*/
priParam.sched_priority = 1;
pthread_attr_setschedparam (&attrs、&priParam);
retc = pthread_create (&thread0、&attrs、masterThread、NULL);
如果(retc!= 0){
/* pthread_create()失败*/
while (1);
}
返回(NULL);
}
%%%%%%%%%%%%%%%%%%
SPI 从器件:
%%%%%%%%%%%%%%%%%%
#define THREADSTACKSIZE (1024)
#define SPI_MSG_LENGTH (30)
#define SLAVE_MSG ("Hello from slave、msg#:")
#define MAX_LOOP (10)
静态 Display_Handle 显示;
unsigned char slaveRxBuffer[SPI_MSG_length];
unsigned char slaveTxBuffer[SPI_MSG_length];
//在传输完成前阻止从站的信号量*/sem_t
slaveSem;
/*
*=== transferCompleteFxn ===
* SPI_TRANSFCTION ()的回调函数。
//
void transferCompleteFxn (SPI_Handle handle、SPI_Transaction *事务)
{
SEM_post (&slaveSem);
}
/*
=== slaveThread ====
*从器件 SPI 在同时接收
来自主器件的*消息的同时向主器件发送消息。
//
void * slaveThread (void * arg0)
{
SPI_Handle slaveSpi;
SPI_Params Parspiams;
SPI_Transaction 事务;
uint32_t 一;
布尔 转让;
内部32_t 状态;
/*
* Board_SPI_MASTER_READY 和 Board_SPI_SLAVE_READY 是连接的 GPIO 引脚
主器件和从器件之间的*。 这些引脚用于同步
*通过一个小的"握手"来控制主器件和从器件应用。 引脚
*稍后用于同步传输并确保主设备不会
*开始传输、直至从设备就绪。 这些引脚的行为
*不同的 spimaster 和 spislave 示例:
*
* spislave 示例:
* * Board_SPI_MASTER_READY 配置为输入引脚。 期间
* "握手"读取此引脚、高电平值将指示
* 主设备已准备好运行应用程序。 之后、引脚为
* 读取以确定主器件是否已打开其 SPI 引脚。
* 当主器件打开其 SPI 时、它将把这个引脚拉低。
*
* * Board_SPI_SLAVE_READY 配置为输出引脚。 期间
* "握手"此引脚从低电平更改为高电平输出。 这种情况
* 通知主器件从器件已准备好运行应用程序。
* 之后、从器件使用该引脚向主器件发出通知
* 已准备好进行传输。 当准备好进行传输时、该引脚将会
* 下拉至低电平。
*
*下面我们设置 Board_SPI_MASTER_READY 和 Board_SPI_SLAVE_READY 初始值
*"握手"的条件。
*
GPIO_setConfig (Board_SPI_SLAVE_READY、GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_setConfig (Board_SPI_MASTER_READY、GPIO_CFG_INPUT);
/*
*握手-将 Board_SPI_SLAVE_READY 设置为高电平以指示从器件就绪
*以运行。 等待 Board_SPI_MASTER_READY 变为高电平。
*
GPIO_WRITE (Board_SPI_SLAVE_READY、1);
while (GPIO_Read (Board_SPI_MASTER_READY)=0){}
/*
*创建同步信标;该信标将阻止从器件
*直到传输完成。 从机配置为回调模式
*以便我们配置 SPI 传输、然后通知主器件
*从设备已准备就绪。 但是、我们仍然必须等待电流传输
*在设置下一个之前完成。 因此、我们等待 slaveSem;
*一旦传输完成、回调函数将解除阻止
*从属设备。
*
状态= SEM_INIT (&slaveSem、0、0);
if (status!= 0){
display_printf (display、0、0、"创建 slaveSem\n"error creating slaveSem\n");
while (1);
}
/*
*等待主器件 SPI 打开。 配置 SPI 引脚时、将会发生这种情况
*时钟可以从低电平切换到高电平(或从高电平切换到低电平、具体取决于
*极性)。 如果使用3引脚 SPI 且从器件在之前已打开
*假设主器件、时钟转换可能会导致从器件移出位
*这是一个实际的传输。 我们可以通过打开来防止这种行为
*首先主设备,然后打开从设备。
*
while (GPIO_Read (Board_SPI_MASTER_READY)){}
/*
*在回调模式下以从器件身份打开 SPI;回调模式用于允许我们这样做
*配置传输、然后将 Board_SPI_SLAVE_READY 设置为高电平。
*
SPI_Params_init (&spiParams);
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.mode = SPI_SLAVE;
spiParams.transferCallbackFxn = transferCompleteFxn;
spiParams.transferMode = SPI_MODE_CALLACK;
slaveSpi = SPI_open (Board_SPI_slave、&spiParams);
if (slaveSpi == NULL){
Display_printf (display、0、0、"初始化从器件 SPI\n"时出错);
while (1);
}
否则{
display_printf (display、0、0、"已初始化从属 SPI \n");
}
/*将消息复制到发送缓冲区*/
strncpy ((char *) slaveTxBuffer、SLAVE_MSG、SPI_MSG_LENGTH);
对于(I = 0;I < MAX_LOOP;I++){
/*初始化从属 SPI 事务结构*/
slaveTxBuffer[sizeof (slave_MSG)- 1]=(I % 10)+'0';
memset ((void *) slaveRxBuffer、0、SPI_MSG_LENGTH);
transaction.count = SPI_MSG_length;
transaction.txBuf =(void *) slaveTxBuffer;
transaction.rxBuf =(void *) slaveRxBuffer;
/*打开用户 LED 指示灯,指示正在进行 SPI 传输*/
GPIO_TOGGLE (Board_GPIO_LED1);
/*
*设置 SPI 传输;Board_SPI_SLAVE_READY 将设置为通知
*主设备从设备就绪。
*
transferOK = SPI_transfer (slaveSpi、事务);
if (transferOK){
GPIO_WRITE (Board_SPI_SLAVE_READY、0);
/*等待传输完成*/
SEM_WAIT (slaveSem);
/*
*驱动 Board_SPI_SLAVE_READY 高电平以指示从器件未就绪
*用于另一个传输。
*
GPIO_WRITE (Board_SPI_SLAVE_READY、1);
display_printf (display、0、0、"从机接收到:%s"、slaveRxBuffer);
}
否则{
display_printf (display、0、0、"从器件 SPI 传输失败");
}
}
SPI_Close (slaveSpi);
/*示例完成-将引脚设置为已知状态*/
GPIO_setConfig (Board_SPI_MASTER_READY、GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_WRITE (Board_SPI_SLAVE_READY、0);
display_printf (display、0、0、"\nDone");
返回(NULL);
}
/*
==== mainThread ====
//
void * mainThread (void * arg0)
{
pthread_t 线程0;
pthread_attr_t attrs;
struct sched_param primParam;
内部 REC;
内部 detachState;
/*调用驱动程序初始化函数。 *
display_init();
GPIO_init();
spi_init();
/*配置 LED 引脚*/
GPIO_setConfig (Board_GPIO_LED0、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_setConfig (Board_GPIO_LED1、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/*打开输出的显示屏*/
Display = Display_open (Display_Type_UART、NULL);
if (display =NULL){
/*无法打开显示驱动程序*/
while (1);
}
/*打开用户 LED */
GPIO_WRITE (Board_GPIO_LED0、Board_GPIO_LED_ON);
display_printf (display、0、0、"启动 SPI 从设备示例");
display_printf (display、0、0、"此示例要求外部电线为"
"已连接至接头引脚。 有关详细信息、请参阅 Board.html。\n");
/*创建应用程序线程*/
pthread_attr_init (atttrs);
detachState = pthread_create_detached;
/*设置优先级和堆栈大小属性*/
retc = pthread_attr_setdetachstate (&attrs、detachState);
如果(retc!= 0){
/* pthread_attr_setdetachstate()失败*/
while (1);
}
retc |= pthread_attr_setstacksize (&attrs、THREADSTACKSIZE);
如果(retc!= 0){
/* pthread_attr_setstacksize()失败*/
while (1);
}
/*创建从线程*/
priParam.sched_priority = 1;
pthread_attr_setschedparam (&attrs、&priParam);
retc = pthread_create (&thread0、&attrs、slaveThread、NULL);
如果(retc!= 0){
/* pthread_create()失败*/
while (1);
}
返回(NULL);
}