jinglixixi 发表于 2025-10-23 17:19

以RA4M2-SENSOR开发板实现迷你型信号发生器

本帖最后由 jinglixixi 于 2025-10-23 19:42 编辑

申请原创@21小跑堂

实现迷你信号发生器的方法有两种,一种是以硬件的方式,即通过相应功能模块来实现,如AD9833模块就是一种可编程波形发生器;另一种则是以软件的方式来实现。这里介绍的就是一种采用软件方式,来实现的方案,其功能包括:产生指定幅值的信号、可调占空比的信号、三角波、锯齿波、正弦波、余弦波及控制步进电机的正反转节拍信号等。为便于使用,是以OLED屏为显示器件,来减少引脚的占用。为配合功能的选择,是使用板载的按键K1、K2及K3。产生的信号,则是由DAC引脚输出。至于步进电机的驱动信号,则由其他的引脚输出。具体的引脚连接关系为:OLED_SCL----P100OLED_SDA----P101K1----P013K2----P112K3----P111DAC----P014TXD9----P109RXD9----P110A----P301B----P302C----P407D----P408
相关引脚的配置在RASC下完成,所使用的资源如图1所示,相应资源的配置情况见图2至图5所示。
图1所用资源


图2GPIO配置 (输入与输出)

图3 定时器配置

图4DAC配置

图5 串口配置
随后,可用RASC生成相应的KEIL项目工程。
该信号发生器的界面如图6所示,所用字模由工具软件提取其界面如图7所示。
图6 界面效果

图7 提取方式
实现界面效果的程序为:OLED_Init();
OLED_Clear();
OLED_ShowCHinese(0,0,0);
OLED_ShowCHinese(16,0,1);
OLED_ShowCHinese(32,0,2);
OLED_ShowCHinese(48,0,3);
OLED_ShowCHinese(64,0,4);
OLED_ShowCHinese(80,0,5);
OLED_ShowCHinese(96,0,6);
OLED_ShowString(0,5,"by:jinglixixi",16);
while(R_BSP_PinRead(BSP_IO_PORT_01_PIN_11)==BSP_IO_LEVEL_HIGH);
功能选择的形式及滚动效果如图8至图10所示,为进行功能选择,K1键用于选取下一项、K2键用于选取前一项、K3键用于确认。
图8 菜单显示

图9 滚动选取

图10 滚动效果
菜单选项滚动效果的函数为:void gui_menu(uint8_t k)
{
         uint8_t i,h;
         uint8_t menu_GRAM={{7,8,25},{9,10,11},{12,13,14},{15,16,14},{17,18,14},{19,18,14},{17,21,22},{20,21,22}};
         for(i=0;i<4;i++)
         {
                  h=(k+i)%6;
                  OLED_ShowCHinese(16,i*2,menu_GRAM);
                  OLED_ShowCHinese(32,i*2,menu_GRAM);
                  OLED_ShowCHinese(48,i*2,menu_GRAM);
         }
}
功能选择处理的程序为:OLED_Clear();                        
j=1;
k=1;
OLED_ShowChar(8,0,'>',16);
while(j)
{
      if(R_BSP_PinRead(BSP_IO_PORT_01_PIN_12)==BSP_IO_LEVEL_LOW)
      {
                if(k>1) k=k-1;
      }
      if(R_BSP_PinRead(BSP_IO_PORT_00_PIN_13)==BSP_IO_LEVEL_LOW)
      {
                if(k>7)
                {
                        k=1;
                }
                else      
                {                                                                        
                        k=k+1;
                }
      }
      if(R_BSP_PinRead(BSP_IO_PORT_01_PIN_11)==BSP_IO_LEVEL_LOW)
      {
                j=0;
      }
      p=k-1;
      gui_menu(p);
      OLED_ShowNum(80,0,k,2,16);
      R_BSP_SoftwareDelay (200, BSP_DELAY_UNITS_MILLISECONDS);
}
为进行参数设置,其界面如图11所示。
图11 参数设置界面
参数设置的程序为:j=1;
k=1;
OLED_Clear();
OLED_ShowString(16,2,"n=",16);
while(j)
{
   if(R_BSP_PinRead(BSP_IO_PORT_01_PIN_12)==BSP_IO_LEVEL_LOW)
   {
          k=k-1;
   }
   if(R_BSP_PinRead(BSP_IO_PORT_00_PIN_13)==BSP_IO_LEVEL_LOW)
   {
          k=k+1;
   }
   if(R_BSP_PinRead(BSP_IO_PORT_01_PIN_11)==BSP_IO_LEVEL_LOW)
   {
          j=0;
   }
   OLED_ShowNum(40,2,k,2,16);
   R_BSP_SoftwareDelay (200, BSP_DELAY_UNITS_MILLISECONDS);                        
}
为了突出直观性的特点,是通过OLED屏来呈现波形的样式。绘制坐标轴的函数为:void gui_draw_axis(void)
{
   gui_draw_hline(62,0,120);
   gui_draw_vline(0,0,62);
}
设置输出幅值的程序为:j=1;
k=0;
o=0;
OLED_ShowString(16,3,"n=0",16);
while(j)
{
                if(R_BSP_PinRead(BSP_IO_PORT_01_PIN_12)==BSP_IO_LEVEL_LOW)
                {
                         if(k>1) k=k-1;
                }
                if(R_BSP_PinRead(BSP_IO_PORT_00_PIN_13)==BSP_IO_LEVEL_LOW)
                {
                         k=k+1;
                }
                if(R_BSP_PinRead(BSP_IO_PORT_01_PIN_11)==BSP_IO_LEVEL_LOW)
                {
                         j=0;
                }                                       
                if((p==0)&&(o!=k))
                {
                        k=k%33;
                        h=3;                                                
                        OLED_ShowString(16,h,"n= .V",16);
                        OLED_ShowNum(32,h,k/10,1,16);
                        OLED_ShowNum(48,h,k%10,1,16);
                        o=k;
                }
                if((p==1)&&(o!=k))
                {
                        k=k%101;
                        h=3;                                                
                        OLED_ShowString(16,h,"n=    %",16);
                        OLED_ShowNum(32,h,k,3,16);
                        o=k;
                }
                R_BSP_SoftwareDelay (200, BSP_DELAY_UNITS_MILLISECONDS);                        
}
绘制幅值输出效果的程序为:for( (i=0;i<=100;i++)
{
          if(k==0) OLED_DrawPoint(i,62-k*1.5,1);
}                        
OLED_Refresh();                                 
if(k>16) h=5;
else h=3;                                                
OLED_ShowString(16,h,"n= .V",16);
OLED_ShowNum(32,h,k/10,1,16);
OLED_ShowNum(48,h,k%10,1,16);
在设置输出幅值后,其输出效果如图12和图13所示。
图12 输出低幅值电压

图13 输出高幅值电压
以设置幅值的程序为基础,可方便地完成占空比设置的程序,其介绍这里从略。
绘制占空比效果的程序为:for(i=0;i<=100;i++)
{
      if(k==1)
      {
            if(i<u) OLED_DrawPoint(i,22,1);
            elseOLED_DrawPoint(i,62,1);
            if((i==u)||(i==100)) gui_draw_vline(i,22,62);
      }
}      
gui_draw_hline(22,100,120);                                 
OLED_Refresh();                                       
h=0;                                                
OLED_ShowString(16,h,"n=    %",16);
OLED_ShowNum(32,h,k*10,3,16);
在设置占空比后,占空比的调节效果如图14和图15所示。
图14 占空比=40%

图15 占空比=80%
绘制锯齿波的程序为:for(i=0;i<=100;i++)
{
      g=i%50;   
      if(g<49) OLED_DrawPoint(i,62-g,1);
      if(g==0)gui_draw_vline(i,12,62);
}
其执行效果如图16所示。
图16 锯齿波效果
绘制三角波的程序为:for(i=0;i<=100;i++)
{
         g=(i%25)*2;
         if((i%25)==0) f=(f+1)%2;
         if(f>0) OLED_DrawPoint(i,62-g,1);
         else OLED_DrawPoint(i,12+g,1);                                 
}
其执行效果如图17所示。
图17 三角波效果
绘制正弦波的数据为:int values=
{
{0x07FF},{0x08C8},{0x098E},{0x0A51},{0x0B0F},
{0x0BC4},{0x0C71},{0x0D12},{0x0DA7},{0x0E2E},
{0x0EA5},{0x0F0D},{0x0F63},{0x0FA6},{0x0FD7},
{0x0FF5},{0x0FFF},{0x0FF5},{0x0FD7},{0x0FA6},
{0x0F63},{0x0F0D},{0x0EA5},{0x0E2E},{0x0DA7},
{0x0D12},{0x0C71},{0x0BC4},{0x0B0F},{0x0A51},
{0x098E},{0x08C8},{0x07FF},{0x0736},{0x0670},
{0x05AD},{0x04EF},{0x043A},{0x038D},{0x02EC},
{0x0257},{0x01D0},{0x0159},{0x00F1},{0x009B},
{0x0058},{0x0027},{0x0009},{0x0000},{0x0009},
{0x0027},{0x0058},{0x009B},{0x00F1},{0x0159},
{0x01D0},{0x0257},{0x02EC},{0x038D},{0x043A},
{0x04EF},{0x05AD},{0x0670},{0x0736}
};
绘制正弦与余弦波的函数为:void gui_sin(uint8_t k)
{
          uint16_t i,sj,p;
          for (i = 0 ; i < 128; i++)         
          {
                  if(k==4) sj=values;                        
                  else
                  {
                              p=(i/2+16)%64;
                              sj=values;
                  }
                  sj=sj/80;
                  OLED_DrawPoint(i,63-sj,1);
         }
}
绘制正弦波的程序为:Gram_clear();                        
gui_draw_axis(1);      
gui_sin(5);               
OLED_Refresh();
实现正弦与余弦波的效果如图18和图19所示。
图18 正弦波效果

图19 余弦波效果
为便于步进电机的驱动控制,输出高低电平的语句定义为:#define MAL   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_03_PIN_01, BSP_IO_LEVEL_LOW)#define MAH   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_03_PIN_01, BSP_IO_LEVEL_HIGH)#define MBL   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_03_PIN_02, BSP_IO_LEVEL_LOW)#define MBH   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_03_PIN_02, BSP_IO_LEVEL_HIGH)
#define MCL   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_04_PIN_07, BSP_IO_LEVEL_LOW)#define MCH   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_04_PIN_07, BSP_IO_LEVEL_HIGH)#define MDL   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_04_PIN_08, BSP_IO_LEVEL_LOW)#define MDH   R_IOPORT_PinWrite(&IOPORT_CFG_CTRL, BSP_IO_PORT_04_PIN_08, BSP_IO_LEVEL_HIGH)
步进电机正反转的驱动程序为:void zx(int n)
{
unsigned char X,Y;
for(X=0;X<64;X++)
{
   for(Y=0;Y<8;Y++)
   {
         MDL;
         MAH;
         Delay_hms(n);
         MBH;
         Delay_hms(n);
         MAL;
         Delay_hms(n);
         MCH;
         Delay_hms(n);
         MBL;
         Delay_hms(n);
         MDH;
         Delay_hms(n);
         MCL;
         Delay_hms(n);
         MAH;
         Delay_hms(n);
   }
}
}

void fx(int n)
{
   unsigned char X,Y;
   for(X=0;X<64;X++)
   {
       for(Y=0;Y<8;Y++)
       {
          MDH;
          MAH;
          Delay_hms(n);
          MAL;
          Delay_hms(n);
          MCH;
          Delay_hms(n);
          MDL;
          Delay_hms(n);
          MBH;
          Delay_hms(n);
          MCL;
          Delay_hms(n);
          MAH;
          Delay_hms(n);
          MBL;
          Delay_hms(n);
       }
    }      
}

图20 步进电机控制

波形输出的初始化函数为:void Wave_Init(void)
{
      err = FSP_SUCCESS;      
      err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
      assert(err == FSP_SUCCESS);
      err = R_GPT_Start(&g_timer0_ctrl);
      assert(err == FSP_SUCCESS);
      err = R_DAC_Open(&g_dac0_ctrl, &g_dac0_cfg);
      assert(err == FSP_SUCCESS);
      err = R_DAC_Start(&g_dac0_ctrl);
      assert(err == FSP_SUCCESS);
}
波形输出的中断处理函数为:void g_timer0_callback(timer_callback_args_t * p_args)
{
      FSP_PARAMETER_NOT_USED(p_args);
      R_DAC_Write(&g_dac0_ctrl,wave);
      if(i >= 256) i = 0;
}
至此,就有效地实现了迷你型信号发生器的功能。此外,通过串口还可以指令的方式来控制波形信号的输出。

页: [1]
查看完整版本: 以RA4M2-SENSOR开发板实现迷你型信号发生器