主题中讨论的其他器件:C2000WARE、 SysConfig
工具与软件:
大家好!
我目前正在使用串行通信接口(SCI)将65x 板与 GNSS 模块连接。 我遇到了几个我希望在你的帮助下解决的问题。 以下是我的设置和面临的挑战的简要概述:
我需要从模块可靠地接收约70字节的 GNSS 数据。 数据频率和大小可能会有所不同、因此我已经实现了中断和 FIFO 缓冲区以确保数据处理的一致性。 考虑到我的应用对时间的要求严格、数据必须保持准确、因为它会影响多个子系统。
为了管理数据流、我已经为接收启用了 FIFO 中断、并将阈值设置为 FIFO 满级别。 因此、对于70字节的数据、RX FIFO 会生成4个中断来读取64字节。 但是、这会在 FIFO 缓冲区中保留6个字节。 为了检索最后6个字节,我使用 API 检查 RX FIFO 状态SCI_getRxFIFOStatus(SCI0_BASE)。
以下是我遇到的具体问题:
-
FIFO 状态检查的 ISR 问题 :该
SCI_getRxFIFOStatus函数似乎在 RX FIFO ISR 中不起作用。 我尝试直接使用访问 FIFO 状态(HWREGH(base_addr + SCI_O_FFRX) & SCI_FFRX_RXFFST_M) >> SCI_FFRX_RXFFST_S;、但也失败了。 直接硬件访问在 ISR 中不起作用是什么原因吗?或者我缺少什么吗? -
RX 数据不一致 :我接收的 SCI RX 数据不一致;我通常只接收传输数据的最后32个字节左右。 当我连续发送数据时、似乎会出现这种不一致。 但是、当我只传输一次时、数据是准确的。 我对为什么会发生这种行为感到困惑。
-
中断嵌套 :在电路板中或 C2000ware 中是否启用了中断嵌套? 为了启用嵌套中断、我需要执行什么具体操作吗?
我已附上相关代码片段和 SysConfig 作为参考。 非常感谢您提供任何见解或建议!
感谢你的帮助
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "c2000ware_libraries.h"
#include "stdio.h"
#define BUFFER_SIZE 70
#define CHUNK_SIZE 16
#define base_addr 0x00007210U
//
// Main
//
char txmsg[] = "$GNRMC,123456.00,A,3751.65,N,12225.55,W,0.00,180.00,230920,0.00,E,D";
char rxmsg[BUFFER_SIZE];
char *pos;
volatile uint32_t currentPos = 0;
int check = 0;
volatile uint16_t scitxcount = 0;
volatile uint16_t scirxcount = 0;
volatile uint16_t timerinterruptfreq = 0;
volatile uint32_t scirxlvl;
void buffercntl(char data);
void INT_SCI0_RX_ISR(void);
void INT_SCI0_TX_ISR(void);
void error(void);
void INT_myCPUTIMER0_ISR(void);
//void buffercntl(char data){
// uint32_t nexthead = (head+16)%BUFFER_SIZE;
// if (nexthead != tail) {
// rxmsg[msg] = data;
// head = nexthead;
// }
//}
__interrupt void INT_SCI0_RX_ISR(void){
uint32_t rxintstat = SCI_getInterruptStatus(SCI0_BASE);
switch(rxintstat){
case SCI_INT_PE:
SCI_writeCharNonBlocking(SCI1_BASE, 'P');
error();
break;
case SCI_INT_OE:
SCI_writeCharNonBlocking(SCI1_BASE, 'O');
error();
break;
case SCI_INT_FE:
SCI_writeCharNonBlocking(SCI1_BASE, 'F');
error();
break;
case SCI_INT_RXERR:
SCI_writeCharNonBlocking(SCI1_BASE, 'R');
error();
break;
default:
//error();
break;
}
//
// received data handling
//
//
uint16_t bytesToRead = CHUNK_SIZE;
if (currentPos + bytesToRead > BUFFER_SIZE) {
bytesToRead = BUFFER_SIZE - currentPos;
}
SCI_readCharArray(SCI0_BASE, (uint16_t*)&rxmsg[currentPos], bytesToRead);
currentPos += bytesToRead;
scirxlvl = (SCI_RxFIFOLevel)(HWREGH(base_addr + SCI_O_FFRX) & SCI_FFRX_RXFFST_M) >> SCI_FFRX_RXFFST_S;
if((BUFFER_SIZE-currentPos)< CHUNK_SIZE){
while(scirxlvl){
rxmsg[currentPos++] = SCI_readCharNonBlocking(SCI0_BASE);
check++;
}
}
if (currentPos >= BUFFER_SIZE) {
// SCI_writeCharArray(SCI1_BASE, (uint16_t*)rxmsg, sizeof(rxmsg));
currentPos = 0; // Reset position
}
scirxcount++;
GPIO_togglePin(myLED1_GPIO);
//overflow condition check?
SCI_clearOverflowStatus(SCI0_BASE);
SCI_clearInterruptStatus(SCI0_BASE, SCI_INT_RXFF);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
__interrupt void INT_SCI0_TX_ISR(void){
GPIO_togglePin(myLED0_GPIO);
scitxcount++;
SCI_clearInterruptStatus(SCI0_BASE, SCI_INT_TXFF);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
__interrupt void INT_myCPUTIMER0_ISR(void){ //cpu timer to simulate data transmission every 1 second
timerinterruptfreq++;
SCI_writeCharArray(SCI1_BASE,(uint16_t*)txmsg,sizeof(txmsg));
Interrupt_clearACKGroup(INT_myCPUTIMER0_INTERRUPT_ACK_GROUP);
}
void error(void)
{
asm(" ESTOP0"); // Test failed
for (;;);
}
void main(void)
{
//
// Initialize device clock and peripherals
//
Device_init();
//
// Disable pin locks and enable internal pull-ups.
//
Device_initGPIO();
//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();
//
// PinMux and Peripheral Initialization
//
Board_init();
//
// C2000Ware Library initialization
//
C2000Ware_libraries_init();
//
// Enable Global Interrupt (INTM) and real time interrupt (DBGM)
//
EINT;
ERTM;
//SCI_writeCharArray(SCI0_BASE,(uint16_t*)txmsg,sizeof(txmsg));
while(1)
{
scirxlvl = SCI_getRxFIFOStatus(SCI0_BASE);
// sprintf(pos,"%d",(int)currentPos);
// SCI_writeCharBlockingNonFIFO(SCI1_BASE,(uint16_t)*pos);
// sprintf(buff,"%d",)
// SCI_writeCharNonBlocking(SCI1_BASE, scitxlvl);
// SCI_writeCharNonBlocking(SCI1_BASE, scirxlvl);
}
}
//
// End of File
//

如何以最佳方式实施此应用、从而以全双工方式发送和接收数据并仍然保持可靠且一致的数据。
这项工作仍在拟订之中、因此欢迎提出任何建议。
提前感谢您
Ashwin Bhaskar A.