DSP28335与simulink进行串口中断模式通信并收发double类型数据

一、DSP28335串口中断模式通信

本程序是DSP28335中的串口程序,其原理是DSP28335接收到8个单字节(注意是8个数据,每个数据是1个字节(8bit))的数据后,触发中断;然后将每个数据加1后返回。里面我没说到的函数可以在TI官网上的例程里给出,可以下一个TI给的SCI例程,在此基础上结合我给的函数修改。

1.1、main函数

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File

#include "uart.h"

Uint16 sdataA[8];    // Send data for SCI-A
Uint16 rdataA[8];    // Received data for SCI-A

__interrupt void sciaTxFifoIsr(void);
__interrupt void sciaRxFifoIsr(void);

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{

	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

    EALLOW;	        // This is needed to write to EALLOW protected registers
    PieVectTable.SCIRXINTA = &sciaRxFifoIsr;//接收中断函数
    PieVectTable.SCITXINTA = &sciaTxFifoIsr;//发送中断函数
//    PieVectTable.SCIRXINTB = &scibRxFifoIsr;
//    PieVectTable.SCITXINTB = &scibTxFifoIsr;
    EDIS;
	UARTa_Init(4800);//设置波特率为4800


    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
    PieCtrlRegs.PIEIER9.bit.INTx1=1;     // PIE Group 9, int1,使能scia的RX中断
    PieCtrlRegs.PIEIER9.bit.INTx2=1;     // PIE Group 9, INT2,使能scia的TX中断
//    PieCtrlRegs.PIEIER9.bit.INTx3=1;     // PIE Group 9, INT3
//    PieCtrlRegs.PIEIER9.bit.INTx4=1;     // PIE Group 9, INT4
    IER = 0x100;	                     // Enable CPU INT
    EINT;

	while(1)
	{
	}
}


__interrupt void
sciaTxFifoIsr(void)
{
//这个发送中断函数只是在发送完中断后置位,使其可以重复发送,如果想不要这个函数,应该是需要设置为禁止发送中断触发(我个人理解)
    SciaRegs.SCIFFTX.bit.TXFFINTCLR=1;
    PieCtrlRegs.PIEACK.all|=0x100;      //要想在接收数据后重新发送回去,相应的发送中断必须复位,否则无法再次发送数据(中断占用)
}

//
// sciaRxFifoIsr -
//
__interrupt void
sciaRxFifoIsr(void)
{
    Uint16 i;
    for(i=0;i<8;i++)
    {
        rdataA[i]=SciaRegs.SCIRXBUF.all;	 // Read data
    }

    for(i=0; i< 8; i++)
    {
        SciaRegs.SCITXBUF=rdataA[i]+1;     //对接收到的数据+1
    }

    SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;      // Clear Overflow flag
    SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;      // Clear Interrupt flag

    PieCtrlRegs.PIEACK.all|=0x100;          // Issue PIE ack
}

1.2、UARTa_Init()函数

以下程序是我在
http://www.prechin.net/forum.phpmod=viewthread&tid=35264&extra中的DSP云盘里的资料找的,并进行了修改,主要是修改了TX和RX中断使能。输入的是波特率,对SCIA进行配置。

void UARTa_Init(Uint32 baud)
{
	unsigned char scihbaud=0;
	unsigned char scilbaud=0;
	Uint16 scibaud=0;

	scibaud=37500000/(8*baud)-1;
	scihbaud=scibaud>>8;
	scilbaud=scibaud&0xff;


	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-A
	EDIS;

	InitSciaGpio();

	//Initalize the SCI FIFO
	SciaRegs.SCIFFTX.all=0xE068;//8个int深度的发送和接收数据
	SciaRegs.SCIFFRX.all=0x2068;//反正我的理解是接收和发送深度必须相同
	SciaRegs.SCIFFCT.all=0x0;

	// Note: Clocks were turned on to the SCIA peripheral
	// in the InitSysCtrl() function
	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.all =0x0003;
	SciaRegs.SCICTL2.bit.TXINTENA =1;
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;
	SciaRegs.SCIHBAUD    =scihbaud;  // 9600 baud @LSPCLK = 37.5MHz.
	SciaRegs.SCILBAUD    =scilbaud;
//	SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
	SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset

}

剩下的函数基本都是TI库函数自带的了。

1.3、运行结果

使用了STC公司的串口调试助手进行测试,也可以用别的串口调试助手,调试步骤如下:

  • 先打开STC的串口调试助手,并打开串口
  • 通过CCS下载程序到DSP28335上(RAM或Flash),进入调试阶段
  • 通过串口调试助手收发数据,注意只有发送8个数据后才会有结果返回,因为我们设置的是8个深度的接收中断。串口收发效果
    以上就是程序运行结果了;可以看到DSP28335的串口中断已经成功运行了。

二、与simulink进行串口通讯并收发double类型数据

simulink具有强大的数据处理功能,如果我们想通过simulink与TI的DSP28335进行通信,可按如下步骤来。需要注意的是,一般的UART通信只能以ASCII码的形式发送,也就是一次发送1个字节;要想发送double类型数据需要进行一定的修改。

2.1 matlab中的模块

simulink中的串口通讯模块有Serial configuration(进行串口配置),serial send(发送数据),serial receive(接收数据)。
连接图

每个模块配置如下:
Serial Configuration
Serial Receive中的Data Size表示的是接收数据个数,这里只接收一个double类型数据,所以是1,如果接收两个,那么此处写为[1 2],可以使用一个1输入,2输出的mux模块,第一条线就会输出第一个收到的数,第二条线就会输出第二个收到的数。
在这里插入图片描述

Serial Send

2.2 DSP28335程序

首线明确一点,matlab中的double类型数据是64位的;CCS编译器中的数据最低是16位的,最高的long double类型数据是64位的,串口通信每次发送8位数据(串口发送先发送低位,再发送高位)。
本程序发送一个double数据给单片机,单片机对该数据+1后再通过串口返回。
参考https://blog.csdn.net/humanking7/article/details/80851223
定义并声明一个联合体

typedef union
{
    char           buff[4];//用于发送和接收,注意4个char长度和一个long double长度相等
    long double         number;//用于解码
}Un_sendData;//定义double联合体数据
Un_sendData trdata;

接收数据中断改进

__interrupt void
sciaRxFifoIsr(void)
{
    Uint16 i;
    for(i=0;i<8;i++)
    {
    	if(i%2==0)
        {trdata.buff[i/2]=SciaRegs.SCIRXBUF.all;}
    	else
    	{trdata.buff[i/2]|=(SciaRegs.SCIRXBUF.all<<8);}//由于SCIRXBUF是16位寄存器,对接受到的8bit数据进行移位操作,填充未补满的char高8位
    	// Read data
    }

    trdata.number+=1;//加1后输出验证

    for(i=0; i<8; i++)
    {
    	if(i%2==0)
        {SciaRegs.SCITXBUF=(trdata.buff[i/2]&0x00FF);}     // Send data
		else
		{SciaRegs.SCITXBUF=(trdata.buff[i/2]>>8);}
    }

    SciaRegs.SCIFFRX.bit.RXFFOVRCLR=1;      // Clear Overflow flag
    SciaRegs.SCIFFRX.bit.RXFFINTCLR=1;      // Clear Interrupt flag

    PieCtrlRegs.PIEACK.all|=0x100;          // Issue PIE ack
}

2.3、运行结果

运行结果
看到虽然运行比较慢,但结果是正确的。

2.4、错误提示

  1. 错误1
    错误1原因是在单片机连好之前打开了matlab。把matlab关掉,连好单片机,然后打开matlab就可以了
  2. 错误2
    在这里插入图片描述
    我个人理解由于单片机只能处理离散数据,所以需要对matlab进行相应设置,使simulink处理离散数据。
    解决方法:
    在这里插入图片描述

总结

第一次发博客,写了这么多字,点个赞吧。可以留言交流。

  • 18
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值