This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/LAUNCXL-F2.8069万M:如何提高数学精度

Guru**** 2595770 points
Other Parts Discussed in Thread: CONTROLSUITE, SFRA

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/659786/ccs-launchxl-f28069m-how-to-increase-math-accuracy

部件号:LAUNCHTXL-F2.8069万M
主题中讨论的其他部件:controlSUITESFRA

工具/软件:Code Composer Studio

大家好,

我编写了一个程序,通过sci与PC接口通信。 SCI发送了我的launchxl一些字符,我需要将这些字符转换为整数/浮点等

仅包含math.h。

我对这些计算有一些问题。 下面的子例程由for循环调用,用于我获得的每个sci字符。 我知道它不是最好的字符数转换算法,但无论如何。 :)

int whatcomesnext = 0;
UINT16 bytecounter=0;


UINT16 sdataA[8];
UINT16 rdataA[8];

UINT32 result=0;
浮点数32;
浮点数32除法器;
浮点数32除法器; 

void stringToNumeral()
{
IF (SciaRegs.SCIRXEMU == 48)
{
whatcomesnext = 0;
}
否则IF (SciaRegs.SCIRXEMU == 49)
{
whatcomesnext = 1;
}
否则IF (SciaRegs.SCIRXEMU == 50)
{
whatcomesnext = 2;
}
否则IF (SciaRegs.SCIRXEMU == 51)
{
whatcomesnext = 3;
}
否则IF (SciaRegs.SCIRXEMU == 52)
{
whatcomesnext = 4;
}
否则IF (SciaRegs.SCIRXEMU == 53)
{
whatcomesnext = 5;
}
否则IF (SciaRegs.SCIRXEMU == 54)
{
whatcomesnext = 6;
}
否则IF (SciaRegs.SCIRXEMU == 55)
{
whatcomesnext = 7;
}
否则IF (SciaRegs.SCIRXEMU == 56)
{
whatcomesnext = 8;
}
否则IF (SciaRegs.SCIRXEMU == 57)
{
whatcomesnext = 9;
}
否则IF (SciaRegs.SCIRXEMU == 44 || SciaRegs.SCIRXEMU == 46)
{
whatcomesnext =",";
}
否则{
whatcomesnext = 0;
}


IF (SciaRegs.SCIRXEMU>10 && SciaRegs.SCIRXEMU!=32 && SciaRegs.SCIRXEMU!=13 && SciaRegs.SCIRXEMU!=44 && SciaRegs.SCIRXEMU!=46 && bytecounter <=7)
{
bytecounter=bytecounter+1;
如果(字节代入者>=1)
{
rdataA[bytecounter]=whatcomesnext;
}

}
否则,如果(SciaRegs.SCIRXEMU!=44 && SciaRegs.SCIRXEMU!=46)
{
bytecounter=0;
结果= 0;
除法=0;
}

如果(bytecounter=1)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext * 1000万;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=1亿;
}

}
否则,如果(bytecounter=2)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext *100万;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=1000万;
}

}
否则,如果(bytecounter=3)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext *10万;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=100万;
}

}
否则,如果(bytecounter=4)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
float32 value1 = whatcomesnext *100;
value=value1*100;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=10万;
}

}
否则,如果(bytecounter=5)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext *1000;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU!=44 && SciaRegs.SCIRXEMU!=46)
{
除法器=1万;
}

}
否则,如果(bytecounter=6)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext *100;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=1000;
}

}

否则,如果(bytecounter=7)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext *10;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=100;
}

}
否则,如果(bytecounter=8)
{
如果(whatcomesnext >=0 && whatcomesnext <=9)
{
值= whatcomesnext;
结果=值+结果;
}
IF (SciaRegs.SCIRXEMU=44 && SciaRegs.SCIRXEMU=46)
{
除法器=10;
}

}
} 

"值"始终正确,但"结果"不正确。 当我发送1111.1111万或2222.2222万时,没有问题。 结果正确。 但对于3333.3333万,结果变为3333.3334万。 对于9999.9999万,结果= 1亿。

所以我需要一个正确的结果,根据我的结果,我将除以另一个值。 (33,25或7.7358万 等。一些浮点参数值)

我认为math.h是不够的。 我读过CLA和IQmath,但不能正确使用它们。 您有什么建议来提高计算精度?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    3.33333333亿"4":)4怎么做?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    UINT16 sdataA[8];
    UINT16 rdataA[8];
    
    UINT32 result=0;
    float32 floatResult;
    UINT32 value;
    UINT32分禾器;
    浮式32分禾器; 

    转换为UINT32解决了我的问题。 但现在我有了这个:

    FloatResult =结果;
    Division = floatResult/diver;//调用FS$DIV 

    我需要将UINT32转换为Float32。  

    但结果和浮点Result却不同了。 有什么建议?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    John,

    我想你是以一种相当困难的方式来处理这个问题的,如果你真的只是想传输浮点数据,SCI并不在乎这些是位是否有浮点或固定数据,你真的不需要做你正在做的事情。

    例如,我可以向您指出我们与PC通信并具有浮点数据的例程。

    C:\ti\controlSUITE\libs\app_libs\sfra\v1_10_00_00\gui

    很遗憾,我没有相关文档,您需要花一些时间来理解代码。 但是我想说的一点是通信协议不在乎它们是浮动数据还是固定数据,它们是位,你不必像char那样将东西都当作字符来解释它们...这样设计数据包会更有效率 您可以容纳32位数据,然后根据数据包使用解码,无论数据包是浮点还是固定的。

    现在回答您的特定问题:

    C2000 MCU上的浮点表示为32位,因此您看到的某些轮组错误可能会出现在如此大的数字上。

    我对你得到的浮点结果并不感到惊讶...你必须切换到64位浮点,但是从int到float的转换也不是很精确...虽然小数点中的误差可能更低...

    下面是一个很好的参考指南

    www.ti.com/.../spraan9a.pdf
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨,Manish,

    您是SFRA示例的作者。 我现在是您的忠实粉丝! :D

    //===========================================================================================================================================
    //===========================================================================================================================================
    //
    //文件:	SciCommsGui.c
    ////
    标题:	GP Comms内核作为外部GUI的接口
    ////
    版本:2009年4月22日- Release 1.2 -内部发行版(BRL)
    //===================================================================================================================================================
    //===========================================================================================================================================
    #include <stdint.h>
    #ifdef F28x_device
    #include "F28x_Project.h"
    #include
    "DSP28x_Project.h"
    #endif
    
    #define	PktSize				6
    #define	Cmd16			
    #define_CMD_NUM				8
    
    
    //命令接收状态机的函数原型
    //-------
    void GetCmdByte (void);
    void EchoCmdByte (void);
    void GetSizeByte (void);
    void EchoSizeByte (void);
    void GetDataByte (void);
    void EchoDataByte (void);
    void PackWord (void);
    void
    CmdInterpreter (void);
    
    //命令解释器和调度器的函数原型
    //--------------------------------------------------
    void LifePulseTsk(void);		// 0
    void TextSet(void);				// 1
    void ButtonSet(void);			// 2
    void SliderSet(void);			// 3
    void VariableSet(void);			// 4
    void ArraySet(void);			// 5
    DataSet(void);				// 6 void DataSet32;
    			
    Spoid; 			
    
    
    
    
    			//命令数据包接收
    void (*CmdDispatcher[CmdNumber])的状态指针(void);	//函数指针数的数组(即任务)
    
    extern Int16_t *varSetTxtList[];
    extern Int16_t *varSetBtnList[];
    extern 16_t *varSetSledList[];GetInt
    16[_Intraht]
    
    extern Int16_t *dataGetList[];
    extern UINT32_t *dataSetList[];
    
    extern Int16_t CommsOKflg,SerialCommsTimer;
    
    uint16_t	LowByteFlag, SendTaskPtr;
    uint16_t	RxChar,RxWord;
    uint16_t	Cmdlbp[PktSize];
    uint16_t	TaskDoneFlag, NumWords,wordsLeftToGet;
    
    uint16_t dataOut16;
    Int32_t dataOut32;
    
    Int16_t *memDataPtr16;
    Int32_t *memDataPtr32;
    
    Int16_t RcvTskPtrShdw;	//用于调试
    
    Int16_t	delayer;
    
    Int16_t	MemGetPtr;
    UINT32_t	GetMemAddress;
    Int16_t	MemGetAmount;
    
    Int16_t MemSetPtr;
    UINT32_t MemSetValue;
    
    UINT32_t Temp;
    
    
    void SCIA_Init(long SCI_VBUS_clockrate, long SCI_BAUDRATE)
    {//
    注意:假定在InitSysCtrl()//中打开了到SCIA的时钟
    。注意:假定SCCR的GPIO引脚配置为主要功能
    
    	Int16_t j =0;
    
    	SciaRegs /0x0001
    //无奇偶校验,8个字符位,
    //异步模式,空闲行协议
    	SciaRegs.SCICTL1.all =0x0003;//启用TX,RX,内部SCICLK,
    //禁用RX ERR,睡眠,TXWAKE
    	SciaRegs.SCICT2.ALL =0x0003;
    	SciaRegs.SCICT2.bit.TXINTENA =0;
    	SciaRegs.SCICTL2.bit.RXKINTENA =0;
    SciaRegs.SCIHBAUD =0x0000;
    
    	SciaRegs.SCILBAUD =(SCI_VBUS_clockrate_(8*SCI_BAUDRATE))-1;//0x0020;			// 20h = 57.6Kbaud @ LSPCLK = 60/4MHz
    
    	SciaRegs.SCICTL1.ALL =0x0023;		//放弃重置
    
    //SciaRegs.SCIFFTX.all=0xE040;		//启用FIFO增强
    SciaRegs.SCIFFTX.all=0x8040;		//禁用FIFO增强
    SciaRegs.SCIFFRX.all=0x204f;
    SciaRegs.SCIFFCT.All=0x0;
    SciaRegs.SCIPRI.bit.soft=0x0;
    SciaRegs.scipri.bit.free = 0x1;
    
    	RcvTaskPointer =&GetCmdlbyte;			//初始化CmdPacket Rcv处理程序状态机PTR
    	RcvTskPtrShdw = 1;						//调试
    	SendTaskPtr = 0;						//初始化到第一状态
    	LowByteFlag = 1;						//开始数据SB = 0;*Outtr16 =数据封装期间
    
    	
    	
    
    	
    	的数据= 0;
    
    	RcvTskPtrShdw = 0; 	//对于debug
    
    	delayer =0;
    
    	MemGetPtr =0;
    	MemGetAddress =0x0万;
    	MemGetAmount =0;
    
    	MemSetPtr =0;
    	MemSetValue = 0x0万;
    
    	//清除命令数据包
    	(j=0;j<PktSize;j++)
    	{
    		CmdPacket[j]= 0x0;
    	}
    
    	j=0;
    	
    //初始化所有调度任务
    	CmdDispatcher[0]= LifePulseTsk;
    	CmdDispatcher[1]=文本集;
    	CmdDispatcher[2]= ButtonSet;
    	CmdDispatcher[3]= SliderSet;
    	CmdDispatcher[4]= VariableGet;
    	CmdDispatcher[5]= ArrayGet;
    	CmdDispatcher[6]= DataGet;
    	CmdDispatcher[7]= DataSet32;
    	CmdDispatcher[8]= SpareTsk08
    
    ;}
    
    //===================================================================================================================
    //主机命令接收和调度状态计算机
    //===========================================
    
    //========= SM入口点===================
    void SerialHostComms()
    {(*RcvTaskPointer)();//		
    		通过状态指针指向的调用例程
    }//=========================
    
    
    void GetCmdByte(void)//任务1
    {
    	IF (CiaRegs.SCIRXST.bit.RXRDY ==1)	//检查是否已接收到char
    	{
    		RxChar = SciaRegs.SCIRXBUF.all;
    		RcvTaskPointer =&EchoCmdTskByte;//		指向下一状态
    		SerialsTimer = Cmd2;
    						
    		<=调试Cd2</md2by>
    	
    
    	否则,如果(SiaRegs.SCIRXST.bit.BRKDT ==1|| SerialCommsTimer >2500)//~2 s超时
    	{//	
    	如果检测到中断或串行端口超时,当
    		代码使用仿真器
    		SciaRegs.SCICCR.ALL =0x0007;//		运行时,某些串行端口需要重置SCI //---
    			//无奇偶校验,8个字符位,
    			//异步模式,空闲行协议
    		SciaRegs.SCICTL1.all =0x0003;		//启用TX,RX,内部SCICLK,
    			//禁用RX ERR,睡眠,TXWAKE
    		SciaRegs.SCICT2.all =0x0000;
    
    		SciaRegs.SCICTL1.all =0x0023;		//从重置放弃SCI
    
    		asm (" RPT#8 || NOP");
    		//--
    
    		SendTaskPtr = 0;					//初始化到第一状态	
    		SerialCommsTimer = 0;
    								
    		CommsOKflg =0;
    		RcvTaskPointer =&GetCmdByte;		//返回并等待新的CMD
    	}
    }
    
    作废EchoCmdByte(void)//任务2
    {
    IF (SciaRegs.SCICTL2.bit.TXRDY == 1)		// TXBUF是否为空?,即TXRDY =1
    {
    	SciaRegs.SCITXBUF=RxChar;			//如果是,回显收到的char
    	CmdPacket[0]= RxChar;
    		RcvTaskPointer =&GetSizeByte;
    		//RcvTskPtrShdw = 3;					// debug
    		//RcvTaskPointer =&GetCmdByte;		//简单回显测试
    		SerialCommsTimer =0的取消注释; 						//重置超时计时器
    	}
    
    void
    
    GetSizeByte(void)//任务3
    {
    	IF (CiaRegs.SCIRXST.Bit.RXRDY ==1)	//检查是否已收到char
    	{
    		RxChar = SciaRegs.SCIRXBUF.ALL;
    
    		RcvTaskPointer =&EchoSizestate;		//
    		回					声字节=4;
    		
    	//回声状态=//
    
    	否则,如果(SerialCommsTimer >1000)		// 1000*1ms = 1.0 sec timeout
    	{
    		CommsOKflg =0;
    		RcvTaskPointer =&GetCmdByte;//		中止,返回等待新的CMD
    		SerialCommsTimer =0;
    	}
    
    
    } void EchoSizeByte(void)//任务4
    {
    IF (SciaRegs.SCICTL2.bit.TXRDY == 1)		// TXBUF是否为空?,即TXRDY =1
    {
    	SciaRegs.SCITXBUF=RxChar;			//如果是,回显收到的char
    	CmdPacket[1]= RxChar;
    		RcvTaskPointer =&GetDataByte;
    		//RcvTskPtrShdw =5;				// debug
    		//RcvTaskPointer =&GetCmdByte;		//取消测试
    		SerialCommsTimer的注释				
    = 0;//重置超时计时器}
    }
    
    void GetDataByte(void)//任务5
    {
    	IF (CiaRegs.SCIRXST.bit.RXRDY ==1)	//检查是否已接收到char
    	{
    		RxChar = SciaRegs.SCIRXBUF.all;
    		RcvTaskPointer =&EchoDataTskByte;		//指向下一状态
    		//RcvData6 =<=</trbybybybyby> 				
    						
    	
    
    	否则,如果(SerialCommsTimer >500)		// 1000*1ms = 1秒超时
    	{
    		CommsOKflg =0;
    		RcvTaskPointer =&GetCmdByte;		//中止,返回等待新的CMD
    		SerialCommsTimer =0;
    	}
    	
    
    
    } void EchoDataByte(void)//任务6
    {
    IF (SciaRegs.SCICTL2.bit.TXRDY == 1)		// TXBUF是否为空?,即TXRDY =1
    {
    	SciaRegs.SCITXBUF=RxChar;			//如果是,回显收到的char
    		RcvTaskPointer =&PackWord;
    		//RcvTskPtrShdw =7;				// debug
    }
    }
    
    Void PackWord(void)//首先期望LSB,然后期望MSB //任务7
    {
    	IF(LowByteFlag ==1)
    	{
    		RxWord = RxChar;
    		LowByteFlag =0;
    		RcvTaskPointer =&GetDataByte;
    		//RcvTskPtrShdw =5;				// Getdebug DataByte()
    		;
    	}
    	否则
    	{
    		RxWord = RxWord |(RxChar<8);
    		LowByteFlag = 1;
    		CmdPacket[2]= RxWord;				//在数据包
    		中存储数据RcvTaskPointer =&CmdInterpreter;
    		//RcvTskPtrShdw = 8;				// debug
    		TaskDoneFlag =0; 					//指示正在执行的新任务	
    	}
    
    
    void CmdInterpreter(void)//任务8
    {
    	IF (TaskDoneFlag ==0)
    	{
    		(*CmdDispatcher[ CmdPacket[0]])))();	//调度任务					
    	}//
    
    	如果
    	(SerialCommsTimer >2500)实例任务从未完成			// 2500*1ms = 2.5 秒超时
    	{ CmdintersOKvPool=CmdPo0;
    		
    				//中止,返回等待新的CMD
    		SerialCommsTimer =0;
    	}
    	如果(TaskDoneFlag ==1)
    	{
    		RcvTaskPointer =&GetCmdByte;//RcvTskPtrShdw
    		=1;				//调试
    	}}//===========================================================================================
    
    
    
    //主机命令的从属任务
    //===================================================
    void LifePulseTsk(void)	// CmdPacket[0]= 0
    {
    	IF (CmdPacket[2]=0x0000 && CmdPacket[1]=0x00)//LED2-ON
    	{
    		#IF DSP2802x_DEVICE GPIODataRegs.GPASET.Bit.GPLE12=1
    		;		
    		#else
    		GPIOSP1=1&DataDataDataPacket
    		
    	
    	=1=0x1=12&D21_DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData=1=1=1=1=
    	
    		
    		
    		
    		
    				
    	
    	
    	
    		
    		
    		
    		
    		
    	
    
    	
    	SerialCommsTimer =0;
    	TaskDoneFlag =1;
    }//------------------
    
    void TextSet(void)// CmdPacket[0]=1
    {	
    	*varSetTxtList[CmdPacket[1]]= CmdPacket[2];
    
    	TaskDoneFlag =1;//表示任务执行已完成
    }//------------------
    
    void ButtonSet(void)	// CmdPacket[0]=2
    {
    	*varSetBtnList[CmdPacket[1]]= CmdPacket[2];
    
    	TaskDoneFlag =1;//表示任务执行已完成
    }//------------------
    
    void SliderSet(void)	// CmdPacket[0]=3
    {
    	*varSetSldrList[CmdPacket[1]]= CmdPacket[2];
    
    	TaskDoneFlag =1;//表示任务执行已完成
    }//------------------
    
    void VariableGet(void)		// CmdPacket[0]=4
    {
    	SendData();
    }//------------------
    
    //发送UINT16数组,一次发送一个元素
    void ArrayGet(void)			// CmdPacket[0]=5{
    
    	SendData();}//------------------ 	
    
    
    void DataGet(void)			// CmdPacket[0]=6
    {
    	SWITCH(MemGetPtr){
    	
    		案例0:
    			MemGetAddress = CmdPacket[2];
    			MemGetPtr =1;
    
    			wordsLeftToGet =1;
    			SendTaskPtr =1;
    			TaskDoneFlag =1;
    			中断;
    
    		案例1:
    			temp = CmdPacket[2];
    			MemGetAddress = MemGetAddress +(Temp<16);
    			MemDataPt16 =(Int16_t*) MemGetAddress;
    			dataOut16 =*memDataPtr16;
    			SendData();		
    
    			IF(TaskDoneFlag ==1)
    			{
    				MemGetPtrFlag =0;
    			
    			
    		}/}--
    
    		完成
    
    
    void DataSet32(void)		// CmdPacket[0]=7 [编辑以获取32位设置文本并使标签正常工作]
    {
    	SWITCH (MemSetPtR)
    	{
    		案例0:
    			MemSetValue = CmdPacket[2];
    			MemSetPtr =1;
    
    			TaskDoneFlag =1;
    			中断;
    
    		案例1:
    			temp = CmdPacketPacket[2];MemSetValue=<MemSetValue1;<MemSetValue=1;<MemSetValue=1<MemSetValue1;<MemSetValue=1<MemSetValue]
    			
    
    			
    
    			
    			
    			中断;
    	}
    
    }//------------------
    
    void SpareTsk08(void)		// CmdPacket[0]=8
    {
    	TaskDoneFlag =1;		//表示任务执行已完成
    }//------------------
    
    
    void SendData(void)
    {
    	IF(CmdPacket[0]== 0x04|| CmdPacket[0]== 0x06){
    		SWITCH(SendTaskPtr)
    		{
    		案例0://初始化
    
    			memDataPtr16=(Int16_t *) varGetList[CmdPacket[1];
    			dataOut16=*memDataPackets Left16; wordsNotl =(
    			
    				未插入案例1):
    
    		//发送LSB
    			if(wordsLeftToGet >0)
    			{
    				IF (SiaRegs.SCICTL2.bit.TXRDY ==1)
    				{
    					SciaRegs.SCITXBUF = dataOut16 & 0x0万FF;
    					SendPtr =2;
    				} TaskElse
    				
    				{
    					TaskDoneFlag = TaskDoneFlag;
    					Break;
    				
    			
    			Taskelse
    			{
    				SendPtr }=1; TaskElse }
    				
    				
    			
    
    		//发送MSB
    			IF (SiaRegs.SCICTL2.bit.TXRDY ==1)
    			{
    				SciaRegs.SCITXBUF =(dataOut16>8 & 0x0万FF);
    
    				memDataPtr16 = memDataPtr16 +1;
    				dataOut16 =**DataPackets
    				LeftToGet
    				
    			
    			
    		
    	
    	
    	
    		
    		
    		=(demDataOutptr16;{*32;DataOutptrp=32;}DataGet=1;DataGet1;DataGet1;DataGet1;DataGetPtr;DataGet1;DataGet1;</mdOutptr;}=32>DataGet1;DataGet1;DataGet1;DataGet1;DataGet1}=12
    		
    		
    		
    		//请注意,案例0进入案例1 (不中断)
    		案例1://发送LSB
    			IF (wordsLeftToGet > 0)
    			{
    				IF (SciaRegs.SCICTL2.bit.TXRDY ==1)
    				{
    					SciaRegs.SCITXBUF =(data32 & 0x0万FF);
    					
    				
    				
    				
    					Flag TaskTaskPtr =2; Flag TaskOut> SendPoneDelse =0;
    					
    				
    			
    			
    			{ Flag TaskDoneDtr=
    				1}
    				
    				
    			
    
    		案例2:
    			IF (SiaRegs.SCICTL2.Bit.TXRDY ==1)
    			{
    				SciaRegs.SCITXBUF =(dataOut32>8 & 0x0万FF);
    				SendTaskPtr =3;
    			}
    			ELSE
    			{
    				TaskDoneFlag = TaskDoneFlag;
    				break;
    			}
    		案例3:
    			IF (SiaRegs.SCITL2.send= 8 & 0x0万FF){
    			
    				TaskUneA=
    				DoneFlag = 1;{ SC1= D>TaskD1= D1}
    			
    			
    			
    				
    				
    			
    			//发送MSB
    			if (SiaRegs.SCICTL2.bit.TXRDY ==1)
    			{
    				SciaRegs.SCITXBUF =(dataOut32>24 & 0x0万FF);
    
    				memDataPtr32 = memDataPtr32 +1;
    				dataOut32 =*DataPtr32;
    				wordsLeftToGet = wordsSendToGet
    				
    			
    			
    		
    	= 1;}TaskPtr1 }中断
    
    
    

    SciCommsGui_32bit.c文件似乎完全能够用于sci通信,但我不能轻松理解,所以我有一些问题。

    一切都很好,直到"RxChar = SciaRegs.SCIRXBUF.all;)

    现在,我将移动 下面与接收值相关的一些代码;

    void GetDataByte(void)//任务5
    {
    	IF (SiaRegs.SCIRXST.bit.RXRDY ==1)	//检查是否已收到char
    	{
    		RxChar = SciaRegs.SCIRXBUF.all;
    		RcvTaskPointer =&EchoDataDebug		
    						
    						
    	;//指向下一个状态//RcvTskPtrbyf.f.f.all;Echbyby= Ech&sbyby&s&sbyData</ch;//
    
    	否则,如果(SerialCommsTimer >500)		// 1000*1ms = 1秒超时
    	{
    		CommsOKflg =0;
    		RcvTaskPointer =&GetCmdByte;		//中止,返回等待新的CMD
    		SerialCommsTimer =0;
    	}
    	
    
    

    void PackWord(void)//首先期望LSB,然后期望MSB //任务7
    {
    	IF(LowByteFlag ==1)
    	{
    		RxWord = RxChar;
    		LowByteFlag =0;
    		RcvTaskPointer =&GetDataByte;//RcvTskPtrShdw
    		=5;				// Getdebug DataByte()
    		;
    	}
    	否则
    	{
    		RxWord = RxWord |(RxChar<8);
    		LowByteFlag = 1;
    		CmdPacket[2]= RxWord;				//将数据存储在数据包
    		中RcvTaskPointer =&CmdInterpreter;
    		//RcvTskPtrShdw =8;				//调试
    		TaskDoneFlag =0;					//表示正在执行的新任务	
    	}
    
    

    void CmdInterpreter(void)//任务8
    {
    	IF (TaskDoneFlag == 0)
    	{
    		(*CmdDispatcher[ CmdPacket[0]]))));//	调度任务					
    	}//
    
    	如果
    	(SerialCommsTimer >2500)			// 2500*1ms = 2.5 秒超时
    	{
    		CommsOKflg =0;
    		RcvTaskPointer = 		//中止,返回等待新的CMD
    		SerialCommsTimer =0;
    	}
    	如果(TaskDoneFlag ==1)
    	{
    		RcvTaskPointer =&GetCmdByte;//RcvTskPtrShdw
    		=1;				//调试
    	}
    }
    

    void DataGet(void)			// CmdPacket[0]=6
    {
    	SWITCH(MemGetPtr){
    	
    		案例0:
    			MemGetAddress = CmdPacket[2];
    			MemGetPtr =1;
    
    			wordsLeftToGet =1;
    			SendTaskPtr =1;
    			TaskDoneFlag =1;
    			中断;
    
    		案例1:
    			temp = CmdPacket[2];
    			MemGetAddress = MemGetAddress +(Temp<16);
    			memDataPt16 =(Int16_t*) MemGetAddress;
    			dataOut16 =*memDataPtr16;
    			SendData();		
    
    			IF (TaskDoneFlag == 1)
    			{
    				MemGetPtr =0;
    			}
    			中断
    		;} 

    所以,我从一开始就开始。

    PC发送我的sci RXBUF ASCII字符(8位,最大255),如49,50,51,... (十进制1,2,3 ...)

    我是否应该先将这些字符转换为十六进制,为我的float 32或float 64缓冲区保留一个地址指针,为每个接收到的字符增加指针地址,例如,如果该地址为6字节,则定义一个64位浮点值并使用该值?

    或者上述代码已经为我执行了这些操作? 正如我所理解的,我一定要使用指针,对吗?

    对不起,“SciCommsGui_32bit”中有太多变量,让我感到困惑。 :)

    感谢你的帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    顺便说一下,当我测试“atof”函数的一些浮点值时,它也不准确。

    Converter = atof (“1.2 ”);      //(变频器显示:1.1999.9993万)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    John,我这个月都在出差,所以我想再谈一下这个话题。

    1.您引用的atof不准确也是意料之中的事,在浮点中没有精确的表示。 预计会出现一些舍入错误,并且这些错误始终存在。

    2.对于SCI通信部分,我将尝试如下解释

    该代码适用于以下变量。

    //GUI支持变量
    //设置外部GUI控件的数量限制-根据需要增加
    //16文本框控制变量
    volatile Int16_t *varSetTxtList[16];
    //16按钮控制变量
    volatile Int16_t *varSetBtnList[16];
    //16滑块控制变量
    volatile Int16_t *varSetSldrList[16];
    //16个变量可应用于GUI
    volatile Int16_t *varGetList[16];
    //16个阵列可扩展到GUI
    volatile Int32_t *arrayGetList[16];
    //16 32位文本框或标注控制变量
    volatile UINT32_t *dataSetList[16];

    我们设计的它可以与主机GUI配合使用,它可以容纳tex框,滑块,列表AD阵列。

    因为您希望将其用于通常关心的浮点数据
    //16个阵列可扩展到GUI
    volatile Int32_t *arrayGetList[16];
    //16 32位文本框或标注控制变量
    volatile UINT32_t *dataSetList[16];


    现在,作为串行主机计时器的一部分,我们总是调用SerialHostComms()

    它执行RcvTaskPointer ()指向的函数,该函数可以指向

    GetCmdByte
    EchoCmdByte;
    GetSizeByte
    EchoSizeByte
    GetDataByte
    EchoDataByte
    PackWord
    CmdInterpreter

    SCI通信进入的第一个例程是GetCmdByte

    如果收到来自主机PC的命令,则代码将在此处执行。 一旦收到此命令,MCU就会在SCI通道上回覆命令。 转到EcoCmdByte。 该命令存储在RxChar中。

    此命令用于区分我们是在交换"list variable","slider variable"还是"array"。

    根据我们为此定义的协议,下一个RxChar将包括“数据”的大小,即16位数字为2,32位数字(如float)为4。

    根据协议,我们等待此数据大小从主机传输,然后由MCU接收。 然后MCU回显该数据大小。

    一旦对传输32位浮点的请求进行了解释,我们就会到达

    其中,我们一次将32位数的8位发送到主机PC,在主机PC中,可以先将其重新构造为位。


    交换机(SendTaskPter)

    案例0://初始化
    MemDataPtr32 =(Int32_t *) arrayGetList[CmdPacket[1]];
    dataOut32 =*memDataPtr32;
    wordsLeftToGet = CmdPacket[2];
    //请注意,案例0进入案例1 (无中断)
    案例1://发送LSB
    IF (wordsLeftToGet > 0)

    如果(SCI_isTransmitterBusy(SCIA_BUS)=0)

    SCI_writeCharBlockingNonFIFO (SCIA_BASE,dataOut32和0x0万FF);
    SendTaskPtr =2;
    }
    }
    否则

    SendTaskPtr =0;
    TaskDoneFlag =1;
    中断;
    }

    案例2:
    如果(SCI_isTransmitterBusy(SCIA_BUS)=0)

    SCI_writeCharBlockingNonFIFO (SCIA_BASE,dataOut32>8和0x0万FF);
    SendTaskPtr =3;
    }

    案例3:
    IF (SCI_isTransmitterBusy (SCIA_BASE)=0)

    SCI_writeCharBlockingNonFIFO (SCIA_BASE,dataOut32>16和0x0万FF);
    SendTaskPtr =4;
    }

    案例4: //发送MSB
    IF (SCI_isTransmitterBusy (SCIA_BASE)=0)

    SCI_writeCharBlockingNonFIFO (SCIA_BASE,dataOut32>24和0x0万FF);

    MemDataPtr32 = memDataPtr32 + 1;
    dataOut32 =*memDataPtr32;
    wordsLeftToGet = wordsLeftToGet -1;
    SendTaskPtr =1;
    }
    中断;



    是的,您必须使用指针来完成所有这些操作。