TI中文支持网
TI专业的中文技术问题搜集分享网站

救急!,采用CC1310实现modbus-rtu的功能,但是串口工作不正常

我需要使用CC1310作为MODBUS-RTU的从设备,我必须采用定时器的时间来判断帧的结束,但是我采用9600波特率时,设置定时器为3.5ms判断帧结束,这时我只能接收小数据字节的数据帧,当进行大量数据的时候,还没有接收完成,定时器就产生了中断,判断帧结束了

一下是我的代码,

1、底层配置

/*
 *  =============================== UART ===============================
 */
#include <ti/drivers/UART.h>
#include <ti/drivers/uart/UARTCC26XX.h>

UARTCC26XX_Object uartCC26XXObjects[CC1310_5x5BOARD_UARTCOUNT];

uint8_t uartCC26XXRingBuffer[CC1310_5x5BOARD_UARTCOUNT][1024];

const UARTCC26XX_HWAttrsV2 uartCC26XXHWAttrs[CC1310_5x5BOARD_UARTCOUNT] = {{.baseAddr= UART0_BASE,.powerMngrId= PowerCC26XX_PERIPH_UART0,.intNum= INT_UART0_COMB,.intPriority= 0,.swiPriority= 2,.txPin= CC1310_5x5BOARD_UART_TX,.rxPin= CC1310_5x5BOARD_UART_RX,.ctsPin= PIN_UNASSIGNED,.rtsPin= PIN_UNASSIGNED,.ringBufPtr= uartCC26XXRingBuffer[CC1310_5x5BOARD_UART0],.ringBufSize= sizeof(uartCC26XXRingBuffer[CC1310_5x5BOARD_UART0]),.txIntFifoThr= UARTCC26XX_FIFO_THRESHOLD_1_8,.rxIntFifoThr= UARTCC26XX_FIFO_THRESHOLD_2_8,.errorFxn= NULL}
};

const UART_Config UART_config[CC1310_5x5BOARD_UARTCOUNT] = {{.fxnTablePtr = &UARTCC26XX_fxnTable,.object= &uartCC26XXObjects[CC1310_5x5BOARD_UART0],.hwAttrs= &uartCC26XXHWAttrs[CC1310_5x5BOARD_UART0]},
};

const uint_least8_t UART_count = CC1310_5x5BOARD_UARTCOUNT;

/*
 *  =============================== UDMA ===============================

2、串口初始化

/***********************************************************************************************
 * Function:RS485_Usart_Init
 * Description:485串口初始化
 * Input:uint32_t u32baudRate
 * Output:
 * Note(s):
 ***********************************************************************************************/
void RS485_Usart_Init(uint32_t u32baudRate)
{//GPIO_setConfig(Board_PIN_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);//const char echoPrompt[] = "RS485_Usart_Init:\r\n";/* Call driver init functions */GPIO_init();{GPIO_setConfig(Board_GPIO_REDE0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);GPIO_setConfig(Board_GPIO_REDE1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);GPIO_setConfig(Board_GPIO_REDE2, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);}UART_init();/* Create a UART with data processing off. */UART_Params_init(&uartParams);uartParams.baudRate = u32baudRate;uartParams.parityType = UART_PAR_NONE;uartParams.dataLength = UART_LEN_8;uartParams.stopBits = UART_STOP_ONE;uartParams.writeDataMode = UART_DATA_BINARY;uartParams.writeMode = UART_MODE_CALLBACK;uartParams.writeCallback = uartCallback;//uartParams.writeTimeout = UART_WAIT_FOREVER;uartParams.readDataMode = UART_DATA_BINARY;uartParams.readMode = UART_MODE_CALLBACK;uartParams.readCallback = uartReadCallback;uartParams.readTimeout = UART_WAIT_FOREVER;uart = UART_open(Board_UART0, &uartParams);if (uart == NULL){/* UART_open() failed */while (1);}
//USART_SWITCH_TX
//;
//
//UART_write(uart, echoPrompt, sizeof(echoPrompt));
//Delay_ms(1);USART_SWITCH_RX;
//GPIO_write(Board_GPIO_REDE0, 0);
//GPIO_write(Board_GPIO_REDE1, 0);
//GPIO_write(Board_GPIO_REDE2, 0);Modbus_RegMap(); //modbus-rtu寄存器地址映射

}

3、串口接收回调

void uartReadCallback(UART_Handle handle, void *buf, size_t count)
{
//Led1Toggle();
UART_readCancel(handle);
usartControl.byteRxEndFlag = false;
if (usartControl.strRxCount < USART_MAX_RX_COUNT)
{
usartControl.RxBuf[usartControl.strRxCount] = ((uint8_t*) buf)[0];
usartControl.strRxCount++;
}
else
{
usartControl.strRxCount = 0;
usartControl.RxBuf[usartControl.strRxCount] = ((uint8_t*) buf)[0];
usartControl.strRxCount++;
}

stopTimer(); //关闭定时器
//gpTimerClose();
//timerSet((float)usartControl.strRxCount * 1.04 + 8); //配置为4ms
myGpTimerInit(usartControl.strRxCount + 1);
openTimer(); //开启定时器
UART_read(uart, &input, 1);
return;
}

4、定时器函数

/***********************************************************************************************
* Function :myGpTimerInit
* Description : 定时器初始化
* Input :uint32_t timerValue
* Output :
* Note(s) :
***********************************************************************************************/
void myGpTimerInit(float timerValue)
{
/* Open the GPTimer driver */
GPTimerCC26XX_Params params;
if(timerValue == 0)
{
GPTimerCC26XX_Params_init(&params);
params.width = GPT_CONFIG_32BIT;
params.mode = GPT_MODE_ONESHOT_UP;
//params.mode = GPT_MODE_PERIODIC_UP;
params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
hTimer = GPTimerCC26XX_open(Board_GPTIMER1A, &params);
if(hTimer == NULL)
{
while(1);
}
}
if(timerValue != 0)
{

GPTimerCC26XX_setLoadValue(hTimer, 0);

GPTimerCC26XX_setLoadValue(hTimer, 191996);//定时3.5ms

/* Register the GPTimer interrupt */
GPTimerCC26XX_registerInterrupt(hTimer, myTimeoutCb, GPT_INT_TIMEOUT);
}

}

/***********************************************************************************************
* Function :openTimer
* Description : 开启定时器
* Input :
* Output :
* Note(s) :
***********************************************************************************************/
void openTimer(void)
{
/*
* Start the Receiver timeout timer (300ms) before
* EasyLink_receiveAsync enables the power policy
*/
//myGpTimerInit(300);
GPTimerCC26XX_start(hTimer);
}

/***********************************************************************************************
* Function :openTimer
* Description :关闭定时器
* Input :
* Output :
* Note(s) :
***********************************************************************************************/
void stopTimer(void)
{

GPTimerCC26XX_stop(hTimer);
//gpTimerClose();
}

void gpTimerClose(void)
{
GPTimerCC26XX_close(hTimer);
}

4、定时器中断回调

/***********************************************************************************************
* Function :rxTimeoutCb
* Description : 定时器超时回调函数
* Input :GPTimerCC26XX_Handle handle,GPTimerCC26XX_IntMask interruptMask
* Output :
* Note(s) :
***********************************************************************************************/
void myTimeoutCb(GPTimerCC26XX_Handle handle,GPTimerCC26XX_IntMask interruptMask)
{
/* Set the Timeout Flag */
//rxTimeoutFlag = true;
Led1Toggle();
// Led2Toggle();
//readCancel();
usartControl.strRxEndFlag = true;
/*
* Timer is automatically stopped in one-shot mode and needs to be reset by
* loading the interval load value
*/
//timerSet();
}

5、主循环调用

// while(1)
{
usartDataGet();
RTU_SlaverService();
}

Viki Shi:

“但是我采用9600波特率时,设置定时器为3.5ms判断帧结束,这时我只能接收小数据字节的数据帧,当进行大量数据的时候,还没有接收完成,定时器就产生了中断,判断帧结束了”

如果我理解正确,你所有的数据结束判断都是通过3.5ms?那大量数据时显然时间不够啊。modbus我没做过,是否可以通过外部中断?

Hwadong Chan:

程序架构貌似没有问题,你确定定时器是预想的3.5ms吗?适当延长一下时间看看。

注释的代码是什么情况,主循环都注释掉了。

赞(0)
未经允许不得转载:TI中文支持网 » 救急!,采用CC1310实现modbus-rtu的功能,但是串口工作不正常
分享到: 更多 (0)