文章目录
前言
随开发板带的教程并没有给出SCI FIFO中断串口通信的例程。
通过对顾卫钢老师《手把手教你学DSP——基于TMS320X281x》的源码和TI给出的其他类似源码,结合调试开发板,正式看懂SCI FIFO。
特此记录,加深印象~
1 SCIA FIFO 串口通信配置步骤
1.1 使能SCIA外设时钟
EALLOW;
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
EDIS;
1.2 初始化SCIA对应GPIO
void InitSciaGpio()
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled disabled by the user.
// This will enable the pullups for the specified pins.
GpioCtrlRegs.GPBPUD.bit.GPIO36 = 0; // Enable pull-up for GPIO36 (SCIRXDA)
GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0; // Enable pull-up for GPIO35 (SCITXDA)
/* Set qualification for selected pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.
GpioCtrlRegs.GPBQSEL1.bit.GPIO36 = 3; // Asynch input GPIO28 (SCIRXDA)
/* Configure SCI-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SCI functional pins.
GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 1; // Configure GPIO36 for SCIRXDA operation
GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 1; // Configure GPIO35 for SCITXDA operation
EDIS;
}
1.3 SCI工作方式
1.3.1 数据格式
// 1位停止位,奇极性,无奇偶校验,无回送测试,空闲地址模式,8位字符
ScibRegs.SCICCR.bit.STOPBITS = 0;//0-One stop bit; 1-Two stop bits
SciaRegs.SCICCR.bit.PARITY = 0;//0-Odd parity; 1-Even parity
SciaRegs.SCICCR.bit.PARITYENA = 0;//0-Parity disable; 1-Parity enable
SciaRegs.SCICCR.bit.LOOPBKENA = 0;//0-loopback disable; 1-loopback enable
SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;//0-idle-line; 1-address-bit
SciaRegs.SCICCR.bit.SCICHAR = 0x7;//character length = 8
// SCIA发送使能,接收使能
SciaRegs.SCICTL1.bit.TXENA = 1;
SciaRegs.SCICTL1.bit.RXENA = 1;
1.3.2 波特率
unsigned char scihbaud=0;
unsigned char scilbaud=0;
Uint16 scibaud=0;
scibaud=37500000/(8*baud)-1;
scihbaud=scibaud>>8;
scilbaud=scibaud&0xff;
SciaRegs.SCIHBAUD =scihbaud;
SciaRegs.SCILBAUD =scilbaud;
1.3.3 FIFO寄存器配置
// SciaRegs.SCIFFTX.all=0xC028;
SciaRegs.SCIFFTX.bit.SCIRST = 1; // FIFO复位
SciaRegs.SCIFFTX.bit.SCIFFENA = 1; // 使能FIFO
//SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // 清除发送FIFO中断标志位
SciaRegs.SCIFFTX.bit.TXFFIENA = 1; // 使能发送FIFO中断
SciaRegs.SCIFFTX.bit.TXFFIL = 8; // 发送FIFO中断级别
// SciaRegs.SCIFFRX.all=0x0028;
SciaRegs.SCIFFRX.bit.RXFFIENA = 1; // 使能接收FIFO中断
SciaRegs.SCIFFRX.bit.RXFFIL = 8; // 接收FIFO中断级别
SciaRegs.SCIFFCT.all=0x00; // FIFO传送延时为0
SciaRegs.SCICTL1.bit.SWRESET=1; // 重启SCIA
SciaRegs.SCIFFTX.bit.TXFIFOXRESET=1; // 重新使能发送FIFO的操作
SciaRegs.SCIFFRX.bit.RXFIFORESET=1; // 重新使能接收FIFO的操作
2 串口发送数据函数
// Transmit a character from the SCI'
void UARTa_SendByte(int a)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0); // 发送FIFO不为空
SciaRegs.SCITXBUF=a;
}
void UARTa_SendString(char * msg)
{
int i=0;
while(msg[i] != '\0')
{
UARTa_SendByte(msg[i]);
i++;
}
}
3 ISR
注:一定要在适合的地方及时清除FIFO中断标志位,使其响应新的中断!!!
3.1 发送中断函数
注:如果清除发送中断标志位,则系统会一直发送rdataA
!
interrupt void sciaTxFifoIsr(void)
{
msg = "\n\nDSP Send: ";
UARTa_SendString(msg);
Uint16 i;
for(i=0; i< 8; i++)
{
SciaRegs.SCITXBUF=rdataA[i]; // Send data
}
//SciaRegs.SCIFFTX.bit.TXFFINTCLR=1; // Clear SCI Interrupt flag
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ACK
EINT;
}
3.2 接收中断函数
注:在此处清除发送中断标志位,使其响应新的发送中断。
interrupt void sciaRxFifoIsr(void)
{
Uint16 i;
for(i=0;i<8;i++)
{
rdataA[i]=SciaRegs.SCIRXBUF.all;
}
msg = "\n\nDSP Receive: ";
UARTa_SendString(msg);
UARTa_SendString(rdataA);
SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;
//SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag
SciaRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
}
4 MAIN
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "uart.h"
// Global variables
char sdataA[8]; // Send data for SCI-A
char rdataA[8] ={"Hi,Xiwei"}; // Received data for SCI-A
char *msg;
// ISR
interrupt void sciaTxFifoIsr(void);
interrupt void sciaRxFifoIsr(void);
void main()
{
InitSysCtrl();
// 初始化SCIA GPIO
InitSciaGpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
PieVectTable.SCITXINTA = &sciaTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
// 配置SCIA 波特率:4800
UARTa_Init(4800);
// 提示信息
msg = "Hello World!\r\n";
UARTa_SendString(msg);
msg = "You will enter a string, and the DSP will echo it back!\r\n";
UARTa_SendString(msg);
// 初始化接收数据
Uint16 i;
for(i = 0; i<8; i++)
{
sdataA[i] = 0;
}
// 使能PIE、CPU中断
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER9.bit.INTx1=1; // PIE Group 9, int1
PieCtrlRegs.PIEIER9.bit.INTx2=1; // PIE Group 9, INT2
IER |= M_INT9; // Enable CPU INT
EINT;
ERTM;
while(1)
{
}
}
5 实验分析
5.1 系统上电
首先输出提示信息。
由于rdataA
大小为8,且已被初始化为"Hi,Xiwei"
,又SciaRegs.SCIFFTX.bit.TXFFIL
也为8,直接触发DSP的发送中断。
效果如下图:
注:此时发送中断标志位未清除,不会再次触发发送中断。
5.2 DSP接收数据
由于SciaRegs.SCIFFRX.bit.RXFFIL
为8,当发送的数据达到8位后,直接触发DSP的接收中断。
显示结果符合上位机发送数据。效果如下图:
接收中断ISR末尾清除发送中断标志位后,直接触发DSP的发送中断。
注意,此时rdataA
已被修改为上位机发送的数据。该次发送中断的输出应和上一次接收中断接收到的数据相同。
再次验证如下:
总结
第41篇
不得不承认,TI的源码确实相当精简!
当没有正确的代码时,你也不知道咋改,像无头苍蝇一样;当你一旦调试出来一个可用的源码,你就会发现设计者那隐秘而又神奇的设计思路。
无源码从头敲,真的是一件折磨人的事。
可能是之前手敲千行代码,有点麻木:我现在已经有厌代码症,一句代码不想敲。
立个Flag,春节前学完DSP!
个人水平有限,有问题欢迎各位大神批评指正!
参考链接
- 顾卫钢 手把手教你学DSP——基于TMS320X281x
- DSP_28335_SCI_FIFO收发实验
https://blog.youkuaiyun.com/qq_39648250/article/details/89682188 - 28335scififo中断接收与发送
https://www.cnblogs.com/luxiaolai/p/5173927.html