一、实物展示及部分制造流程展示:
嘉立创开源社区开源连接:基于CW32的多功能函数信号发生器设计
实物展示链接:演示视频
二、详细功能说明
本设计以CW32F030系列单片机为系统控制核心,以AD9910模块作为波形生成系统,HMI4.3寸触摸屏作为人机交互接口,用于设定相关参数,W25Q64作为数据存储设备,以简单的外围电路结构,设计一款多功能函数信号发生器,基本功能GUI界面如图所示。
项目基本功能包含:
1.1-420MHz正弦波输出.
2.3.7-244Khz三角波输出.
3.3.7-244Khz方波输出.
4.其他常见波输出(其他常见14种波形输出).
5.单频调制可进行以下功能选择
(1)AM调制.
(2)PM调制.
(3)FM调制.
(4)2ASK.
(5)2PSK.
(6)2FSK.
6.扫描功能可进行以下功能选择
(1)扫频.
(2)扫幅.
(3)扫相.
7.谐波调制可选择以下功能选择
(1)FM.
(2)AM.
(3)PM.
8.跳频(该功能暂未实现)
8.其他(拓展功能).
详细功能说明:
1.正弦波输出模式:在正弦波输出模式下,频率、幅度、相位通过HMI触摸屏可调,频率范围:1Hz-450MHz,步进1Hz,幅度0-100%可调,步进1%,相位0-360度可调,步进1度。GUI界面如下图所示.
2. 三角波输出模式:在三角波模式下,频率、宽度可调,频率步进1Hz,最大244KHz,在三角波输出模式下提供两种波形输出模式.
1.连续双向扫描:播放完一个波形后,波形倒放.
2.连续循环扫描:连续播放一个波形
GUI界面如图所示
3.方波输出模式:在方波输出模式下波形宽度、频率可调,宽度步进5%,频率步进1Hz。
GUI界面如图所示
4.其他波形输出模式:输出波形有以下14种常见的波形进行选择:
(1)斩波.
(2)全波.
(3)半波.
(4)对数.
(5)削顶正弦.
(6)辛格函数.
(7)衰减震荡.
(8)削顶三角.
(9)正指数.
(10)负指数.
(11)正阶梯.
(12)负阶梯.
(13)洛伦兹.
(14)高斯.
选择GUI界面如图所示
在此模式下,波形频率可调,波形输出模式可调。提供两种波形输出模式
1.连续双向扫描
2.连续循环扫描
对应波形输出界面如图所示
通过点击输出波形按钮,可按照顺序切换1种波形输出。
通过点击确认可进行波形输出,在确认点击按键按下后,再次按下可变为取消按键,取消波形输出.返回按键按下,返回上一级菜单.
4.单频调制GUI如下图所示
4.单频调制模式下提供
(1)FM调制:
界面GUI如下图所示
在此模式下可设定FM调制的以下参数:
1.起始频率.
2.终止频率.
3.步进频率.
4.波形幅度.
5.波形相位.
(2)AM调制
GUI如下图所示
在此模式下可设定AM调制的以下参数:
1.起始幅度.
2.终止幅度.
3.步进幅度.
4.波形频率.
5.波形相位.
(3)PM调制
GUI如下图所示
在此模式下可设定PM调制的以下参数:
1.起始相位.
2.终止相位.
3.步进相位.
4.波形频率.
5.波形幅度.
(4)2FSK调制
GUI如下图所示
在此模式下可设定2FSK调制的以下参数:
1.起始频率.
2.终止频率.
3.起始频率持续时间.
4.起始频率持续时间.
5.波形幅度.
5.波形相位.
(5)2ASK调制
GUI如下图所示
在此模式下可设定2ASK调制的:
1.起始幅度.
2.终止幅度.
3.起始幅度持续时间.
4.起始幅度持续时间.
5.波形频率.
5.波形相位.
(5)2PSK调制
GUI如下图所示
在此模式下可设定2PSK调制的以下参数:
1.起始相位.
2.终止相位.
3.起始相位持续时间.
4.起始相位持续时间.
5.波形频率.
5.波形幅度.
4.扫描模式下GUI如下图所示
扫描模式下功能1:扫频
扫频功能下三种不同扫频模式GUI如下图所示
上扫频GUI
下扫频GUI
上下扫频GUI
在扫频模式下可以设定以下参数用于扫频控制:
1.扫频上限频率
2.扫频下限频率
3.扫频步进频率
4.扫频幅度
5.扫频相位
6.扫频时间间隔
7.扫频DRC引脚时间间隔
8.扫频下限频率
9.选择扫频方式:上扫频、下扫频、上下扫频
在扫幅模式下可以设定以下参数用于扫幅控制:
1.扫幅上限幅度
2.扫幅下限幅度
3.扫幅步进幅度
4.扫幅频率
5.扫幅相位
6.扫幅时间间隔
7.扫幅DRC引脚时间间隔
9.选择扫幅方式:上扫幅、下扫幅、上下扫幅
扫描模式下功能3:扫相
在扫相模式下可以设定以下参数用于扫相控制:
1.扫相上限幅度
2.扫相下限幅度
3.扫相步进幅度
4.扫幅频率
5.扫相相位
6.扫相时间间隔
7.扫相DRC引脚时间间隔
9.选择扫相方式:上扫相、下扫相、上下扫相
谐坡调制功能
谐坡调制GUI如下图所示:
谐波调制功能1: FM调制
谐波FM调制GUI如下图所示:
在此模式下可设定以下参数用于FM调制
1.FM调制起始频率
2.FM调制终止频率
3.FM调制幅度
4.FM调制相位
5.FM调制斜率维持时间
谐波调制功能2: AM调制
谐波AM调制GUI如下图所示:
在此模式下可设定以下参数用于AM调制
1.AM调制起始幅度
2.AM调制终止幅度
3.AM调制频率
4.AM调制相位
5.AM调制斜率维持时间
谐波调制功能3: PM调制
谐波AM调制GUI如下图所示:
在此模式下可设定以下参数用于PM调制
1.PM调制起始相位
2.PM调制终止相位
3.PM调制频率
4.PM调制幅度
5.PM调制斜率维持时间
三、设计硬件说明
本项目主要由CW32F030单片机、AD9910模块、HMI4.3寸触摸屏、W25Q64存储芯片构成,硬件不存在复杂的数字或模拟电路,最复杂的应该是AD9910控制板的电路。可参考该账户下其他开源项目进行查阅详细说明。
CW32的GPIO口占用少,但功能相对强大,除跳频功能外其他全部完成。
因此对硬件电路不进行过多赘述,可以将整个硬件系统理解为:一个CW32最小系统(小蓝板)+一块HMI触摸屏+一个AD9910构成,最难部分均在软件代码设计.
对于ASK、PSK、FSK、AM、PM、FM、扫幅、扫频、扫相这些需要对高频电子这门课需要较深的理解,对实际应用有一定认知…我也不知道怎么进行论述,比如可以通过扫频确定一个电容的容量之类的…具体实现原理…请查相关资料。
硬件电路电源部分简单说明
电源电路:本项目供电电路由Type-C电路和电池供电电路组合而成,当Type-C悬空时,由电池进行供电,当Type-C接口接入时,由Type-C进行系统供电。流程图图下图所示。
电路结构如下图所示
电源流向:从左向右
在电路结构中存在这些屏蔽掉所有接口的电路,是用于定位孔绘制和3D模型绘制,在实际电路中无任何电气意义。
对于AD9910的电路,请参考我的其他开源项目进行的详细说明,在本项目中不进行过多论述。
本项目的原理图很简单,复杂的只有供电电路。
PCB设计说明
在本项目下只有两款PCB,第一款是核心板,第二款是AD9910接口的转接板,将2.54mm的排针接口转为PFC接口,用于跟核心板上的FPC接口进行连接,构成一个集成化的系统,避免通过线束的连接方式,在该PCB上开出一个开口,用于将FPC排线引出。
为降低板子的实际高度,该板尽量薄,因此我打板的时候选择厚度为1.2mm.
通过镂空区域和底部的螺丝柱,可以将AD9910完美的固定在上面。从节省成本上考虑,该部分可以舍去不用,只用底层的螺丝柱即可达到固定效果。板子大于10x10mm,不能使用免费打扮,双层板打板要40多!
三、设计软件说明
软件部分是整个设计的终点,在硬件电路设计时,一个小下午,硬件电路设计时用了一个多月,涉及的内容比较多。软件运行流程如下图所示。
4.3寸HMI串口屏代码编写.
串口通信代码流程如下图所示
串口屏运行流程如下图所示,所有逻辑代码均遵循以下原则
受限于CW32的片内资源,无法应用一些功能强大的RGB屏幕,因此选用MHI串口屏进行人机交互,实验结果表明,人机交互状态良好,基本实现预定功能。
其中HMI串口屏只用于发送预定帧结构的数据,单片机进行解算后进行相应,单片机不对HMI串口屏进行其他控制。
串口屏帧结构如下图所示:
帧结构构成:帧头+4位控制数据+帧尾(0A+数据位或标志位1+数据位或标志位2+数据位或标志位3+数据位或标志位3+帧尾)
帧头:0A,数据接收允许标志
数据:屏幕上设定参数构成,最大4个位
帧尾:A0,数据接收结束标志位
如发送一个频率参数,其HMI发送的帧结构为:0A EF 1A 03 06 A0,单片机进行接收,控制系统响应流程如下图所示。
具体逻辑代码请查看上传的HMI工程,该模块很好上手,在对其进行编程时,我只会画火柴人,UI界面不怎么好看,但是代码逻辑很完善。
在液晶显示部分,你可以理解为你要发什么数据、什么时候发、发了之后怎么样!
2.W25Q64代码编写
在本项目中,还是CW32片内Flash的问题,我只能用W25Q64进行波形数据存储,在CW32下只能定义一个4096大小的数据,因此智能一此次的往对应的4K字节扇区写入4096个波形数据。
在使用W25Q64时应明确:
1.你要把数据存到(128块每块64)块中的哪一块。哪一块的那个扇区(32K),哪个扇区的那个区域(4K),那个区域的那个页(256字节)的地址。
本项目存储数据都是线性存储,都是4096个数据,相当于一次寸一个区域,一个32K的扇区可以寸8个波形,一个64K的块可以存16个波形,因此需要大约3个快进行数据存储。存入结构路程如下图所示。
波形写入步骤如下图所示
1.波形数据存入4096大小的数组:const uint8_t Wave_Date[4096]
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
2.选择写入的4K扇区,用十进制数表示,从0开始向上递增
3.运行写入代码将4096大小的波形数据拆分为256大小,进行分页写入,刚好可以写满一个4K扇区.代码如下所示。
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i];} W25Q64_PageWrite(Wdate,0+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256];} W25Q64_PageWrite(Wdate,1+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*2];} W25Q64_PageWrite(Wdate,2+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*3];} W25Q64_PageWrite(Wdate,3+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*4];} W25Q64_PageWrite(Wdate,4+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*5];} W25Q64_PageWrite(Wdate,5+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*6];} W25Q64_PageWrite(Wdate,6+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*7];} W25Q64_PageWrite(Wdate,7+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*8];} W25Q64_PageWrite(Wdate,8+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*9];} W25Q64_PageWrite(Wdate,9+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*10];} W25Q64_PageWrite(Wdate,10+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*11];} W25Q64_PageWrite(Wdate,11+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*12];} W25Q64_PageWrite(Wdate,12+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*13];} W25Q64_PageWrite(Wdate,13+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*14];} W25Q64_PageWrite(Wdate,14+page);
for(i=0;i<256;i++) {Wdate[i]=Wave_Date[i+256*15];} W25Q64_PageWrite(Wdate,15+page);
4.运行读取代码,查看数据写入情况,可确认数据是否正常写入,读取数据不受限制,一次读取4096个字节。
W25Q64_Read(Date,0x29000,4096);
for(i=0;i<4096;i++)
{
printf("Wave[%d]=%x\r\n",i,Date[i]);
}
以上完成数据写入代码,写入的波形需要一个个写入!!!这个是个很繁琐的过程,一定要做好记录!
别问位啥不一次性写入,因为RAM就10K ,你定义两个4096大小的数组,直接硬件异常,芯片直接歇菜!
3.串口代码注解
串口代码只要是对传输过来的数据进行相应,必须是0A开头,必须是0A结尾,不然数据无效。
接收流程是:
1.收到A0–开始接收数据,否则无效
2.收到0A–结束数据否则无效
3.对接收数据根据帧结构进行基本解算,并对相应标志位赋值,告诉主函数是什么数据来了,以下是解算代码。
if(USART_GetITStatus(CW_UART1, USART_IT_RC) != RESET)
{
recv_dat = USART_ReceiveData_8bit(CW_UART1);
//数据结构 FF 00 01 02 03 FE
// 帧头 + 帧内容 + 帧尾
switch(recv_state)
{
case 0:
if(recv_dat==0x0A)
{
recv_state=1;//是包头标志位置于1
rxd_index=0;
}else {recv_state=0;}//不是处于等待状态
break;
case 1:
rxd_buf[rxd_index]=recv_dat;
rxd_index++;
if(rxd_index>=4)
{
recv_state=2;
}
break;
case 2:
if(recv_dat==0xA0)
{
rxd_flag=1;
if(rxd_buf[0]==0x00){rxd_flag=1; printf("1\n\r");}//频率档位标志位
if(rxd_buf[0]==0x01){rxd_flag=2; printf("2\n\r");}//频率参数设定标志位
if(rxd_buf[0]==0x02){rxd_flag=3; printf("3\n\r");}//幅度参数设定标志位
if(rxd_buf[0]==0x03){rxd_flag=4; printf("4\n\r");}//相位参数设定标志位
/**进入正弦页面和离开正弦页面判断标志位***/
if(rxd_buf[0]==0x04){rxd_flag=5; printf("5\n\r");}//进入正弦界面
if(rxd_buf[0]==0x05){rxd_flag=6; printf("6\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; }}
//返回主界面
//进入三角波模式
if(rxd_buf[0]==0xAA){rxd_flag=7; printf("7\n\r");}//频率
if(rxd_buf[0]==0xA1){rxd_flag=8; printf("8\n\r");}//宽
if(rxd_buf[0]==0xA2){rxd_flag=9; printf("9\n\r");}//模式
if(rxd_buf[0]==0xA3){rxd_flag=10; printf("10\n\r");}//档位
if(rxd_buf[0]==0xA4){rxd_flag=11; printf("11\n\r");//开启或关闭
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}//开启或关闭
//进入方波模式
if(rxd_buf[0]==0xB0){rxd_flag=12; printf("12\n\r");}//频率档位
if(rxd_buf[0]==0xB1){rxd_flag=13; printf("13\n\r");}//占空比
if(rxd_buf[0]==0xB2){rxd_flag=14; printf("14\n\r");}//播放模式
if(rxd_buf[0]==0xB3){rxd_flag=15; printf("15\n\r");}//频率
if(rxd_buf[0]==0xB4){rxd_flag=16; printf("16\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}//开启或关闭
//其他波形处理函数
//***************扫频模式************************/
if(rxd_buf[0]==0x70){rxd_flag=17; printf("16上限频率\n\r");}//扫频上限
if(rxd_buf[0]==0x71){rxd_flag=18; printf("18下限频率\n\r");}//扫频下限
if(rxd_buf[0]==0x72){rxd_flag=19; printf("19步进频率\n\r");}//扫频步进
if(rxd_buf[0]==0x73){rxd_flag=20; printf("20幅度\n\r");}//扫频幅度
if(rxd_buf[0]==0x74){rxd_flag=21; printf("21相位\n\r");}//扫频相位
if(rxd_buf[0]==0x75){rxd_flag=22; printf("22斜率档位\n\r");}//斜率时间档位
if(rxd_buf[0]==0x76){rxd_flag=23; printf("23斜率数据\n\r");}//斜率
if(rxd_buf[0]==0x77){rxd_flag=24; printf("24DRC时间间隔\n\r");}//DRC时间间隔
if(rxd_buf[0]==0x78){rxd_flag=25; printf("25扫频模式\n\r");}//扫频模式
if(rxd_buf[0]==0x79){rxd_flag=26; printf("26开启或关闭\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
} //开启或关闭扫频
//**************扫幅模式************************/
if(rxd_buf[0]==0x80){rxd_flag=27; printf("27扫幅上限\n\r");}
if(rxd_buf[0]==0x81){rxd_flag=28; printf("28扫幅下限\n\r");}
if(rxd_buf[0]==0x82){rxd_flag=29; printf("29扫幅步进\n\r");}
if(rxd_buf[0]==0x83){rxd_flag=30; printf("30扫幅频率\n\r");}
if(rxd_buf[0]==0x84){rxd_flag=31; printf("31扫幅相位\n\r");}
if(rxd_buf[0]==0x85){rxd_flag=32; printf("32时间档位\n\r");}
if(rxd_buf[0]==0x86){rxd_flag=33; printf("33时间\n\r");}
if(rxd_buf[0]==0x87){rxd_flag=34; printf("34DRC时间间隔\n\r");}
if(rxd_buf[0]==0x88){rxd_flag=35; printf("35扫幅方式\n\r");}
if(rxd_buf[0]==0x89){rxd_flag=36; printf("36扫幅开启或关闭\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}
//**************扫相模式************************/
if(rxd_buf[0]==0xC7){rxd_flag=37; printf("32扫相上限\n\r");}
if(rxd_buf[0]==0xC8){rxd_flag=38; printf("38扫相下限\n\r");}
if(rxd_buf[0]==0xC9){rxd_flag=39; printf("39扫相步进\n\r");}
if(rxd_buf[0]==0xCA){rxd_flag=40; printf("40扫相频率\n\r");}
if(rxd_buf[0]==0xCB){rxd_flag=41; printf("41扫相幅度\n\r");}
if(rxd_buf[0]==0xCC){rxd_flag=42; printf("42扫相时间档位\n\r");}
if(rxd_buf[0]==0xCD){rxd_flag=43; printf("43扫相时间\n\r");}
if(rxd_buf[0]==0xCE){rxd_flag=44; printf("44扫相DRC时间间隔\n\r");}
if(rxd_buf[0]==0xCF){rxd_flag=45; printf("45扫相方式\n\r");}
if(rxd_buf[0]==0xFA){rxd_flag=46; printf("46扫相开启或关闭\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}
//FM模式参数
if(rxd_buf[0]==0xF0){rxd_flag=47; printf("47FM起始频率\n\r");}
if(rxd_buf[0]==0xF1){rxd_flag=48; printf("48FM终止频率\n\r");}
if(rxd_buf[0]==0xF2){rxd_flag=49; printf("49FM步进频率\n\r");}
if(rxd_buf[0]==0xF3){rxd_flag=50; printf("50FM频率斜率时间\n\r");}
if(rxd_buf[0]==0xF4){rxd_flag=51; printf("51FM幅度\n\r");}
if(rxd_buf[0]==0xF5){rxd_flag=52; printf("52FM相位\n\r");}
if(rxd_buf[0]==0xF6){rxd_flag=53; printf("53FM开启或关闭标志位\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}
//AM模式参数
if(rxd_buf[0]==0x20){rxd_flag=54; printf("47AM起始幅度\n\r");}
if(rxd_buf[0]==0x21){rxd_flag=55; printf("48AM终止幅度\n\r");}
if(rxd_buf[0]==0x22){rxd_flag=56; printf("49AM步进幅度\n\r");}
if(rxd_buf[0]==0x23){rxd_flag=57; printf("50AM频率斜率时间\n\r");}
if(rxd_buf[0]==0x24){rxd_flag=58; printf("51AM频率\n\r");}
if(rxd_buf[0]==0x25){rxd_flag=59; printf("52AM相位\n\r");}
if(rxd_buf[0]==0x26){rxd_flag=60; printf("53AM开启或关闭标志位\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}
//PM模式参数
if(rxd_buf[0]==0x30){rxd_flag=61; printf("61PM起始相位\n\r");}
if(rxd_buf[0]==0x31){rxd_flag=62; printf("62PM终止相位\n\r");}
if(rxd_buf[0]==0x32){rxd_flag=63; printf("63PM步进相位\n\r");}
if(rxd_buf[0]==0x33){rxd_flag=64; printf("64PM频率斜率时间\n\r");}
if(rxd_buf[0]==0x34){rxd_flag=65; printf("65PM频率\n\r");}
if(rxd_buf[0]==0x35){rxd_flag=66; printf("66PM幅度\n\r");}
if(rxd_buf[0]==0x36){rxd_flag=67; printf("67PM开启或关闭标志位\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910();}
}
//单频调制FM
if(rxd_buf[0]==0x40){rxd_flag=68; printf("68单频调制FM起始频率\n\r");}
if(rxd_buf[0]==0x41){rxd_flag=69; printf("69单频调制FM终止频率\n\r");}
if(rxd_buf[0]==0x42){rxd_flag=70; printf("70单频调制FM步进频率\n\r");}
if(rxd_buf[0]==0x43){rxd_flag=71; printf("71单频调制FM幅度\n\r");}
if(rxd_buf[0]==0x44){rxd_flag=72; printf("72单频调制FM相位\n\r");}
if(rxd_buf[0]==0x45){rxd_flag=73;stateFM=0;
printf("73单频调制FM开启或关闭标志位\n\r");
if(Get_Stat()==0){Init_ad9910(); Break_FM=1;ad9910_reset(1); MAS_REST_HIGH;}
if(Get_Stat()==1){Init_ad9910(); Test(); MAS_REST_LOW; Break_FM=0;}
} //在此直接解算,直接关闭
//单频AM调制
if(rxd_buf[0]==0x50){rxd_flag=74; stateFM=0;printf("74单频调制AM起始幅度\n\r");}
if(rxd_buf[0]==0x51){rxd_flag=75; printf("75单频调制AM终止幅度\n\r");}
if(rxd_buf[0]==0x52){rxd_flag=76; printf("76单频调制AM步进幅度\n\r");}
if(rxd_buf[0]==0x53){rxd_flag=77; printf("77单频调制AM频率\n\r");}
if(rxd_buf[0]==0x54){rxd_flag=78; printf("78单频调制AM相位\n\r");}
if(rxd_buf[0]==0x55){rxd_flag=79; stateAM=0;printf("79单频调制AM开启或关闭标志位\n\r");
if(Get_Stat()==0){
Init_ad9910(); stateAM=2;ad9910_reset(1); MAS_REST_HIGH; //关闭
}
if(Get_Stat()==1){Init_ad9910(); Test(); MAS_REST_LOW; stateAM=0;}
} //在此直接解算,直接关闭
//单频PM调制
if(rxd_buf[0]==0x60){rxd_flag=80; stateFM=0;printf("80单频调制PM起始相位\n\r");}
if(rxd_buf[0]==0x61){rxd_flag=81; printf("81单频调制PM终止相位\n\r");}
if(rxd_buf[0]==0x62){rxd_flag=82; printf("82单频调制PM步进相位\n\r");}
if(rxd_buf[0]==0x63){rxd_flag=83; printf("83单频调制PM频率\n\r");}
if(rxd_buf[0]==0x64){rxd_flag=84; printf("84单频调制PM幅度\n\r");}
if(rxd_buf[0]==0x65){rxd_flag=85; stateAM=0;printf("85单频调制PM开启或关闭标志位\n\r");
if(Get_Stat()==0){
Init_ad9910(); statePM=3;ad9910_reset(1); MAS_REST_HIGH; //关闭
}
if(Get_Stat()==1){Init_ad9910(); Test(); MAS_REST_LOW; statePM=0;}
} //在此直接解算,直接关闭
//单频2FSK
if(rxd_buf[0]==0xD1){rxd_flag=86; printf("86单频调制FSK起始频率1\n\r");}
if(rxd_buf[0]==0xD2){rxd_flag=87; printf("87单频调制FSK终止频率2\n\r");}
if(rxd_buf[0]==0xD3){rxd_flag=88; printf("88单频调制FSK宽度1\n\r");}
if(rxd_buf[0]==0xD4){rxd_flag=89; printf("89单频调制FSK宽度2\n\r");}
if(rxd_buf[0]==0xD5){rxd_flag=90; printf("90单频调制FSK相位\n\r");}
if(rxd_buf[0]==0xD6){rxd_flag=91; printf("91单频调制FSK幅度\n\r"); }
if(rxd_buf[0]==0xD7){rxd_flag=92; printf("92单频调制FSK开启或关闭标志位\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910(); } }
//单频2ASK
if(rxd_buf[0]==0x90){rxd_flag=93; printf("93单频调制ASK起始频率1\n\r");}
if(rxd_buf[0]==0x91){rxd_flag=94; printf("94单频调制ASK终止频率2\n\r");}
if(rxd_buf[0]==0x92){rxd_flag=95; printf("95单频调制ASK宽度1\n\r");}
if(rxd_buf[0]==0x93){rxd_flag=96; printf("96单频调制ASK宽度2\n\r");}
if(rxd_buf[0]==0x94){rxd_flag=97; printf("97单频调制ASK相位\n\r");}
if(rxd_buf[0]==0x95){rxd_flag=98; printf("98单频调制ASK幅度\n\r"); }
if(rxd_buf[0]==0x96){rxd_flag=99; printf("99单频调制ASK开启或关闭标志位\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910(); } }
//单频2PSK
if(rxd_buf[0]==0xC0){rxd_flag=100; printf("100单频调制PSK起始相位1\n\r");}
if(rxd_buf[0]==0xC1){rxd_flag=101; printf("101单频调制PSK终止相位2\n\r");}
if(rxd_buf[0]==0xC2){rxd_flag=102; printf("102单频调制PSK宽度1\n\r");}
if(rxd_buf[0]==0xC3){rxd_flag=103; printf("103单频调制PSK宽度2\n\r");}
if(rxd_buf[0]==0xC4){rxd_flag=104; printf("104单频调制PSK幅度\n\r");}
if(rxd_buf[0]==0xC5){rxd_flag=105; printf("105单频调制PSK频率\n\r"); }
if(rxd_buf[0]==0xC6){rxd_flag=106; printf("106单频调制PSK开启或关闭标志位\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910(); } }
其他波形处理函数
if(rxd_buf[0]==0xB5){rxd_flag=107; printf("107\n\r");}
if(rxd_buf[0]==0xB6){rxd_flag=108; printf("108\n\r");}
if(rxd_buf[0]==0xB7){rxd_flag=109; printf("109\n\r");}
if(rxd_buf[0]==0xB8){rxd_flag=110; printf("110\n\r");}
if(rxd_buf[0]==0xB9){rxd_flag=111; printf("111\n\r");
if(Get_Stat()==0){MAS_REST_HIGH; } if(Get_Stat()==1){Init_ad9910(); }
}
recv_state=0;
}
break;
根据不同的标志位,在主函数中节能型相应的操作即可。在主函数中,均是逻辑代码,遵循以下流程:
接收到数据–>标志位赋值----根据标志位进行相应的操作
整个函数信号发生器的逻辑功能代码大约3000行,相对简单。
不在串口中断接收处进行直接逻辑操作,是因为,中断就是要快速相应,遵循快入快出原则。代码执行流程如下图所示。
值得注意的是,HMI传输过来的数据是十六进制,因此需要进行解算为10进制,解算代码如下:
uint32_t Get_date(void)
{
static int val = 0;
static uint8_t *pBuf = (uint8_t*)&val;
pBuf[0] = rxd_buf[1];
pBuf[1] = rxd_buf[2];
pBuf[2] = rxd_buf[3];
return val;
// printf("串口传输过来的频率=%d\n",val);
}