📄 tms320vc5416与tlc16c554的接口函数.c
字号:
// 如要选择第29路port900 = 0xef, port700 = 0xff, port300 = 0xff, port200 = 0xff;
ioport UINT port200; // 通道选择
ioport UINT port300;
ioport UINT port700;
ioport UINT port900;
// 串口芯片中断标识位读取地址
// --------------------------
// INT0:写500H,D1D0 = 00,同时读取600H,D0-D8分别对应INTA1、INTB1、INTC1、INTD1、INTA3、INTB3、INTC3、INTD3;
// INT2:写500H,D1D0 = 01,同时读取A00H,D0-D8分别对应INTA2、INTB2、INTC2、INTD2、INTA4、INTB4、INTC4、INTD4;
// INT1:写500H,D1D0 = 10,同时读取600H,D0-D8分别对应INTA5、INTB5、INTC5、INTD5、INTA7、INTB7、INTC7、INTD7;
// Nmi: 写500H,D1D0 = 11,同时读取A00H,D0-D8分别对应INTA6、INTB6、INTC6、INTD6、INTA8、INTB8、INTC8、INTD8;
//
// 用通道号表示
// ------------
// INT0:写500H,D1D0 = 00,同时读取600H,D0-D8分别对应 1、 2、 3、 4、 9、10、11、12;
// INT2:写500H,D1D0 = 01,同时读取A00H,D0-D8分别对应 5、 6、 7、 8、13、14、15、16;
// INT1:写500H,D1D0 = 10,同时读取600H,D0-D8分别对应17、18、19、20、25、26、27、28;
// NMI: 写500H,D1D0 = 11,同时读取A00H,D0-D8分别对应21、22、23、24、29、30、31、32;
ioport UINT port500; // 中断标识
ioport UINT port600; // 读出8位中断状态,从而判断是那路发生了中断
ioport UINT portA00;
// 中断处理
// --------
// INT0:第一、三片串口芯片中断使用DSP的INT0, 1、 2、 3、 4、 9、10、11、12;
// INT1:第五、七片串口芯片中断使用DSP的INT1,17、18、19、20、25、26、27、28;
// INT2:第二、四片串口芯片中断使用DSP的INT2, 5、 6、 7、 8、13、14、15、16;
// Nmi: 第六、八片串口芯片中断使用DSP的NMI, 21、22、23、24、29、30、31、32;
BOOL blIntr0NeedToBeActive; // 主程序有必要启动一次INTR0;每次收到网络数据,均应置此标志,以便启动串口发送
BOOL blIntr1NeedToBeActive; // 主程序有必要启动一次INTR1;每次收到网络数据,均应置此标志,以便启动串口发送
BOOL blIntr2NeedToBeActive; // 主程序有必要启动一次INTR2;每次收到网络数据,均应置此标志,以便启动串口发送
BOOL blNmiNeedToBeActive; // 主程序有必要启动一次NMI;每次收到网络数据,均应置此标志,以便启动串口发送
// 用于INT0、INT1和INT2公用
UINT uiComNo0_1_2, uiComNoINT0_1_2, uiInterruptFlagINT0_1_2, uiMaskINT0_1_2;
// 用于NMI
UINT uiComNoNmi, uiComNoIntNmi, uiInterruptFlagNmi, uiMaskNmi;
// 由于NMI可能中断INT0、INT1和INT2,因此需要保护现场
UINT uiInINT0_1_2; // 0x0000:未在INT0、INT1或INT2服务中;0xff00、0xff01和0xff02分别标识在INT0、INT1和INT2服务中
UINT uiPort900Val; // 不选中任何串口
UINT uiPort700Val;
UINT uiPort300Val;
UINT uiPort200Val;
// 由INT0、INT1和INT2调用的串口信息接收函数
void vRecvComInforByInt0_1_2() // 因为INT0、INT1和INT2的中断级别相同,因此可以使用同一函数,而不会造成重入问题
{
UINT uiTemp, *uipRxdPtr, uiBytesCount;
//////////////
// 读取数据 //
//////////////
if (uiInterruptFlagINT0_1_2 & uiMaskINT0_1_2) // 接收或发送中断有效
{
uipRxdPtr = uiLowComRxd[uiComNoINT0_1_2] + (uiComTempRecvBytePtr[uiComNoINT0_1_2] >> 1); // 临时接收缓冲指针,以提高速度
// 检查线状态寄存器 0 D6 D5 D4 D3 D2 D1 D0
// ---------------------------------------
// D0--接收数据准备好
// D1--数据被冲出错
// D2--校验出错
// D3--数据格式出错
// D4--检出间断
// D5--发送保持寄存器空
// D6--发送移位寄存器空
uiBytesCount = 0;
uiTemp = port105; // 线路状态寄存器
while (uiTemp & 0x01) // 数据准备好否 D0
{
if (uiBytesCount ++ >= 16) break; // FIFO最大16字节,防止硬件错误导致死机!
// D1--数据被冲出错
// D2--校验出错
// D3--数据格式出错
if (uiTemp & 0x6) // D3.D2--校验出错
{
uiTemp = port100; // 接收当前字符(必须读取,否则可能导致该字符一直留在FIFO中)
uiTemp = "?";
}
else // 中断接收缓存中, 用于放下一字节的位置
uiTemp = port100 & 0xff; // 接收当前字符
if (uiComTempRecvBytePtr[uiComNoINT0_1_2] & 0x01) // 第1、3、5、7、...字节在低字节位置
{
*uipRxdPtr = (*uipRxdPtr) + uiTemp;
uipRxdPtr ++; // 整字指针加1
}
else // 第0、2、4、6、...字节在高字节位置
*uipRxdPtr = uiTemp << 8;
// 若指针位于末尾, 则指针回零,并转移数据
uiComTempRecvBytePtr[uiComNoINT0_1_2] ++;
if (uiComTempRecvBytePtr[uiComNoINT0_1_2] >= cnComTmpRecvBufByteSize) // 串口临时接收缓冲区大小
{
// 将低端RAM缓冲中的数据写入实际串口接收缓冲;
uiWriteDataExtComRxd(uiComNoINT0_1_2, uiLowComRxd[uiComNoINT0_1_2], cnComTmpRecvBufWordSize); // 准备发给网络的数据
uiComTempRecvBytePtr[uiComNoINT0_1_2] = 0;
uiComTempRecvByteUse[uiComNoINT0_1_2] = 0;
uipRxdPtr = uiLowComRxd[uiComNoINT0_1_2]; // 临时接收缓冲指针,以提高速度
}
uiTemp = port105; // 线路状态寄存器
} // 数据准备好
/*
// 中断有效,但数据未准备好;属于错误状态
if (uiBytesCount == 0)
uiTemp = port100; // 防止错误??????????????????
*/
} // 接收或发送中断有效
//////////////
// 发送数据 // 因为可能由软件启动中断发送数据,因此每次中断必须检查,而不管是否有硬件中断标志
//////////////
uiBytesCount = 0;
do
{
if (uiBytesCount ++ >= 16) break; // FIFO最大16字节,防止硬件错误导致死机!
// 是否有数据需要发送
if (uiComTempSendByteUse[uiComNoINT0_1_2] == uiComTempSendBytePtr[uiComNoINT0_1_2]) break;
uiTemp = port105; // 线路状态寄存器
if (uiTemp & 0x60) // 移位寄存器或发送寄存器空否 D6 D5
{
if (uiComTempSendByteUse[uiComNoINT0_1_2] & 0x01) // 第0、2、4、6、...字节在低字节位置
port100 = (*(uiLowComTxd[uiComNoINT0_1_2] + (uiComTempSendByteUse[uiComNoINT0_1_2] >> 1))) & 0xff; // 发送当前字节
else // 第1、3、5、7、...字节在高字节位置
port100 = (*(uiLowComTxd[uiComNoINT0_1_2] + (uiComTempSendByteUse[uiComNoINT0_1_2] >> 1))) >> 8; // 发送当前字节
// 若临时发送缓冲内容发送完毕, 则指针回零,并准备转移数据
uiComTempSendByteUse[uiComNoINT0_1_2] ++;
if (uiComTempSendByteUse[uiComNoINT0_1_2] >= uiComTempSendBytePtr[uiComNoINT0_1_2]) // 临时缓冲信息发送完毕
{
uiComTempSendBytePtr[uiComNoINT0_1_2] = 0;
break; // 每次中断仅发送临时发送缓冲中的内容
}
} // if ((uiTemp & 0x60)) // 移位寄存器或发送寄存器空否 D6 D5
else
break; // 发送寄存器不空,无法继续发送
} while(TRUE);
// 若还有数据等待发送,在上一级函数启动串口中断,以提高代码效率
if (uiComTempSendBytePtr[uiComNoINT0_1_2])
return;
else // 串口临时发送缓冲内容发送完毕,检查扩展RAM中是否有数据
{
// 从实际串口发送缓冲中读取数据到指定的低端RAM缓冲;
if (uiComRealSendWordUse[uiComNoINT0_1_2] != uiComRealSendWordPtr[uiComNoINT0_1_2]) // 实际缓冲中数据有效
{
// 从实际串口发送缓冲中读取数据到指定的低端RAM缓冲;
uiComTempSendBytePtr[uiComNoINT0_1_2] = uiReadDataExtComTxd(uiComNoINT0_1_2, uiLowComTxd[uiComNoINT0_1_2], cnComTmpSendBufWordSize); // 需要发给串口的数据
uiComTempSendBytePtr[uiComNoINT0_1_2] = uiComTempSendBytePtr[uiComNoINT0_1_2] << 1; // 字 = 2字节
}
uiComTempSendByteUse[uiComNoINT0_1_2] = 0;
}
}
// 由NMI调用的串口信息接收函数
void vRecvComInforByNMI()
{
UINT uiTemp, *uipRxdPtr, uiBytesCount;
//////////////
// 读取数据 //
//////////////
if (uiInterruptFlagNmi & uiMaskNmi) // 接收或发送中断有效
{
uipRxdPtr = uiLowComRxd[uiComNoIntNmi] + (uiComTempRecvBytePtr[uiComNoIntNmi] >> 1); // 临时接收缓冲指针,以提高速度
// 检查线状态寄存器 0 D6 D5 D4 D3 D2 D1 D0
// ---------------------------------------
// D0--接收数据准备好
// D1--数据被冲出错
// D2--校验出错
// D3--数据格式出错
// D4--检出间断
// D5--发送保持寄存器空
// D6--发送移位寄存器空
uiBytesCount = 0;
uiTemp = port105; // 线路状态寄存器
while (uiTemp & 0x01) // 数据准备好否 D0
{
if (uiBytesCount ++ >= 16) break; // FIFO最大16字节,防止硬件错误导致死机!
// D1--数据被冲出错
// D2--校验出错
// D3--数据格式出错
if (uiTemp & 0x6) // D3.D2--校验出错
{
uiTemp = port100; // 接收当前字符(必须读取,否则可能导致该字符一直留在FIFO中)
uiTemp = "?";
}
else // 中断接收缓存中, 用于放下一字节的位置
uiTemp = port100 & 0xff; // 接收当前字符
if (uiComTempRecvBytePtr[uiComNoIntNmi] & 0x01) // 第1、3、5、7、...字节在低字节位置
{
*uipRxdPtr = (*uipRxdPtr) + uiTemp;
uipRxdPtr ++; // 整字指针加1
}
else // 第0、2、4、6、...字节在高字节位置
*uipRxdPtr = uiTemp << 8;
// 若指针位于末尾, 则指针回零,并转移数据
uiComTempRecvBytePtr[uiComNoIntNmi] ++;
if (uiComTempRecvBytePtr[uiComNoIntNmi] >= cnComTmpRecvBufByteSize) // 串口临时接收缓冲区大小
{
// 将低端RAM缓冲中的数据写入实际串口接收缓冲;
uiWriteDataExtComRxd(uiComNoIntNmi, uiLowComRxd[uiComNoIntNmi], cnComTmpRecvBufWordSize); // 准备发给网络的数据
uiComTempRecvBytePtr[uiComNoIntNmi] = 0;
uiComTempRecvByteUse[uiComNoIntNmi] = 0;
uipRxdPtr = uiLowComRxd[uiComNoIntNmi]; // 临时接收缓冲指针,以提高速度
}
uiTemp = port105; // 线路状态寄存器
} // 数据准备好
/*
// 中断有效,但数据未准备好;属于错误状态
if (uiBytesCount == 0)
uiTemp = port100; // 防止错误??????????????????
*/
} // 接收或发送中断有效
//////////////
// 发送数据 // 因为可能由软件启动中断发送数据,因此每次中断必须检查,而不管是否有硬件中断标志
//////////////
uiBytesCount = 0;
do
{
if (uiBytesCount ++ >= 16) break; // FIFO最大16字节,防止硬件错误导致死机!
// 是否有数据需要发送
if (uiComTempSendByteUse[uiComNoIntNmi] == uiComTempSendBytePtr[uiComNoIntNmi]) break;
uiTemp = port105; // 线路状态寄存器
if (uiTemp & 0x60) // 移位寄存器或发送寄存器空否 D6 D5
{
if (uiComTempSendByteUse[uiComNoIntNmi] & 0x01) // 第0、2、4、6、...字节在低字节位置
port100 = (*(uiLowComTxd[uiComNoIntNmi] + (uiComTempSendByteUse[uiComNoIntNmi] >> 1))) & 0xff; // 发送当前字节
else // 第1、3、5、7、...字节在高字节位置
port100 = (*(uiLowComTxd[uiComNoIntNmi] + (uiComTempSendByteUse[uiComNoIntNmi] >> 1))) >> 8; // 发送当前字节
// 若临时发送缓冲内容发送完毕, 则指针回零,并准备转移数据
uiComTempSendByteUse[uiComNoIntNmi] ++;
if (uiComTempSendByteUse[uiComNoIntNmi] >= uiComTempSendBytePtr[uiComNoIntNmi]) // 临时缓冲信息发送完毕
{
uiComTempSendBytePtr[uiComNoIntNmi] = 0;
break; // 每次中断仅发送临时发送缓冲中的内容
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -