DSP串口通信浮点数

本文详细介绍了如何在TMS320F28335DSP上配置SCI串口,包括初始化设置、发送和接收中断的配置,以及如何发送字符串和浮点数。通过示例代码展示了如何实现浮点数的32位分拆发送,并提到了上位机VOFA的数据包尾帧要求,以确保数据正确解析。
摘要由CSDN通过智能技术生成

DSP 串口通信

DSP串口介绍

串口通信接口(SCI)是一个双线异步串行端口,即通常所说的UART。F28335有3各SCI接口模块。

通信引脚:

SCITXD:SCI发送引脚

SCIRXD:SCI接收引脚

DSP串口配置

初始化模块

void SCIa_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;
 
        //第一步. 使能 SCI 外设时钟及初始化对应 GPIO   ----------------
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // 使能SCI-A时钟
	EDIS;
        
        //SCI 的 GPIO 初始化配置,TI 已经在库文件内提供给我们了
        //使用哪个 SCI 口可通过宏定义决定,该宏定义在 DSP2833x_Device.h 头文件内已定义了,
        //使用哪个就将宏值改为 1 即可
	InitSciaGpio();//初始化串口A对应的引脚
        //------------------------------------------------------
        
    
        //第二步.SCI 工作方式及参数设置,包括数据格式、波特率、使能发送、接收功能等。
	//Initalize the SCI FIFO
	SciaRegs.SCIFFTX.all=0xE040;// FIFO功能使能、重新使能发送FIFO、清除TXFFINT标志位
	SciaRegs.SCIFFRX.all=0x204f;//重新使能接收FIFO、清除RXFFINT标志位、接收FIFO深度设置为16
	
    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; //使能TXRDY中断
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;  //使能RXRDY、BRKDT中断
	SciaRegs.SCIHBAUD    = scihbaud ;
	SciaRegs.SCILBAUD    = scilbaud ;
	//SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
	SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset,发送使能、接收使能
}

配置串口发送中断:

interrupt void sciaTx_isr()
{
	PieCtrlRegs.PIEACK.all |=M_INT9; //发起PIE应答

}

配置串口接收中断:

interrupt void sciaRx_isr()
{
	Data = sci_reconechar();
	PieCtrlRegs.PIEACK.all |= M_INT9;
}

串口发送字符串

发送单个字符

void SCIa_SendByte(int a)
{
	while (SciaRegs.SCICTL2.bit.TXRDY == 0); //等待,直到SCITXDBUF可以接收下一个数据
	SciaRegs.SCITXBUF=a;
}

发送字符串

void SCIa_SendString(char * msg)
{
	int i=1;
	SciaRegs.SCICTL2.bit.TXINTENA = 0;//关闭发送中断
	SCIa_SendByte(msg[0]);
	while(msg[i] != '\0')
	{
		SCIa_SendByte(msg[i]);
		i++;
	}
	SciaRegs.SCICTL2.bit.TXINTENA = 1;//发送完成从新开启中断
}

串口发送浮点数

浮点数发送

DSP浮点数的长度为32位因此需要把浮点数拆成4个8位的数来进行发送。

void SCI_Sendfloat(float32 my_float)
{

	int32 *ptr;

	while (SciaRegs.SCICTL2.bit.TXRDY == 0); //等待,直到SCITXDBUF可以接收下一个数据
	SciaRegs.SCICTL2.bit.TXINTENA = 0;//关闭发送中断
	ptr = & my_float;

	//先发高位再发低位
	// SciaRegs.SCITXBUF = *(ptr) >> 24 ;
	// SciaRegs.SCITXBUF = *(ptr) >> 16 ;
	// SciaRegs.SCITXBUF = *(ptr) >> 8;
	// SciaRegs.SCITXBUF = *(ptr);

	//先发低位再发高位
	SciaRegs.SCITXBUF = *(ptr);
	SciaRegs.SCITXBUF = *(ptr) >> 8;
	SciaRegs.SCITXBUF = *(ptr) >> 16 ;
	SciaRegs.SCITXBUF = *(ptr) >> 24 ;

	SciaRegs.SCICTL2.bit.TXINTENA = 1;//发送完成从新开启中断
}

上位机接收

使用的上位机是VOFA,根据VOFA的数据引擎JustFloat的要求传输浮点数需要配置数据包的尾帧。

void Send_tail(void)
{
	while (SciaRegs.SCICTL2.bit.TXRDY == 0); //等待,直到SCITXDBUF可以接收下一个数据
	SciaRegs.SCICTL2.bit.TXINTENA = 0;//关闭发送中断
	//发送数据尾帧
	SciaRegs.SCITXBUF = 0x00;
	SciaRegs.SCITXBUF = 0x00;
	SciaRegs.SCITXBUF = 0x80;
	SciaRegs.SCITXBUF = 0x7f;
	SciaRegs.SCICTL2.bit.TXINTENA = 1;//发送完成从新开启中断
}

在上位机VOFA中绘制通信波形

只需要在你传输的浮点数末尾调用Send_tail函数加上数据尾帧就可以实现数据的发送。

VOFA会以32位为一组对尾帧数据之前的数据进行拆包解析。因此每次发送的数据顺序应该保持一致。

#include "DSP28x_Project.h"
#include "epwm.h"
#include "bsp_ADC.h"
#include "bsp_sci.h"
extern Uint16 Date;
/**
 *  @brief                           主函数
 *  @parameter                  无
 *  @return_value               无
 */
void main(void)
{
    float32 Duty;
    float32 I;
    float32 V;
    int16 i;
/*第一步:初始化系统控制:*/
    InitSysCtrl(); 

/* 清除所有中断 和初始化 PIE 向量表:*/
    DINT;// 禁用CPU中断
    InitPieCtrl();// 初始化 PIE 控制寄存器到默认状态,默认状态是全部 PIE 中断被禁用和标志位被清除
    IER = 0x0000;// 禁用 CPU 中断和清除所有 CPU 中断标志位:
    IFR = 0x0000;
    InitPieVectTable();// 初始化 PIE 中断向量表
    // 中断重映射,注册中断程序入口(用户按需求添加)

	// 指定中断向量表ISR地址
	EALLOW;  
	// PieVectTable.EPWM1_INT = &epwm1_isr;
    // PieVectTable.EPWM2_INT = &epwm2_isr;

    PieVectTable.SCITXINTA = &sciaTx_isr;
    PieVectTable.SCIRXINTA = &sciaRx_isr;
	EDIS;

    /*程序烧录入28335(可选的)*/
#if RUN_TYPE==FLASH_RUN
   MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);
   InitFlash();
#endif

    // Init_Epwm1();
    // Init_Epwm2();

    // // 使能CPU中断INT3
	// IER |= M_INT3;
	// // 中断使能
	// PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //使能PIE中断EPWM1_INT
    // PieCtrlRegs.PIEIER3.bit.INTx2 = 1; //使能PIE中断EPWM2_INT


	// // 使能全局中断
	// EINT;  
	// // 使能实时中断
	// ERTM; 
    // for(;;)
    // {

    // }

    SCIa_Init(115200); //初始化波特率为9600

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;//使能PIE块
    IER |= M_INT9;//使能PIEINT9 (SCIA SCIB)
    
    PieCtrlRegs.PIEIER9.bit.INTx1 =1;//SCIA_RX_INT
    PieCtrlRegs.PIEIER9.bit.INTx2 =1;//SCIA_TX_INT

    EINT;//使能全局中断
    ERTM;
    SCIa_SendByte('L');
    SCIa_SendString("Hello\r\n");
    
    while (1)
    {
        /* code */
    	//SCIa_SendString("0.056\r\n");
        Duty = 4.98;
        V = 198.8;
        I = 0;
        
        for(i=0;i<5000;i++)
        {
            I=I+0.05;
            SCI_Sendfloat(Duty);
            SCI_Sendfloat(V);
            SCI_Sendfloat(I);
            Send_tail();
            DELAY_US(10000);
        }
       
    }
    

}

文件

串口配置.c文件

#include "bsp_sci.h"


/**
 * @brief 串口通行
 * @端口 SCITXDA---2 SCIRXDA----141
 * 
 */
/**
 * @brief 窜口初始化
 * 
 * @param baud 
 */
Uint16 Data;

void SCIa_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;
 
        //第一步. 使能 SCI 外设时钟及初始化对应 GPIO   ----------------
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // 使能SCI-A时钟
	EDIS;
        
        //SCI 的 GPIO 初始化配置,TI 已经在库文件内提供给我们了
        //使用哪个 SCI 口可通过宏定义决定,该宏定义在 DSP2833x_Device.h 头文件内已定义了,
        //使用哪个就将宏值改为 1 即可
	InitSciaGpio();//初始化串口A对应的引脚
        //------------------------------------------------------
        
    
        //第二步.SCI 工作方式及参数设置,包括数据格式、波特率、使能发送、接收功能等。
	//Initalize the SCI FIFO
	SciaRegs.SCIFFTX.all=0xE040;// FIFO功能使能、重新使能发送FIFO、清除TXFFINT标志位
	SciaRegs.SCIFFRX.all=0x204f;//重新使能接收FIFO、清除RXFFINT标志位、接收FIFO深度设置为16
	
    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; //使能TXRDY中断
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;  //使能RXRDY、BRKDT中断
	SciaRegs.SCIHBAUD    = scihbaud ;
	SciaRegs.SCILBAUD    = scilbaud ;
	//SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
	SciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset,发送使能、接收使能
}

/**
 * @brief 单数据发送
 * 
 * @param a 
 */
// Transmit a character from the SCI'
void SCIa_SendByte(int a)
{
	while (SciaRegs.SCICTL2.bit.TXRDY == 0); //等待,直到SCITXDBUF可以接收下一个数据
	SciaRegs.SCITXBUF=a;
}

/**
 * @brief 字符串发送
 * 
 * @param msg 
 */

void SCIa_SendString(char * msg)
{
	int i=1;
	SciaRegs.SCICTL2.bit.TXINTENA = 0;//关闭发送中断
	SCIa_SendByte(msg[0]);
	while(msg[i] != '\0')
	{
		SCIa_SendByte(msg[i]);
		i++;
	}
	SciaRegs.SCICTL2.bit.TXINTENA = 1;//发送完成从新开启中断
}


void SCI_Sendfloat(float32 my_float)
{

	int32 *ptr;

	while (SciaRegs.SCICTL2.bit.TXRDY == 0); //等待,直到SCITXDBUF可以接收下一个数据
	SciaRegs.SCICTL2.bit.TXINTENA = 0;//关闭发送中断
	ptr = & my_float;

	//先发高位再发低位
	// SciaRegs.SCITXBUF = *(ptr) >> 24 ;
	// SciaRegs.SCITXBUF = *(ptr) >> 16 ;
	// SciaRegs.SCITXBUF = *(ptr) >> 8;
	// SciaRegs.SCITXBUF = *(ptr);

	//先发低位再发高位
	SciaRegs.SCITXBUF = *(ptr);
	SciaRegs.SCITXBUF = *(ptr) >> 8;
	SciaRegs.SCITXBUF = *(ptr) >> 16 ;
	SciaRegs.SCITXBUF = *(ptr) >> 24 ;

	SciaRegs.SCICTL2.bit.TXINTENA = 1;//发送完成从新开启中断
}


/**
 * @brief 发送数据尾针
 * 
 */
void Send_tail(void)
{
	while (SciaRegs.SCICTL2.bit.TXRDY == 0); //等待,直到SCITXDBUF可以接收下一个数据
	SciaRegs.SCICTL2.bit.TXINTENA = 0;//关闭发送中断
	//发送数据尾帧
	SciaRegs.SCITXBUF = 0x00;
	SciaRegs.SCITXBUF = 0x00;
	SciaRegs.SCITXBUF = 0x80;
	SciaRegs.SCITXBUF = 0x7f;
	SciaRegs.SCICTL2.bit.TXINTENA = 1;//发送完成从新开启中断
}

/**
 * @brief 储存接收数据
 * @return 接收的数据
 */

Uint16 sci_reconechar (void)
{
	Uint16 date;
	date = SciaRegs.SCIRXBUF.all;
	return date;
}



/**
 * @brief 发送中断
 * 
 * @param 
 * 
 * @date 
 * 
 */
interrupt void sciaTx_isr()
{
	PieCtrlRegs.PIEACK.all |=M_INT9; //发起PIE应答

}

/**
 * @brief 接收中断
 * 
 * @return interrupt 
 */

interrupt void sciaRx_isr()
{
	Data = sci_reconechar();
	PieCtrlRegs.PIEACK.all |= M_INT9;
}



串口配置头文件.h

#ifndef _BSP_SCI_H_
#define _BSP_SCI_H_

#include "DSP28x_Project.h"

void SCIa_Init(Uint32 baud);
void SCIa_SendByte(int a);
void SCIa_SendString(char * msg);
Uint16 sci_reconechar (void);
void SCI_Sendfloat(float32 my_float);
void Send_tail(void);

interrupt void sciaTx_isr();
interrupt void sciaRx_isr();



#endif

主函数:

#include "DSP28x_Project.h"
#include "epwm.h"
#include "bsp_ADC.h"
#include "bsp_sci.h"

extern Uint16 Date;



/**
 *  @brief                           主函数
 *  @parameter                  无
 *  @return_value               无
 */
void main(void)
{
    float32 Duty;
    float32 I;
    float32 V;
    int16 i;
/*第一步:初始化系统控制:*/
    InitSysCtrl();



    

/* 清除所有中断 和初始化 PIE 向量表:*/
    DINT;// 禁用CPU中断
    InitPieCtrl();// 初始化 PIE 控制寄存器到默认状态,默认状态是全部 PIE 中断被禁用和标志位被清除
    IER = 0x0000;// 禁用 CPU 中断和清除所有 CPU 中断标志位:
    IFR = 0x0000;
    InitPieVectTable();// 初始化 PIE 中断向量表
    // 中断重映射,注册中断程序入口(用户按需求添加)

	// 指定中断向量表ISR地址
	EALLOW;  
	// PieVectTable.EPWM1_INT = &epwm1_isr;
    // PieVectTable.EPWM2_INT = &epwm2_isr;

    PieVectTable.SCITXINTA = &sciaTx_isr;
    PieVectTable.SCIRXINTA = &sciaRx_isr;
	EDIS;

    /*程序烧录入28335(可选的)*/
#if RUN_TYPE==FLASH_RUN
   MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);
   InitFlash();
#endif

    // Init_Epwm1();
    // Init_Epwm2();

    // // 使能CPU中断INT3
	// IER |= M_INT3;
	// // 中断使能
	// PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //使能PIE中断EPWM1_INT
    // PieCtrlRegs.PIEIER3.bit.INTx2 = 1; //使能PIE中断EPWM2_INT


	// // 使能全局中断
	// EINT;  
	// // 使能实时中断
	// ERTM; 
    // for(;;)
    // {

    // }

    SCIa_Init(115200); //初始化波特率为9600

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;//使能PIE块
    IER |= M_INT9;//使能PIEINT9 (SCIA SCIB)
    
    PieCtrlRegs.PIEIER9.bit.INTx1 =1;//SCIA_RX_INT
    PieCtrlRegs.PIEIER9.bit.INTx2 =1;//SCIA_TX_INT

    EINT;//使能全局中断
    ERTM;
    SCIa_SendByte('L');
    SCIa_SendString("Hello\r\n");
    

    while (1)
    {
        /* code */
    	//SCIa_SendString("0.056\r\n");
        Duty = 4.98;
        V = 198.8;
        I = 0;
        
        for(i=0;i<5000;i++)
        {
            I=I+0.05;
            SCI_Sendfloat(Duty);
            SCI_Sendfloat(V);
            SCI_Sendfloat(I);
            Send_tail();
            DELAY_US(10000);
        }
       
    }
    

}

实验波形:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tLenVRFe-1678870337480)(DSP串口通信浮点数.assets/image-20230315165137606.png)]

VOFA波形

参考文献:

TMS320F28335入门1- SCI串口_f28335 sci_Paul_Yu_Zhang的博客-CSDN博客

JustFloat | VOFA+

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值