DSP DTK6437、seed6437 通过指定的定标数据生成梯形波(带串口通信)

C6437通过串口通信生成指定波形、幅值、频率、相位的梯形波

综述

C6437生成梯形波,可以用C语言进行分段式的编程形成梯形波。
难点在于串口通信采用的是字符串,需要进行字符串和整数型的转换和定标数据。由于采用数据定标,输入的部分都是整数型,所以不考虑浮点数,如果有输入浮点数,则在字符串和浮点数转换过程要再加一步。

头文件部分

#include "math.h"
#include "stdio.h"
#include "evmdm6437.h"
#include "evmdm6437_uart.h"

定义数值

#define NX  1024
float temp[1024],txb[1024],c[1024];//temp临时数组,txb梯形波,c谐波
Int16  tmp,i,j,k,t,len,n;//i,j是用来计数的,t是时间,len是长度。
//k是用来给字符型浮点数计算的,计算完后k清0,再用来判断波形的正负周期。
float p;//相位
float f;//频率
float v;//幅值
float q;//谐波
float pi=3.14;
char rx[256];
int Q;//定标

主函数

void main(void) //第一个void无返回,第二个(void)空参数
{
	

	UART_Handle uart1;

	/* Initialize BSL */
	EVMDM6437_init();//函数,功能为初始化dm6437
	*(Uint32 *)0x01c40004 = 0x200000;//对32位内存映射寄存器进行操作,初始化0x01c40004地址中的值为0x200000

	/* Open Uart Handle */
	uart1 = SEEDDEC6437_UART_open(1,
		baud_9k6,//波特率
		data_w8,//每个字节有8位
		data_s1,//1个停止位
		data_p);//奇偶校验位

	/* Setup buffers */
	for (i = 0; i < 0x100; i++)//给rx数组清零
	{
		rx[i] = 0;
	}
     while(1)
     {          

          i=0;
          while(1)
          {
			while (1)
			{
				tmp = EVMDM6437_UART_rcvReady(uart1);//串口准备接受数据
				if (tmp == 1)//如果接收到数据,则tmp为1,跳出循环
					break;
			}
			EVMDM6437_UART_getChar(uart1, &rx[i]);//读取字符型数据

			while (1)
			{
				tmp = EVMDM6437_UART_xmtReady(uart1);//中断控制
				if (tmp == 1)
					break;
			}
			EVMDM6437_UART_putChar(uart1, rx[i]);//输出rx[i],且如果读到"@"符号就跳出
                        if (rx[i]=='@')
                         {
                            len=i;
                            break;
                         }
	               i++;
          }
     //输入字符串指令,例如90 50 1 5 @,表示相位为定标值90,频率为定标值50,幅值为定标值1,谐波为定标值5。因为输入的数字都是以空格隔开的,所以可以利用空格来进行每个数据的读取。
     printf("依次输入定标后的相位 频率 幅值 谐波 以@结束");
     p=0;f=0;v=0;
     i=0;
     Q=2;//Q2定标
     while(rx[i]!=' ')//当数组中的数不是空格的时候,执行运算
     {
         p=p*10+rx[i]-48;//48为字符0的ASCII码值,即字符型转换为整型
         i++;
     }//计算相位p
     i++;

     for( n=0; n < Q; n++) 
	{
	     p /= 2;
	}

     while(rx[i]!=' ')//当数组中的数不是空格的时候,执行运算
     {
         f=f*10+rx[i]-48;
         i++;
     }//计算频率f

     for( n=0; n < Q; n++) 
	{
	     f /= 2;
	}
     i++;
     //计算字符型浮点数:比如输入v=1.2,在小数点之前,v=0*10+49-48=1,在小数点之后,v=1*10+50-48=12,k=1
     //明显v变大了10倍,就要除以10,而且如果k=2,则v变大100倍,以此类推
     while(rx[i]!=' ')//当数组中的数不是空格的时候,执行运算
     {
          v=v*10+rx[i]-48;
          i++;
     }

          for( n=0; n < Q; n++) 
	{
	     v /= 2;
	}

     i++;q=0;
     while(rx[i]!=' ')
     {
          q=q*10+rx[i]-48;
          i++;
     }//计算谐波数

     for( n=0; n < Q; n++) 
	{
	     q /= 2;
	}
     printf("%e !\n", q);

     i++ ;  
    
     //到这里完成了字符型到整型数or浮点型数的转化    
     t=f/25; //t为NX个点的半周期数  以基波50hz为例,t=2,就有两个半周期组成1024个点的大周期
     for (i=0;i<t;i++) //i从0开始,意味着0/2=0 第一个半周期肯定是正的
     {
          if (i%2==0)  //i被2整除
          {
               k=1;
          }
          else k=-1;   //确定波形的正负
          for (j=NX*i/t;j<NX*(i+1)/t;j++)//在半个周期里,比如f=50时,t=2。i=0时,j=0到j=512,i=1时,j=512到1023
          {
               if ((j >= NX*i/t) && (j <= NX*i/t+NX/4/t))//&&逻辑与,&位与。t=2,i=0时。0<=j<=128
               {
                    temp[j] = 4*k*v*((j*t/1.0/NX-i));
               }
               else if ((j>NX*i/t+NX/4/t) && (j <= NX*i/t+NX*3/4/t))//t=2,i=0时。128<=j<=384
               {
                    temp[j] = k*v;
               }
               else 
               {
                    temp[j] = 4*k*v*((i+1-j*t/1.0/NX));//t=2,i=0时。384<=j<=512
               }
          }
     }
     for (i=0;i<NX;i++)
          {
               txb[i]=temp[(i+p*NX/t/180)%NX];  //移相  %是求余数
          }   //梯形波生成
	

     for (i=0;i<NX;i++)
     {
          c[i]=16*1.0*v/(pi*pi)*(1/(q*q)*sin(q*pi/4.0)*sin(q*2*pi*f*i/(1024*50)));

     }



    
	while (1)     
	{
		tmp = EVMDM6437_UART_xmtReady(uart1);
		if (tmp == 1)
		     break;
	}
	EVMDM6437_UART_putChar(uart1, '#');   //#程序结束
}

浮点数问题

如果不需要定标,则输入的可能是浮点数,比如输入的幅值为1.5V,则字符串到还原成1.5的过程如下:

//计算字符型浮点数:比如输入v=1.2,在小数点之前,v=0*10+49-48=1,在小数点之后,v=1*10+50-48=12,k=1,明显v变大了10倍,就要除以10,而且如果k=2,则v变大100倍,以此类推。
     while(rx[i]!='.')//当数组中的数不是空格的时候,执行运算
     {
          v=v*10+rx[i]-48;
          i++;
     }//幅值是浮点数,这里计算的是浮点数的整数部分
     i++;
     k=0;
     while(rx[i]!=' ')
     {
          v=v*10+rx[i]-48;
          i++;
          k++;
     }//计算浮点数的小数部分
     while(k>0)
     {
          v=v/10.0;
          k--;
     }//计算幅值v

定标问题

由于不涉及加减乘除等计算,所以程序采用的是统一定标。
这里简要说一下定标Q。

DSP处理器处理浮点数的办法之一是定标,把浮点数转化为整数。
比如Q3定标1.5,那么计算如下:
int(1.5X2^3)=12
那么定标完的数据就是12。

上一篇:STM32学习笔记(八)


下一篇:网络层协议之IPv4