• 正文
  • 相关推荐
申请入驻 产业图谱

基于STM32和AD9833的信号发生器设计(4)——封装错误害人太深,整套装置功亏一篑

3小时前
227
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

上期说到,我们发现第一版设计中MCP4017数字电位器无法直接应用于运算放大器的反馈电阻,设计时并没有考虑到MCP4017的电气特性,因此导致原理图作废。

同时我们发现在嘉立创EDA中,AD8034与AD8033的原理图存在混淆,导致型号选择错误。

在解决完这些事情之后,对装置进行了焊接和软件编程以及测试过程。

1、装置存在的问题

首先是可能由于放大倍数过大以及偏置电流的问题,导致输出存在着一个直流偏置,这个直流偏置是运算放大器引入的并非是AD9833的输出偏置被放大了。

应当在第一级放大后加交流耦合,防止直流偏置被进一步放大。

除此之外,又被嘉立创的库给坑了,到底是哪些神人在嘉立创上上面绘制错误的原理图和封装!!!

由于我没用过BNC母座,我其实在绘制的时候就有疑问,为什么输出引脚不是和SMA座子那种一样,输出引脚在中间,而是选择了边上?但是我以为BNC母座的特性就是这样子的,太过于相信这个封装了!!!

导致我在最后测试完毕,焊接上输出端口的时候,运放的输出直接接地!

2、装置大体

装置采用U8g2作为OLEDGUI库,两颗旋转编码器分别用来调节频率大小和频率位置 以及电压大小。

频率和幅度都可以正常改变,就是频率高的时候幅值会有一点衰减。

3、代码解析

  AD9833_Init();//AD9833初始化  HAL_Delay(100);  AT24C02_LoadData(&current_freq, &current_vol,&freq_unit);//读取频率和电压  if(current_freq>=1000)//判断频率范围  {    freq_unit = 1;  }  UpdateFreqDigitsFromFreq();//更新显示数字  AD9833_SetFrequency(current_freq);//设置频率  AD9833_SetWave(WAVE_SINE);//设置AD9833波形  MCP4017_SetWiper(current_vol);//设置电压  HAL_TIM_Base_Start_IT(&htim1);//启用定时器  HAL_TIM_Base_Start(&htim2);  HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_1 | TIM_CHANNEL_2);//启用编码器  HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_1 | TIM_CHANNEL_2);//启用编码器  u8g2_t u8g2; //定义u8g2句柄  u8g2Init(&u8g2);//u8g2初始化

初始化阶段包括对AD9833的初始化,从EEPROM中读取上次的频率和电压大小,AD9833频率设置,数字电位器档位设置以及U8g2的初始化。

  while (1)  {    if(save_flag)    {      save_flag = 0;      AT24C02_SaveData(current_freq, current_vol, freq_unit);    }    MainGUI(&u8g2);    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);      HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_2);    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */  }

在主函数中进行U8g2的更新以及AT24C02的存储。

voidMainGUI(u8g2_t *u8g2){  char freq_str[3];  char vol_str[10];  char unit_str[3];    blink_counter++;  uint8_t blink_state = (blink_counter % 10) < 5;    u8g2_ClearBuffer(u8g2);    u8g2_SetFont(u8g2, u8g2_font_ncenB12_tf);  u8g2_DrawStr(u8g2, 5, 20, "Fre:");    u8g2_SetFont(u8g2, u8g2_font_ncenB12_tf);    for(uint8_t i = 0; i < 3; i++)  {    if(edit_mode == 1 && freq_digit == i && !blink_state)    {      u8g2_DrawHLine(u8g2, 45 + i * 9, 21, 7);      continue;    }    freq_str[0] = freq_digits[i] + '0';    freq_str[1] = '';    u8g2_DrawStr(u8g2, 45 + i * 9, 20, freq_str);  }    u8g2_DrawStr(u8g2, 72, 20, ".");    if(edit_mode == 1 && freq_digit == 3 && !blink_state)  {    u8g2_DrawHLine(u8g2, 81, 21, 7);  }  else  {    freq_str[0] = freq_digits[3] + '0';    freq_str[1] = '';    u8g2_DrawStr(u8g2, 81, 20, freq_str);  }    if(freq_unit == 0)  {    strcpy(unit_str, "Hz");  }  elseif(freq_unit == 1)  {    strcpy(unit_str, "K");  }  else  {    strcpy(unit_str, "M");  }    if(edit_mode == 1 && freq_digit == 4 && !blink_state)  {    u8g2_DrawHLine(u8g2, 90, 21, u8g2_GetStrWidth(u8g2, unit_str));  }  else  {    u8g2_DrawStr(u8g2, 90, 20, unit_str);  }    u8g2_SetFont(u8g2, u8g2_font_ncenB08_tf);  u8g2_DrawStr(u8g2, 15, 35, "Min");    uint8_t bar_width = (uint8_t)((current_vol / 127) * 90);  u8g2_DrawRBox(u8g2, 25, 40, bar_width, 12, 3);  u8g2_DrawRFrame(u8g2, 25, 40, 90, 12, 3);    u8g2_DrawStr(u8g2, 100, 35, "Max");    // 在滑条下方显示当前值  u8g2_SetFont(u8g2, u8g2_font_ncenB08_tf);  sprintf(vol_str, "%d", current_vol);  uint8_t vol_num_width = u8g2_GetStrWidth(u8g2, vol_str);  uint8_t vol_num_x = 25 + (90 - vol_num_width) / 2; // 居中显示  u8g2_DrawStr(u8g2, vol_num_x, 65, vol_str);    u8g2_SendBuffer(u8g2);}

GUI绘制中,计算各个显示位数,实现Fre:xxx.xKHZ这个格式的实现以及使用滑条显示MCP4017的档位。

    KeyScan(&Userkey1,GPIOA,GPIO_PIN_3);    KeyScan(&Userkey2,GPIOA,GPIO_PIN_9);        int16_t encoder1_current = __HAL_TIM_GET_COUNTER(&htim4);    int16_t encoder2_current = __HAL_TIM_GET_COUNTER(&htim3);        int16_t encoder1_diff = -(encoder1_current - encoder1_last);    int16_t encoder2_diff = -(encoder2_current - encoder2_last);        if(edit_mode == 1)    {      if(encoder1_diff != 0)      {        encoder1_accum += encoder1_diff;                if(encoder1_accum >= 4 || encoder1_accum <= -4)        {          if(freq_digit < 4)          {            if(freq_digit == 0)            {              if(encoder1_accum > 0)              {                freq_digits[0]++;                if(freq_digits[0] > 9) freq_digits[0] = 0;              }              else              {                if(freq_digits[0] == 0) freq_digits[0] = 9;                else freq_digits[0]--;              }            }            elseif(freq_digit == 1)            {              if(encoder1_accum > 0)              {                freq_digits[1]++;                if(freq_digits[1] > 9)                {                  freq_digits[1] = 0;                  if(freq_digits[0] < 9)                  {                    freq_digits[0]++;                  }                }              }              else              {                if(freq_digits[1] == 0)                {                  freq_digits[1] = 9;                  if(freq_digits[0] > 0)                  {                    freq_digits[0]--;                  }                }                else                {                  freq_digits[1]--;                }              }            }            elseif(freq_digit == 2)            {              if(encoder1_accum > 0)              {                freq_digits[2]++;                if(freq_digits[2] > 9)                {                  freq_digits[2] = 0;                  if(freq_digits[1] < 9)                  {                    freq_digits[1]++;                  }                }              }              else              {                if(freq_digits[2] == 0)                {                  freq_digits[2] = 9;                  if(freq_digits[1] > 0)                  {                    freq_digits[1]--;                  }                }                else                {                  freq_digits[2]--;                }              }            }            elseif(freq_digit == 3)            {              if(encoder1_accum > 0)              {                freq_digits[3]++;                if(freq_digits[3] > 9)                {                  freq_digits[3] = 0;                  if(freq_digits[2] < 9)                  {                    freq_digits[2]++;                  }                }              }              else              {                if(freq_digits[3] == 0)                {                  freq_digits[3] = 9;                  if(freq_digits[2] > 0)                  {                    freq_digits[2]--;                  }                }                else                {                  freq_digits[3]--;                }              }            }                        // 只更新显示值,不立即设置频率和保存            uint32_t display_freq = freq_digits[0] * 100 + freq_digits[1] * 10 + freq_digits[2];                        if(freq_unit == 0)            {              current_freq = display_freq;            }            elseif(freq_unit == 1)            {              current_freq = display_freq * 1000 + freq_digits[3] * 100;            }            elseif(freq_unit == 2)            {              current_freq = display_freq * 1000000 + freq_digits[3] * 100000;            }          }          else          {            if(encoder1_accum > 0)            {              if(freq_unit < 2)              {                freq_unit++;              }            }            else            {              if(freq_unit > 0)              {                freq_unit--;              }            }            uint32_t display_freq = freq_digits[0] * 100 + freq_digits[1] * 10 + freq_digits[2];                        if(freq_unit == 0)            {              current_freq = display_freq;            }            elseif(freq_unit == 1)            {              current_freq = display_freq * 1000;            }            elseif(freq_unit == 2)            {              current_freq = display_freq * 1000000;            }          }          encoder1_last = encoder1_current;          encoder1_accum = 0;        }      }            if(encoder2_diff != 0)      {        encoder2_accum += encoder2_diff;                if(encoder2_accum >= 4)        {          if(freq_digit < 4)          {            freq_digit++;          }          encoder2_accum = 0;        }        elseif(encoder2_accum <= -4)        {          if(freq_digit > 0)          {            freq_digit--;          }          encoder2_accum = 0;        }        encoder2_last = encoder2_current;      }    }    elseif(edit_mode == 2)    {      if(encoder1_diff != 0)      {        encoder1_accum += encoder1_diff;                if(encoder1_accum >= 4 || encoder1_accum <= -4)        {          if(encoder1_accum > 0)          {            if(current_vol < 127)            {              current_vol++;            }          }          else          {            if(current_vol > 0)            {              current_vol--;            }          }          MCP4017_SetWiper(current_vol);          save_flag = 1;          encoder1_last = encoder1_current;          encoder1_accum = 0;        }      }    }        if(Userkey1._haspress)    {      Userkey1._haspress = 0;      if(edit_mode == 1)      {        uint32_t display_freq = freq_digits[0] * 100 + freq_digits[1] * 10 + freq_digits[2];                if(freq_unit == 0)        {          current_freq = display_freq;        }        elseif(freq_unit == 1)        {          current_freq = display_freq * 1000 + freq_digits[3] * 100;        }        elseif(freq_unit == 2)        {          current_freq = display_freq * 1000000 + freq_digits[3] * 100000;        }                AD9833_SetFrequency(current_freq);        save_flag = 1;        edit_mode = 0;      }      else      {        edit_mode = 1;      }    }        if(Userkey2._haspress)    {      Userkey2._haspress = 0;      edit_mode = 2;    }

按键检测中使用定时器无阻塞检测的方式,对编码器状态实现判断,并设置标记。

相关推荐