Hi,大家好,今天在调试EasyLink的接收例程,想把TX发给RX端的数据通过串口发送到上位机。串口的初始化是参考Uartecho例程的,之前在其他例程中也是一直在使用没有问题。但是在EasyLink中使用时,打印出来的是一串错乱的16进制,并不是我想要的数据。我想请问一下,rfEasyLinkEchoRx这个例程与Uart驱动有冲突吗?以下是我的代码。display已经通过宏注释了,现在只有一个uart。请TI工程师帮忙验证一下。
/*
* ======== rfEasyLinkEchoRx.c ========
*/
/* Standard C Libraries */
#include <stdlib.h>
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/Assert.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>
/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
/* Board Header files */
#include "Board.h"
/* Application Header files */
#include "smartrf_settings/smartrf_settings.h"
/* EasyLink API Header files */
#include "easylink/EasyLink.h"
#include "user/message.h"
#include <ti/drivers/NVS.h>
#if DISPLAY_OPEN
#include <ti/display/Display.h>
#endif
#include <ti/drivers/UART.h>
#define RFEASYLINKECHO_TASK_STACK_SIZE 1024
#define RFEASYLINKECHO_TASK_PRIORITY 2
#define RFEASYLINKECHO_PAYLOAD_LENGTH 30
Task_Struct echoTask; /* not static so you can see in ROV */
static Task_Params echoTaskParams;
static uint8_t echoTaskStack[RFEASYLINKECHO_TASK_STACK_SIZE];
/* Pin driver handle */
static PIN_Handle pinHandle;
static PIN_State pinState;
/*NVS handle*/
NVS_Handle nvsHandle;
/*
* Application LED pin configuration table:
* – All LEDs board LEDs are off.
*/
PIN_Config pinTable[] = {
Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
static Semaphore_Handle echoDoneSem;
static bool bBlockTransmit = false;
EasyLink_TxPacket txPacket = {{0}, 0, 0, {0}};
/***************************Handle***************************/
#if UART_OPEN
/*Uart handle*/
UART_Handle uart;
UART_Params uartParams;
#endif
#if DISPLAY_OPEN
Display_Handle uartDisplayHandle;
void Display_Init();
#endif
/**************************variable**************************/
Uart_Req_Data Sensor_Data = {
.head.Mache = 0x01,
.head.Func = 0xA0,
.Addr = 0x0600,
.tail.CRC16 = 0xA090,
.tail.End = 0x96,
};
Config_Req Rx_Config = {
.Frequency = 868000000,
.Address = 0xDE,
};
Ack_Rx_Req Rx_Ack = {
.head.Mache = 0x03,
.head.Func = 0x87,
.report_time = 30000, //MS
};
Data_Req Rx_Data;
uint8_t Rx_Buff[5];
uint32_t Frq;
uint8_t Address;
uint16_t CRC;
/************************************************************/
void echoTxDoneCb(EasyLink_Status status)
{
if (status == EasyLink_Status_Success)
{
/* Toggle LED2 to indicate Echo TX, clear LED1 */
PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
}
else
{
/* Set LED1 and clear LED2 to indicate error */
PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
}
Semaphore_post(echoDoneSem);
}
void echoRxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
{
if (status == EasyLink_Status_Success)
{
/* Toggle LED2 to indicate RX, clear LED1 */
PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
/* Permit echo transmission */
bBlockTransmit = false;
if(rxPacket->payload[0] == 0x01 && rxPacket->payload[1] == 0xA0)
{
memcpy(&Rx_Data,rxPacket->payload,sizeof(Data_Req));
CRC = crc16((uint8_t *)&Rx_Data,sizeof(Data_Req) – 2);
if(Rx_Data.Crc16 == CRC)
{
memcpy(&Sensor_Data.temp_data,rxPacket->payload+2,14);
Sensor_Data.temp_data.Rssi_Val = rxPacket->rssi;
#if DISPLAY_OPEN
Display_printf(uartDisplayHandle, 0, 0, "rssi:%d",rxPacket->rssi);
#endif
#if UART_OPEN
UART_write(uart, &Sensor_Data, sizeof(Uart_Req_Data));
#endif
}
}
}
else
{
/* Set LED1 and clear LED2 to indicate error */
PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
/* Block echo transmission */
bBlockTransmit = true;
}
Semaphore_post(echoDoneSem);
}
static void rfEasyLinkEchoRxFnx(UArg arg0, UArg arg1)
{
/* Create a semaphore for Async */
Semaphore_Params params;
Error_Block eb;
/* Init params */
Semaphore_Params_init(¶ms);
Error_init(&eb);
/* Create semaphore instance */
echoDoneSem = Semaphore_create(0, ¶ms, &eb);
if(echoDoneSem == NULL)
{
System_abort("Semaphore creation failed");
}
// Initialize the EasyLink parameters to their default values
EasyLink_Params easyLink_params;
EasyLink_Params_init(&easyLink_params);
/*
* Initialize EasyLink with the settings found in easylink_config.h
* Modify EASYLINK_PARAM_CONFIG in easylink_config.h to change the default
* PHY
*/
if(EasyLink_init(&easyLink_params) != EasyLink_Status_Success)
{
System_abort("EasyLink_init failed");
}
#if DISPLAY_OPEN
Display_Init();
#endif
#if UART_OPEN
Uart_Init();
#endif
/*
* If you wish to use a frequency other than the default, use
* the following API:
* EasyLink_setFrequency(868000000);
*/
EasyLink_setFrequency(Frq);
while(1) {
// Wait to receive a packet
EasyLink_receiveAsync(echoRxDoneCb, 0);
/* Wait indefinitely for Rx */
Semaphore_pend(echoDoneSem, BIOS_WAIT_FOREVER);
if(bBlockTransmit == false)
{
Rx_Ack.CRC = crc16((uint8_t *)&Rx_Ack,sizeof(Ack_Rx_Req) – 2);
memcpy(&txPacket.payload, &Rx_Ack, sizeof(Ack_Rx_Req));
txPacket.len = 8;
txPacket.dstAddr[0] = Address;
txPacket.absTime = 0;
EasyLink_transmitAsync(&txPacket, echoTxDoneCb);
/* Wait for Tx to complete. A Successful TX will cause the echoTxDoneCb
* to be called and the echoDoneSem to be released, so we must
* consume the echoDoneSem
*/
Semaphore_pend(echoDoneSem, BIOS_WAIT_FOREVER);
}
}
}
void echoTask_init(PIN_Handle inPinHandle) {
pinHandle = inPinHandle;
Task_Params_init(&echoTaskParams);
echoTaskParams.stackSize = RFEASYLINKECHO_TASK_STACK_SIZE;
echoTaskParams.priority = RFEASYLINKECHO_TASK_PRIORITY;
echoTaskParams.stack = &echoTaskStack;
echoTaskParams.arg0 = (UInt)1000000;
Task_construct(&echoTask, rfEasyLinkEchoRxFnx, &echoTaskParams, NULL);
}
/*
* ======== main ========
*/
int main(void)
{
/* Call driver init functions. */
Board_initGeneral();
/* Open LED pins */
pinHandle = PIN_open(&pinState, pinTable);
Assert_isTrue(pinHandle != NULL, NULL);
/* Clear LED pins */
PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
NVS_Init();
//读寄存器存在两个全局变量中(频率和地址)
NVS_read(nvsHandle, 0, (void *) Rx_Buff, sizeof(Rx_Buff));
if(Rx_Buff[0] == 0xFF && Rx_Buff[1] == 0xFF && Rx_Buff[2] == 0xFF)
{
//将配置的变量分别替换到修改变量中
Frq = Rx_Config.Frequency;
Address = Rx_Config.Address;
// NVS_write(nvsHandle, 0, &TX_Config.Data,sizeof(Config_Data),\
// NVS_WRITE_PRE_VERIFY | NVS_WRITE_POST_VERIFY);
}
else{
//将读取到的值存到对应的变量中
memcpy(&Rx_Config + 2, Rx_Buff, sizeof(uint32_t) + sizeof(uint8_t));
Frq = Rx_Config.Frequency;
Address = Rx_Config.Address;
// NVS_erase(nvsHandle, 0, regionAttrs.sectorSize);
}
echoTask_init(pinHandle);
/* Start BIOS */
BIOS_start();
return (0);
}
#if DISPLAY_OPEN
void Display_Init()
{
Display_init();
Display_Params params;
Display_Params_init(¶ms);
uartDisplayHandle = Display_open(Display_Type_UART, ¶ms);
Display_printf(uartDisplayHandle, 0, 0, "Display Init Success");
}
#endif
#if UART_OPEN
void Uart_Init()
{
UART_init();
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.baudRate = 115200;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readEcho = UART_ECHO_OFF;
uart = UART_open(Board_UART0, &uartParams);
if(uart != NULL) {
/* UART_open() success */
// UART_write(uart, &Test, sizeof(uint8_t));
}
}
#endif
Viki Shi:
不冲突,这俩例程可以结合。举个例子,要把rfEasyLinkEchoRx接收到的数据通过UART输出,可在radio收到数据以后添加UART_write(),初始化的内容应该在开头完成
/* Wait indefinitely for Rx */
Semaphore_pend(echoDoneSem, BIOS_WAIT_FOREVER);
UART_write(uart, txPacket.payload, (size_t)txPacket.len);//默认设置了RFEASYLINKECHO_ASYNC
lin shi chang:
回复 Viki Shi:
感谢您的回复,请教一下。您说的初始化内容要在开头完成是在rfEasyLinkEchoRxFnx这个任务中还是在main中进行初始化?
还有我按照您说的将UART_write()放在了Semaphore_pend(echoDoneSem, BIOS_WAIT_FOREVER);之后,但是打印出来的数据不是TX发过去的数据。debug看到确实是有收到TX发的数据,但是打印出来就不一样了。
Viki Shi:
回复 lin shi chang:
rfEasyLinkEchoRxFnx里
lin shi chang:
回复 Viki Shi:
是的,我确实是放在rfEasyLinkEchoRxFnx里的。还有就是打出来的数据和收到的数据不一样。会不会是哪个功能和uart共用缓冲区造成混乱啊?这个您能帮我验证一下吗?
lin shi chang:
回复 Viki Shi:
刚刚我初始化时,还打了一个固定的16进制数0x11。但是调用UART_write(uart, &Test, sizeof(uint8_t));打出来的却不是我定义的16进制数。而是其他的。您也帮我看一下。
lin shi chang:
回复 Viki Shi:
您好,最后我找到了这个奇怪现象的原因。原来是头文件引用顺序造成的,害我找问题找了大半天,还费了好多时间出现问题的原因。
#include "user/message.h"
#include <ti/drivers/NVS.h>
#include <ti/drivers/UART.h>改成
#include <ti/drivers/UART.h>
#include "user/message.h"
#include <ti/drivers/NVS.h>
就可以了。面对这个问题,我想提个问题,是不是自己定义的头文件一般放在后面比较好。不然会出现这种奇怪的问题?
Viki Shi:
回复 lin shi chang:
照理说顺序应该不影响,没有遇到过这情况
lin shi chang:
回复 Viki Shi:
我今天又还原回去了,没有发现这个问题。挺奇怪的,不知道怎么解释。我看看还能不能还原这个现象。
Viki Shi:
回复 lin shi chang:
ok,期待你的反馈。蛮奇怪的现象
lin shi chang:
回复 Viki Shi:
我把程序还原到原来一开始就有问题的版本了。现在把它压缩了发给您。您帮忙看一下。是否运行有问题,如果出现这个问题,您试试头文件应用顺序。
之后我就按照这个版本往下修改。之后的版本,把顺序换回来没发现这个问题,不知道是什么造成的。RX端有问题程序.rar