您的位置:控制工程论坛网论坛 » 教程与手册 » DSP2812串口FIFO设置之C++程序

常青树

常青树   |   当前状态:在线

总积分:1421  2024年可用积分:0

注册时间: 2008-09-28

最后登录时间: 2012-05-30

空间 发短消息加为好友

DSP2812串口FIFO设置之C++程序

常青树  发表于 2008/10/31 7:38:55      1280 查看 0 回复  [上一主题]  [下一主题]

手机阅读

 

转自HotPower的文潭/*****************************************************
注: 引用此法(实际给出了一般和FIFO两种串口编程方法用SCI_FIFO_MODE区别)
切记是菜农倒塌的~~~
转载请注明: 雁塔菜地 HotPower@126.com  2008.5.7
*****************************************************/
1.设置
void UartObj::Init(void)
{
unsigned int i;
    for (i = 0; i < sizeof(ReceiveBuffer); i ++) {
        ReceiveBuffer = 0;
    }
    for (i = 0; i < sizeof(SendBuffer); i ++) {
        SendBuffer = 0;
    }
    ReceiveWritePtr = 0;
    ReceiveReadPtr = 0;
    ReceivePosition = 0;
    ReceiveCount = 0;
    SendWritePtr = 0;
    SendReadPtr = 0;
SendBusy = false;
State = 0;
  
EALLOW;
    GpioMuxRegs.GPFMUX.bit.SCITXDA_GPIOF4 = 1;
    GpioMuxRegs.GPFMUX.bit.SCIRXDA_GPIOF5 = 1;
EDIS;
    SciaRegs.SCICCR.all = 0x0007;   // 1 stop bit,  No loopback
                                  // No parity,8 char bits,
                                  // async mode, idle-line protocol
    SciaRegs.SCICTL1.all = 0x0003;  // enable TX, RX, internal SCICLK,
                                  // Disable RX ERR, SLEEP, TXWAKE
    SciaRegs.SCICTL2.bit.TXINTENA =1;
    SciaRegs.SCICTL2.bit.RXBKINTENA =1;
    SciaRegs.SCIHBAUD = 0x0000;
//    SciaRegs.SCILBAUD = SCI_PRD;
    SciaRegs.SCILBAUD = SCI_BAUD(CBR_38400);
#if SCI_FIFO_MODE
//    SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
    SciaRegs.SCIFFTX.all=0xE061;
    SciaRegs.SCIFFRX.all=0x2028;
#else   
    SciaRegs.SCIFFTX.all=0xA000;
    SciaRegs.SCIFFRX.all=0x201F;
#endif
    SciaRegs.SCIFFCT.all=0x00;
    SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
#if SCI_FIFO_MODE
SciaRegs.SCICTL1.bit.SWRESET = 1;
//    SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;
    SciaRegs.SCIFFRX.bit.RXFIFORESET=1;
    PieCtrlRegs.PIECRTL.bit.ENPIE = 1;   // Enable the PIE block
#endif
PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
PieCtrlRegs.PIEIER9.bit.INTx2 = 1;
/*设置中断服务程序入口地址*/
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.TXAINT = &ISRTxUart;
PieVectTable.RXAINT = &ISRRxUart;
EDIS;   // This is needed to disable write to EALLOW protected registers
/*开中断*/
IER |= M_INT9;
}

2."手动触发"发送中断
void UartObj::putchar(const char dat)
{
char ch;
    ch = dat;
    SendBuffer[SendWritePtr ++] = ch;//写入发送缓冲区(并非FIFO!!!)
    SendWritePtr &= sizeof(SendBuffer) - 1;
    if ((!SendBusy) && (dat == 0x0a))
    {
     SendBusy = true;
#if SCI_FIFO_MODE
     SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1;//.手动触发"发送中断
#else
  SciaRegs.SCITXBUF = SendBuffer[SendReadPtr ++];
  SendReadPtr &= sizeof(SendBuffer) - 1;
#endif  
    }
}

3.收发中断服务程序
interrupt void ISRTxUart(void)
{
#if SCI_FIFO_MODE//串口为FIFO中断模式
for (int i = 14 - SciaRegs.SCIFFTX.bit.TXFFST; (i > 0) && (Uart.SendWritePtr != Uart.SendReadPtr); i --)
{//最多发送14个字符,16个容易丢字符
  SciaRegs.SCITXBUF = Uart.SendBuffer[Uart.SendReadPtr ++];
  Uart.SendReadPtr &= sizeof(Uart.SendBuffer) - 1;
}
Uart.SendBusy = Uart.SendWritePtr != Uart.SendReadPtr;//判断缓冲区空
//注意下句是成功的关键!!!
SciaRegs.SCIFFTX.bit.TXFIFOXRESET = Uart.SendBusy//缓冲区非空
                                  || SciaRegs.SCIFFTX.bit.TXFFST;//FIFO非空
SciaRegs.SCIFFTX.bit.TXINTCLR = 1;
#else//串口为一般中断模式
if (Uart.SendWritePtr != Uart.SendReadPtr)//缓冲区非空允许发送
{
  SciaRegs.SCITXBUF = Uart.SendBuffer[Uart.SendReadPtr ++];
  Uart.SendReadPtr &= sizeof(Uart.SendBuffer) - 1;
}
Uart.SendBusy = Uart.SendWritePtr != Uart.SendReadPtr;//判断缓冲区空
#endif
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}

interrupt void ISRRxUart(void)
{
#if SCI_FIFO_MODE//串口为FIFO中断模式
for (int i = SciaRegs.SCIFFRX.bit.RXFIFST; i > 0; i --)
{
  Uart.ReceiveBuffer[Uart.ReceiveWritePtr ++] = SciaRegs.SCIRXBUF.all;
  Uart.ReceiveWritePtr &= sizeof(Uart.ReceiveBuffer) - 1;
}
SciaRegs.SCIFFRX.bit.RXFFOVRCLR = 1;
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;
#else//串口为一般中断模式
Uart.ReceiveBuffer[Uart.ReceiveWritePtr ++] = SciaRegs.SCIRXBUF.all;
Uart.ReceiveWritePtr &= sizeof(Uart.ReceiveBuffer) - 1;
#endif
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}
interrupt void ISRADC(void)
{
   Adc.Result[0] = AdcRegs.ADCRESULT0 >>4;
   Adc.Result[1] = AdcRegs.ADCRESULT1 >>4;
   // Reinitialize for next ADC sequence
   AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
   AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
}
1楼 0 0 回复