⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tms320vc5416与tlc16c554的接口函数.c

📁 TMS320VC5416与TL16CC554的接口函数,扩展4个高速串口。
💻 C
📖 第 1 页 / 共 3 页
字号:
//      如要选择第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 + -