打印
[STM32F4]

stm32f407之数字滤波(操作寄存器)

[复制链接]
1216|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
610u|  楼主 | 2022-3-31 15:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
数字滤波


      为了对stm32f4的ADC和DAC有更多的了解,我决定做一个实用性比较强的实验。就是数字滤波实验,利用stm32f4的DAC可以产生噪声的特点,利用它的一路DAC产生叠加噪声的信号作为原始信号。然后用ADC测量,把结果经过滤波处理后用DAC的另一通道把结果输出,用双踪示波器观察。

使用特权

评论回复
沙发
610u|  楼主 | 2022-3-31 15:41 | 只看该作者
一阶惯性滤波器及其数字化

一阶惯性滤波器的传递函数为:


利用一阶差分法离散化,可以得到一阶惯性数字滤波算法:


其中T为采样周期,为滤波时间常数。T和必须根据信号频谱来选择。

使用特权

评论回复
板凳
610u|  楼主 | 2022-3-31 15:43 | 只看该作者
编程实现:

a.     设定一个1024点正弦波表,用DAC1叠加噪声输出

b.     配置定时器6更新频率为1M

c.     DAC的时钟为TIM6更新事件,1024点,频率大概为0.5M

d.     在TIM6的更新中断中启动一次AD转换

e.     AD转换中断中做滤波处理,然后把数值送DAC2,启动一次DAC2

使用特权

评论回复
地板
610u|  楼主 | 2022-3-31 15:50 | 只看该作者
程序:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片

    /************************************  
        标题:数字滤波实验  
        软件平台:IAR for ARM6.21  
        硬件平台:stm32f4-discovery  
        主频:168M  
      
        描述:用DAC1产生一路叠加了噪声的信号  
              用ADC通道11测量上面产生的信号  
              对ADC的测量结果进行滤波处理  
              用DAC2把滤波后的结果输出  
         
        author:小船  
        data:2012-02-17  
    *************************************/  
      
    #include <stm32f4xx.h>   
    #include "MyDebugger.h"  
    #include "sintable.h"   
      
    /*********变量声明********/  
    uint16_t Y0, Y1;//滤波器输出值  
    float T = 0.000001;//采样周期  
    float C = 0.00003; //滤波常数  
      
    /*********函数声明********/  
    void timer6_Init(void);  
    void ADC3_IN11_Config(void);  
    void DAC_channel2_Config(void);  
    void Generate_SinSignal_with_Noise(void);  
      
    void main ()  
    {     
      
      SCB->AIRCR = 0x05FA0000 | 0x400;  //中断优先级分组 抢占:响应=3:1  
      
      MyDebugger_Init();  
      
      ADC3_IN11_Config();  
      Generate_SinSignal_with_Noise();  
      DAC_channel2_Config();   
      timer6_Init();   
      
      while(1)  
      {  
      };  
    }  
      
    /**************************************  
      函数名:timer6_Init  
      参数:无  
      返回值:无  
      功能:设置定时器6更新频率为1M  
            定时器6更新事件为DAC1、2时钟  
            更新中断启动ADC检测  
    **************************************/  
    void timer6_Init(void)  
    {  
      /***定时器设置***/  
      RCC->APB1ENR |= (1<<4);//打开TIM6时钟  
      TIM6->PSC = 0;   
      TIM6->ARR = 83;  //使得更新事件频率为1m  
      TIM6->CR2 |=  0x00000020;//更新事件输出  
      TIM6->DIER |= 1; //使能中断  
      TIM6->CR1 |= 1; //开始计时  
    }  
      
    /**************************************  
      函数名:Generate_SinSignal_with_Noise  
      参数:无  
      返回值:无  
      功能:用DAC1产生一路叠加了噪声的信号  
    ***************************************/  
    void Generate_SinSignal_with_Noise(void)  
    {  
      /***GPIO设置***/  
      RCC->AHB1ENR |= (1<<0); //打开GPIOA时钟  
      GPIOA->MODER |= 0x00000F00;//PA4、5模拟模式  
      GPIOA->PUPDR &= 0xfffff0ff;//无上拉无下拉     
        
      /***DAC设置***/  
      RCC->APB1ENR |= (1<<29); //使能DAC时钟  
      DAC->CR &= 0xffff0000;  
      /*  
      使能DMA堵塞中断  
      使能通道1触发  
      叠加噪声  
      */  
      DAC->CR |= ( (1<<13) | (1<<2) | 0x00000040 | 0x00000800);   
      NVIC->IP[54] = 0xA0;  
      NVIC->ISER[1] |= (1<<(54-32));  
      
      /***DMA设置***/  
      RCC->AHB1ENR |= (1<<21); //使能DMA1时钟  
      DAC->CR &= ~(1<<12);//DAC dma发送模式除能  
      DMA1_Stream5->CR &= 0xFFFFFFFE; //除能DMA1_Stream5  
      while(DMA1_Stream5->CR & 0x00000001);//确保DMA可以被设置   
      DMA1->HIFCR |= 0x000004f0;//传送前清空DMA1_Stream5所有中断标志   
      DMA1_Stream5->PAR = (uint32_t)&DAC->DHR12R1;//设置外设地址  
      DMA1_Stream5->M0AR = (uint32_t)SinTable; //设置内存地址  
      DMA1_Stream5->CR |= 0x0002800;//16位数据  
      DMA1_Stream5->NDTR = 1024; //设置dma传输数据的数量  
      /*  
        设置dma通道7,即DAC1  
        优先级Medium  
        传输方向内存到外设  
        内存递增模式  
        循环模式  
      */  
      DMA1_Stream5->CR |= ( 0x0e000000 | 0x00010000 | (1<<6)  
                            | (1<<10) | (1<<8) );   
        
      DMA1_Stream5->CR |= 1; //DMA数据流5使能  
        
      DAC->CR |= (1<<0);   //DAC通道1使能  
      
      DAC->CR |= (1<<12);//DAC dma发送模式使能  
    }  
      
    /**************************************  
      函数名:ADC3_IN11_Config  
      参数:无  
      返回值:无  
      功能:用ADC通道11测量上面产生的信号  
    ***************************************/  
    void ADC3_IN11_Config(void)  
    {  
        /***GPIO设置***/  
      RCC->AHB1ENR |= (1<<2); //打开GPIOC时钟  
      GPIOC->MODER &= 0xfffffff3;//PC1模拟模式  
      GPIOC->MODER |= 0x0000000C;  
      GPIOC->PUPDR &= 0xfffffff3;//无上拉无下拉     
        
      /***ADC3设置***/  
      RCC->APB2ENR |= (1<<10); //使能ADC3时钟  
      ADC3->SQR1 = 0x00000000;//转换一个通道  
      ADC3->SQR3 = 0x0000000B;//第一个通道为ADC3_in11  
      ADC3->CR1 &= 0x00000000;   
      ADC3->CR2 &= 0x00000000;   
     //单次转换  
      ADC3->CR1 |= (1<<5);//使能转换完成中断  
      NVIC->IP[18] = 0xc0;  
      NVIC->ISER[0] |= (1<<18);   
    }  
      
    /**************************************  
      函数名:DAC_channel2_Config  
      参数:无  
      返回值:无  
      功能:用DAC2把滤波后的结果输出  
    ***************************************/  
    void DAC_channel2_Config(void)  
    {  
      /***DAC设置***/  
      RCC->APB1ENR |= (1<<29); //使能DAC时钟  
      DAC->CR &= 0x0000ffff;  
      /*  
      使能通道2触发   
      配置为软件触发  
      */  
      DAC->CR |= ( (1<<18) | (0x00380000) );   
        
      DAC->CR |= (1<<16);   //DAC通道2使能  
    }  
      
    void TIM6_DAC_IRQHandler(void)  
    {  
      if( DAC->SR & (1<<13) )  
      {  
        MyDebugger_LEDs(red, on);//亮红灯指示DAC1的DMA传输数据错误  
        DAC->SR &= ~(1<<13);   
      }  
        
      if(TIM6->SR)  
      {      
        ADC3->CR2 |= (1<<0);   //开启AD转换   
        ADC3->CR2 |= (1<<30); //规则通道转换开始  
         
        TIM6->SR &= ~(0x0001);   
      }  
    }  
      
    void ADC_IRQHandler(void)  
    {  
      if( ADC3->SR & (1<<1))  
      {  
        Y0 = (uint16_t)( (float)(( T / C ) * ADC3->DR) //滤波公式  
                          + (float)(( 1 - T / C ) * Y1) );  
        Y1 = Y0;  
        DAC->DHR12R2 = Y0;  //DAC2输出滤波后的结果  
        DAC->SWTRIGR |= (1<<1);  
         
        ADC3->SR &= ~(1<<1);  
      }  
    }  

使用特权

评论回复
5
610u|  楼主 | 2022-3-31 15:51 | 只看该作者
输出的信号:

使用特权

评论回复
6
610u|  楼主 | 2022-3-31 15:52 | 只看该作者
用AD测量后不经过滤波直接输出:

使用特权

评论回复
7
610u|  楼主 | 2022-3-31 15:53 | 只看该作者
经过滤波的输出:

使用特权

评论回复
8
610u|  楼主 | 2022-3-31 15:55 | 只看该作者
结论:经过滤波后,很好地把噪声滤除了,但相位有一定的滞后,幅值会变小。


使用特权

评论回复
9
Uriah| | 2022-10-8 09:30 | 只看该作者

使用Optional简化if判空

使用特权

评论回复
10
Bblythe| | 2022-10-8 12:29 | 只看该作者

结构化模块化的程序设计的思想,使最基本的要求

使用特权

评论回复
11
Pulitzer| | 2022-10-8 15:28 | 只看该作者

CPU借助于APB总线访问相关寄存器达到对I2C1工作模块的控制

使用特权

评论回复
12
万图| | 2023-7-1 08:27 | 只看该作者

我们从以前就有了 DefineGender 方法,要求提供的输入值必须始终为 0 或 1。

使用特权

评论回复
13
Uriah| | 2023-7-1 09:30 | 只看该作者

要将多余空间去除。对于第一个字符从第一行开始向下扫描,把那些一行中所有的点的灰度值全为0的点去掉,直到扫描到有一行不全为0时为止。

使用特权

评论回复
14
帛灿灿| | 2023-7-1 11:26 | 只看该作者

需要加上一定的工作电压

使用特权

评论回复
15
Bblythe| | 2023-7-1 12:29 | 只看该作者

标志寄存器用于反应处理器的状态和运算结果的某些特征以及控制指令的执行。

使用特权

评论回复
16
周半梅| | 2023-7-1 14:25 | 只看该作者

TIM4、UART1初始化代码只是些各种相关基本配置,不跟别的外设有关联

使用特权

评论回复
17
Pulitzer| | 2023-7-1 15:28 | 只看该作者

优良的文本处理工具,工作时它会扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式

使用特权

评论回复
18
周半梅| | 2023-7-1 16:31 | 只看该作者

STM32芯片中有多个工作时钟源的外设很常见

使用特权

评论回复
19
童雨竹| | 2023-7-1 17:24 | 只看该作者

显然直接调用的话,那么调用线程会被阻塞暂停

使用特权

评论回复
20
Wordsworth| | 2023-7-1 18:27 | 只看该作者

创建、重命名、查看、删除项目分支,通过 Git 做项目开发时,一般都是在开发分支中进行,开发完成后合并分支到主干。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

517

帖子

0

粉丝