转自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
}
注: 引用此法(实际给出了一般和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
}