DSP相关笔记_6:LaunchXL-F28379D的简单教程系列(四)SCI简单使用_2
注:
1)这是本人关于Ti的C2000系列的学习笔记,所用工具有官方的开发软件CCS10版本,帮助文库以及函数库软件controlSUITE。硬件部分LaunchXL-F28379D和逻辑分析仪一台。
2)DSP相关笔记_5:LaunchXL-F28379D的简单教程系列(四)SCI简单使用_1
接着上次的说,上次我们简单的实现了SCI的TX功能,就是发数据,但是没有实现RX的功能,原因是因为通过查询的方法,来实现接收数据不常用。
所以这一章我们利用中断的方法来实现,中断其实不用怕,我前面讲过,这里也会再次简单阐述一下。
中断的实现流程,1)配置中断相关的寄存器和标志位,2)开启对应设备的中断使能,3)通过中断缘查找PIE中断,配置中断管理器PIE,4)配置对应中断函数。
1)配置中断相关的寄存器和标志位
其实这个我们之前一直都在做就是以下代码:
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
对中断初始化,以及相应标准的初始化和中断向量表的初始化。
2)开启对应设备的中断使能,
3)通过中断缘查找PIE中断,配置中断管理器PIE,
4)配置对应中断函数。
首先我们要什么中断?当然是RX相关的中断,这里我们只会使用简单的RX的中断,不会使用带FIFO的中断。
我们可以看到1号位,RXBKINTEN这是我们需要使用的一个中断,它产生中断会根据两个标志,一个RXEDY接收准备,一个BRKDT中断检测,他们是对应一个中断源SCIA_RX.
通过查PIE表我们可以知道SCIA_RX是第九组中的第一个频道。
将这些操作写成一个函数,如下代码:
void SciInterruptInitial(void)
{
//开启SCI_RX接收中断:
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;
EALLOW;
PieVectTable.SCIA_RX_INT = &SCI_A_SR;//更换中断向量表的中断函数,也可以在默认的中填写
EDIS;
IER |= PIEACK_GROUP9;//这里需要把第九组的中断使能,这是官方函数对应的宏定义
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;//开启PIE
PieCtrlRegs.PIEIER9.bit.INTx1 = 1;//开启第九组第一频道
}
//中断函数
interrupt void SCI_A_SR(void)
{
//读取RXBUF的数据
Uint16 ReceivedChar = SciaRegs.SCIRXBUF.all;
//并向上位机返回读到的数据
SciWrite(ReceivedChar);
//说明中断相应完毕,这个必须要之前也说了的,手册中说过,官方库函数也有说。
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
再做完上面以后基本就实现了,RX中断的配置,可以通过中断的方式完成接收数据,不过需要把中断配置函数放在SCI初始化函数中。
void SciInitial(void)
{
SciGpioInitial();
SciInterruptInitial();//将中断配置函数添加
SciaRegs.SCICTL1.all = 0x0003;
SciaRegs.SCICCR.all = 0x0007;
SciaRegs.SCIHBAUD.all = 0x0000;
SciaRegs.SCILBAUD.all = 0x0036;
SciaRegs.SCICTL1.all = 0x0023;
}
测试环节:
测试内容,今天是2021年正月十五,元宵节,就送歌(网上搜的)给大家,通过上位机发送歌的内容,LAUNCHXL接收歌词,并返回诗歌给上位机。
测试结果,如下图
完整代码:
#include "F28x_Project.h"
//为了方便,我把所有函数先声明了,后面是定义。
interrupt void SCI_A_SR(void);
void SciGpioInitial (void);
void SciInterruptInitial(void);
void SciInitial(void);
void SciWrite(Uint16 a);
void main(void)
{
InitSysCtrl();
InitGpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
SciInitial();
EINT;
SciWrite(0x33);
for(;;)
{
}
}
interrupt void SCI_A_SR(void)
{
Uint16 ReceivedChar = SciaRegs.SCIRXBUF.all;
SciWrite(ReceivedChar);
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
void SciGpioInitial(void)
{
//GPIO8->SCITXDA output
GPIO_SetupPinMux(8, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(8, GPIO_OUTPUT, GPIO_PUSHPULL);
//GPIO9->SCITXRX input
GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(9, GPIO_INPUT, GPIO_ASYNC);
}
void SciInterruptInitial(void)
{
//开启接收中断:
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;
EALLOW;
PieVectTable.SCIA_RX_INT = &SCI_A_SR;
EDIS;
IER |= PIEACK_GROUP9;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
}
void SciInitial(void)
{
SciGpioInitial();
SciInterruptInitial();
SciaRegs.SCICTL1.all = 0x0003;
//SciaRegs.SCICCR.bit.STOPBITS = 0; //0:一个停止位;1:两个停止位
//SciaRegs.SCICCR.bit.PARITYENA = 0;//不启动校验位
//SciaRegs.SCICCR.bit.SCICHAR = 0x7;//0x0-0x7对应 一位数据位->八位数据位
//上面三句相当于
SciaRegs.SCICCR.all = 0x0007;
SciaRegs.SCIHBAUD.all = 0x0000;
SciaRegs.SCILBAUD.all = 0x0036;
SciaRegs.SCICTL1.all = 0x0023;
}
void SciWrite(Uint16 a)
{
while (SciaRegs.SCICTL2.bit.TXRDY != 1) {}
SciaRegs.SCITXBUF.all =a;
}
总结:基本就把SCI简单的用法讲了,关于FIFO那部分可能先把其他的数据传输外设讲了,最后一期来慢慢补充。如果文章有什么错误希望大家及时指出,互相学习,互相进步。
参考资料:
[1] TMS320F2837XD Dual-Core Microcontollers Technical Reference Manual