4回答

0收藏

GD32用作低频滤波(采集信号+FIR低通滤波+输出结果信号)

GD32 GD32 4927 人阅读 | 4 人回复 | 2016-06-20

试了好多种采样率,最终发现以我的水平,1K的采样率,这个板子才能正常采集计算并输出,可是1K的采样率能处理什么信号呢,重低音大概是在150Hz以下,于是就做了个截止频率150Hz的滤波器;

目的:学会用C语言实现FIR滤波器;

既然采样率1K,1ms的时间够MCU做21次乘加运算了,就来个20阶的,程序如下:
  1. [hide]/* Private functions ---------------------------------------------------------*/

  2. /**
  3.   * @brief  systick_init
  4.   * @param  None
  5.   * @retval None
  6.   */
  7. #define nus 1000  // 1000us采样一次,1K的采样率
  8. static uint16_t fac_us;
  9. void systick_init(void)
  10. {

  11.         SysTick_CKSource_Enable(SYSTICK_CKSOURCE_HCLK_DIV8);        // 选择HCLK/8
  12.         fac_us=SystemCoreClock/8000000;            // 为系统时钟的1/8   
  13. }

  14. /**
  15.   * @brief  fir_lp
  16.   * @param  None
  17.   * @retval None
  18.   */
  19. const uint16_t gain[21] = {
  20.         0,     96,    208,    124,      0,      0,      0,    869,   4518,
  21.      8236,   9816,   8236,   4518,    869,      0,      0,      0,    124,
  22.       208,     96,      0
  23. };
  24. static uint16_t buffer[21];
  25. void fir_lp(void)
  26. {               
  27.         uint32_t output = 0;
  28.     uint32_t temp = 0;
  29.     static uint8_t j = 0;
  30.     uint8_t i;
  31.         SysTick->LOAD=nus*fac_us;   // 时间加载                           
  32.         SysTick->VAL=0x00;          // 清空计数器
  33.         SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        // 开始倒数
  34.    
  35.     if((j++) < 128)
  36.             led_on(4);
  37.         else
  38.             led_off(4);
  39.         
  40.     for(i = 0;i < 21;i++)
  41.         buffer[i-1] = buffer[i];    // 数据移位   
  42.     buffer[20] = ADC1->RDTR;    // 读出上一次转换结果
  43.     for(i = 0;i < 20;i++)
  44.         output += gain[i]*buffer[i];   // 计算结果
  45.    
  46.     ADC_SoftwareStartInsertedConv_Enable(ENABLE);
  47.     DAC_SetDAC1Data(DAC_ALIGN_12B_R,(uint16_t)(output >> 15));    // 将结果送入DAC,截位截到接近满输出
  48.     DAC_SoftwareTrigger_Enable(DAC1,ENABLE);
  49. //  while(ADC_GetBitState(ADC_FLAG_EOC) == RESET);  // 等待转换结束

  50.     printf("\n\r%4d--%8x\r\n",buffer[20],(uint16_t)(output >> 15));
  51.         do
  52.         {
  53.                 temp=SysTick->CTRL;
  54.         }
  55.         while(temp&0x01&&!(temp&(1<<16)));              // 等待时间到达   
  56.         SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        // 关闭计数器
  57.         SysTick->VAL =0X00;       // 清空计数器         
  58. }


  59. /**
  60.   * @brief  Main program.
  61.   * @param  None
  62.   * @retval None
  63.   */
  64. int main(void)
  65. {
  66.     /* 初始化 */
  67.     systick_init();
  68.     led_456_init();
  69.     usart_init();
  70.     adc_init();
  71.     dac_init();
  72.         
  73.     while (1)
  74.     {

  75.         fir_lp();
  76.         
  77.     }
  78. }[/hide]
复制代码
这个滤波器的结果还过得去,也算一个信号处理系统了,交作业的时间就到期了,好捉急啊,没时间再做其他东西了。
以下图片为不同频率时输入输出对比效果,黄色为输入,白色为输出;


IMG_20160620_210741.jpg (1.36 MB, 下载次数: 78)

IMG_20160620_210741.jpg

IMG_20160620_210749.jpg (1.41 MB, 下载次数: 64)

IMG_20160620_210749.jpg

IMG_20160620_210809.jpg (1.35 MB, 下载次数: 67)

IMG_20160620_210809.jpg

IMG_20160620_210819.jpg (1.44 MB, 下载次数: 82)

IMG_20160620_210819.jpg

IMG_20160620_210832.jpg (1.47 MB, 下载次数: 78)

IMG_20160620_210832.jpg

IMG_20160620_211310.jpg (1.45 MB, 下载次数: 83)

IMG_20160620_211310.jpg

150HzLP汉明.jpg (85.38 KB, 下载次数: 74)

150HzLP汉明.jpg
分享到:
回复

使用道具 举报

回答|共 4 个

倒序浏览

沙发

杨肉师傅

发表于 2016-6-21 01:22:22 | 只看该作者

我的部分KEIL工程:

5,ADC.rar

377.36 KB, 下载次数: 13

5,ADC_DAC.rar

378.72 KB, 下载次数: 14

6,FIR.rar

376.54 KB, 下载次数: 30

板凳

糖悦之果飞

发表于 2016-6-29 09:08:06 | 只看该作者

文章不错,将内容去经验频道一并发一下,可以有双重奖励哟http://jingyan.eeboard.com/
地板

gsy8023

发表于 2016-6-29 09:13:12 | 只看该作者

真不错,学习啦
5#

jackh

发表于 2016-8-4 10:59:25 | 只看该作者

不错, 学习一下 !!
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条