专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
DSP
STM32F407之数字滤波
2019-07-13 19:24
发布
生成海报
站内文章
/
DSP
17513
0
1253
为了对stm32f4的ADC和DAC有更多的了解,我决定做一个实用性比较强的实验。就是数字滤波实验,利用stm32f4的DAC可以产生噪声的特点,利用它的一路DAC产生叠加噪声的信号作为原始信号。然后用ADC测量,把结果经过滤波处理后用DAC的另一通道把结果输出,用双踪示波器观察。
一阶惯性滤波器及其数字化
一阶惯性滤波器的传递函数为:
利用一阶差分法离散化,可以得到一阶惯性数字滤波算法:
其中T为采样周期,为滤波时间常数。T和必须根据信号频谱来选择。
编程实现:
a. 设定一个1024点正弦波表,用DAC1叠加噪声输出
b. 配置定时器6更新频率为1M
c. DAC的时钟为TIM6更新事件,1024点,频率大概为0.5M
d. 在TIM6的更新中断中启动一次AD转换
e. AD转换中断中做滤波处理,然后把数值送DAC2,启动一次DAC2
程序:
[plain]
view plain
copy
/************************************
标题:数字滤波实验
软件平台:IAR for ARM6.21
硬件平台:stm32f4-discovery
主频:168M
描述:用DAC1产生一路叠加了噪声的信号
用ADC通道11测量上面产生的信号
对ADC的测量结果进行滤波处理
用DAC2把滤波后的结果输出
author:小船
data:2012-02-17
*************************************/
#include
#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);
}
}
输出的信号:
用AD测量后不经过滤波直接输出:
经过滤波的输出:
结论:经过滤波后,很好地把噪声滤除了,但相位有一定的滞后,幅值会变小。
Ta的文章
更多
>>
STM32F407之数字滤波
0 个评论
模拟向服务器POST数据
0 个评论
热门文章
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮