智能车制作

 找回密码
 注册

扫一扫,访问微社区

STM32论坛
查看: 6658|回复: 2
打印 上一主题 下一主题

STM32F4演示例程之DAC数字滤波器

[复制链接]

489

主题

1691

帖子

1

精华

管理员

网站创始人&站长

Rank: 11Rank: 11Rank: 11Rank: 11

积分
85681

特殊贡献奖章资源大师奖章论坛骨干奖章推广达人奖章优秀版主奖章热心会员奖章论坛元老奖章在线王奖章活跃会员奖章优秀会员奖章

QQ
威望
56815
贡献
17296
兑换币
13082
注册时间
2007-6-8
在线时间
5785 小时
跳转到指定楼层
1#
发表于 2012-5-15 00:17:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者:小船   
/************************************
    标题:数字滤波器
    软件平台: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 = 0x05AF0000 | 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);
  }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

22

主题

1613

帖子

1

精华

跨届大侠

Rank: 10Rank: 10Rank: 10

积分
6784
QQ
威望
2910
贡献
1540
兑换币
1579
注册时间
2012-3-17
在线时间
1167 小时
2#
发表于 2012-5-15 00:45:24 | 只看该作者
来支持一个
回复 支持 反对

使用道具 举报

26

主题

913

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
5207

活跃会员奖章在线王奖章优秀会员奖章论坛元老奖章

威望
2267
贡献
1804
兑换币
117
注册时间
2011-3-16
在线时间
568 小时
3#
发表于 2012-5-15 12:15:53 | 只看该作者
谢谢论坛大哥分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|亿加合和智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-5-20 02:02 , Processed in 0.043851 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表