DSP28335 串口中断收发及FIFO使用

基于研旭28335一体板测试

#include "DSP2833x_Device.h" // DSP2833x 头文件

#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件

#include "string.h"

#include "stdio.h"

void InitLedGpio(void);

/**************************************函数声明************************************************/

void scia_echoback_init(void); //声明SCI-A工作方式和参数配置

void scia_xmit(int a); //声明发送字节的函数

void scia_msg(char *msg); //声明发送数组的函数

void SCIASend(char* buff);

void SCIARecvPoll(void);

interrupt void SCIRXINTA_ISRHandler(void);

interrupt void SCITXINTA_ISRHandler(void);

interrupt void SCIRXINTAFIFO_ISRHandler(void);

interrupt void SCITXINTAFIFO_ISRHandler(void);

/**********************************************************************************************/

static char RecvLen = 0;

static char RecvBuf[256] = {0};

static Uint16 SendLen = 0;

static char SendBuf[256] = {0};

static Uint16 RecvOvtime = 0;

/****************************************主程序******************************************************/

#define FIFO_DEPTH 4

void main(void)

{

// 初始化系统控制:

// 设置PLL, WatchDog, 使能外设时钟

// 下面这个函数可以从DSP2833x_SysCtrl.c文件中找到..

InitSysCtrl();

// 初始化串口SCI-A的GPIO

InitSciaGpio();

InitLedGpio();

// 清除所有中断初始化中断向量表:

// 禁止CPU全局中断

DINT;

// 初始化PIE中断向量表,并使其指向中断服务子程序(ISR)

// 这些中断服务子程序被放在了DSP280x_DefaultIsr.c源文件中

// 这个函数放在了DSP2833x_PieVect.c源文件里面.

InitPieCtrl();

// 禁止CPU中断和清除所有CPU中断标志

IER = 0x0000;

IFR = 0x0000;

// PIE 向量表指针指向中断服务程(ISR)完成其初始化.

// 即使在程序里不需要使用中断功能,也要对 PIE 向量表进行初始化.

// 这样做是为了避免PIE引起的错误.

InitPieVectTable();

EALLOW;

//PieVectTable.SCIRXINTA = &SCIRXINTA_ISRHandler;

//PieVectTable.SCITXINTA = &SCITXINTA_ISRHandler;

PieVectTable.SCIRXINTA = &SCIRXINTAFIFO_ISRHandler;

PieVectTable.SCITXINTA = &SCITXINTAFIFO_ISRHandler;

EDIS;

// 初始化SCI-A工作方式和参数配置

scia_echoback_init();

PieCtrlRegs.PIECTRL.bit.ENPIE = 1;

PieCtrlRegs.PIEIER9.bit.INTx1 = 1;

PieCtrlRegs.PIEIER9.bit.INTx2 = 1;

IER |= PIEACK_GROUP9;

sprintf(SendBuf,"%s","\r\n\n\nHello !\0");

scia_msg(SendBuf); //发送函数

sprintf(SendBuf,"%s","\r\nYou will get what you send after terminal send from PC comm tools\n\0"); //发送语句

scia_msg(SendBuf); //发送函数

EINT;

for(;;)

{

DELAY_US(100);

RecvOvtime++;

if(RecvOvtime > 50 && RecvLen)

{

SCIARecvPoll();//查询接收帧字节对接收深度取余的字节数

GpioDataRegs.GPADAT.bit.GPIO0 = 1;

memcpy(SendBuf,RecvBuf,RecvLen);

//SendLen = RecvLen-1;

SendLen = RecvLen;

RecvLen = 0;

//启动发送

SCIASend(SendBuf);

}

else if(RecvLen == 0)//查询接收小于接收深度的字节

{

SCIARecvPoll();

}

}

}

void InitLedGpio(void)

{

EALLOW;

GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0复用为GPIO功能

GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0设置为输出

GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // GPIO1复用为GPIO功能

GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; // GPIO1设置为输出

EDIS;

}

// Test 1,SCIA DLB, 8-bit word, baud rate 0x000F, default, 1 STOP bit, no parity

void scia_echoback_init()

{

//SCI的工作模式和参数需要用户在后面的学习中,深入的了解一个寄存器底层相关的资料了,多看看芯片手册和寄存器的意思。

//因为28335的寄存器太多了,所以在以后的学习过程中,就不会对寄存器进行详细的注释了。

SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback

// No parity,8 char bits,

// async mode, idle-line protocol

SciaRegs.SCICTL1.bit.SWRESET = 0;

SciaRegs.SCICTL1.bit.RXENA = 1;

SciaRegs.SCICTL1.bit.TXENA = 1;

SciaRegs.SCICTL2.bit.TXINTENA = 0;

SciaRegs.SCICTL2.bit.RXBKINTENA =1;

#if (CPU_FRQ_150MHZ) //波特率的配置

SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz.

SciaRegs.SCILBAUD =0x00E7;

#endif

#if (CPU_FRQ_100MHZ)

SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 20MHz.

SciaRegs.SCILBAUD =0x0044;

#endif

SciaRegs.SCICTL1.bit.SWRESET = 1; // Relinquish SCI from Reset

/*******************************************************************/

//增加FIFO功能

SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;

SciaRegs.SCIFFRX.bit.RXFIFORESET = 0;

SciaRegs.SCIFFTX.bit.SCIRST = 1;

SciaRegs.SCIFFTX.bit.SCIFFENA = 1; //发送FIFO使能

SciaRegs.SCIFFTX.bit.TXFFIL = FIFO_DEPTH; //发送FIFO深度16

SciaRegs.SCIFFRX.bit.RXFFIENA = 1; //接收FIFO使能

SciaRegs.SCIFFRX.bit.RXFFIL = FIFO_DEPTH; //接收FIFO深度16

SciaRegs.SCIFFCT.all = 0x00; //无发送延迟

SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;

SciaRegs.SCIFFRX.bit.RXFIFORESET = 1;

/*******************************************************************/

}

void scia_xmit(int a)//发送字节的函数

{

//单个发送

//while (SciaRegs.SCICTL2.bit.TXRDY == 0) {}

//SciaRegs.SCITXBUF=a;

//使用发送FIFO

while(SciaRegs.SCIFFTX.bit.TXFFST >= FIFO_DEPTH) {}

SciaRegs.SCITXBUF = a;

}

void scia_msg(char * msg)//发送数组的函数

{

int i;

i = 0;

while(msg[i] != '\0')

{

scia_xmit(msg[i]);

i++;

}

}

//先发送第一个字节然后启动串口中断处理余下的字节

void SCIASend(char* buff)

{

SciaRegs.SCICTL1.bit.TXENA = 1; //使能串口发送

//SciaRegs.SCICTL2.bit.TXINTENA = 1; //常规中断

//scia_xmit(buff[0]);

SciaRegs.SCIFFTX.bit.TXFFIENA = 1; //串口FIFO发送中断

}

//查询接收,用来接收非整深度的字节数据

void SCIARecvPoll(void)

{

while(SciaRegs.SCIFFRX.bit.RXFFST > 0)

{

RecvBuf[RecvLen++] = SciaRegs.SCIRXBUF.all&0xff;

RecvOvtime = 0;

}

}

// INT9.1

interrupt void SCIRXINTA_ISRHandler(void) // SCI-A

{

GpioDataRegs.GPADAT.all &= 0xfffffffC;

// Insert ISR Code here

if(SciaRegs.SCIRXST.bit.RXRDY == 1)

{

RecvBuf[RecvLen++] = SciaRegs.SCIRXBUF.all&0xff;

RecvOvtime = 0;

}

// To receive more interrupts from this PIE group, acknowledge this interrupt

PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;

}

interrupt void SCIRXINTAFIFO_ISRHandler(void) // SCI-A

{

GpioDataRegs.GPADAT.all &= 0xfffffffC;

while(SciaRegs.SCIFFRX.bit.RXFFST > 0)

{

RecvBuf[RecvLen++] = SciaRegs.SCIRXBUF.all&0xff;

RecvOvtime = 0;

}

SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; //清除FIFO接收中断标志

PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;

}

// INT9.2

interrupt void SCITXINTA_ISRHandler(void) // SCI-A

{

static Uint16 SendCnt = 1; //第一个字节已经发送用来触发进入发送中断

// Insert ISR Code here

if(SciaRegs.SCICTL2.bit.TXRDY == 1)

{

if(SendLen)

{

SciaRegs.SCITXBUF = SendBuf[SendCnt++];

SendLen--;

}

else

{

SendCnt = 1;

SciaRegs.SCICTL2.bit.TXINTENA = 0;

SciaRegs.SCICTL1.bit.TXENA = 0;

GpioDataRegs.GPADAT.bit.GPIO1 = 1;

}

}

// To receive more interrupts from this PIE group, acknowledge this interrupt

PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;

}

interrupt void SCITXINTAFIFO_ISRHandler(void) // SCI-A

{

static Uint16 SendCnt = 0;

// Insert ISR Code here

if(SendLen)

{

while(SciaRegs.SCIFFTX.bit.TXFFST < FIFO_DEPTH && SendLen)

{

SciaRegs.SCITXBUF = SendBuf[SendCnt++];

SendLen--;

}

}

else

{

SendCnt = 0;

SciaRegs.SCICTL2.bit.TXINTENA = 0;

SciaRegs.SCICTL1.bit.TXENA = 0;

GpioDataRegs.GPADAT.bit.GPIO1 = 1;

}

SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; //清除FIFO发送中断标志

// To receive more interrupts from this PIE group, acknowledge this interrupt

PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;

}

//===========================================================================

// No more.

//===========================================================================

相关推荐
茯苓gao33 分钟前
stm32 WDG看门狗
stm32·单片机·嵌入式硬件
小智学长 | 嵌入式1 小时前
单片机-STM32部分:8、外部中断
stm32·单片机·嵌入式硬件
weixin_399264291 小时前
STM32F4官方文档关于定时器时钟自动倍频的说明
stm32·单片机
Ronin-Lotus2 小时前
嵌入式硬件篇---CAN
单片机·嵌入式硬件·can·stm32f103rct6
走错路的程序员7 小时前
stm32测频率占空比最好的方案
stm32·单片机·嵌入式硬件
Ronin-Lotus9 小时前
嵌入式硬件篇---SPI
单片机·嵌入式硬件
白天学嵌入式9 小时前
STM32f103 标准库 零基础学习之按键点灯(不涉及中断)
stm32·单片机·学习
Ronin-Lotus10 小时前
嵌入式硬件篇---陀螺仪|PID
单片机·嵌入式硬件
小智学长 | 嵌入式10 小时前
单片机-STM32部分:12、I2C
单片机·嵌入式硬件