使用c语言设计程序实现平均值滤波,采用定时中断进行AD采样及滤波,程序适用于STM32
时间: 2023-12-10 20:41:10 浏览: 101
下面是一个简单的使用C语言实现平均值滤波的程序,采用定时中断进行AD采样及滤波,适用于STM32开发板。
首先,需要在STM32的头文件中定义定时器和ADC的相关寄存器地址。
```
#define TIM2_CR1 (*((volatile unsigned long *)0x40000000))
#define TIM2_DIER (*((volatile unsigned long *)0x4000000C))
#define TIM2_SR (*((volatile unsigned long *)0x40000010))
#define TIM2_EGR (*((volatile unsigned long *)0x40000014))
#define TIM2_CNT (*((volatile unsigned long *)0x40000024))
#define TIM2_PSC (*((volatile unsigned long *)0x40000028))
#define TIM2_ARR (*((volatile unsigned long *)0x4000002C))
#define RCC_APB2ENR (*((volatile unsigned long *)0x40021018))
#define ADC_CR2 (*((volatile unsigned long *)0x40012408))
#define ADC_SQR3 (*((volatile unsigned long *)0x40012434))
#define ADC_DR (*((volatile unsigned long *)0x4001244C))
#define GPIOC_CRH (*((volatile unsigned long *)0x40011004))
```
接下来,定义全局变量和函数。
```
#define FILTER_SIZE 10
uint16_t filter[FILTER_SIZE];
uint16_t filter_sum = 0;
uint8_t filter_index = 0;
void TIM2_IRQHandler(void);
void adc_init(void);
void tim_init(void);
```
在主函数中,初始化ADC和定时器,并开启中断。
```
int main(void)
{
adc_init();
tim_init();
NVIC_SetPriority(TIM2_IRQn, 0);
NVIC_EnableIRQ(TIM2_IRQn);
while(1);
}
```
ADC初始化函数如下:
```
void adc_init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC_CRH &= ~(GPIO_CRH_CNF0 | GPIO_CRH_MODE0);
GPIOC_CRH |= GPIO_CRH_MODE0_1;
ADC_CR2 |= ADC_CR2_ADON;
ADC_CR2 |= ADC_CR2_CAL;
while (ADC_CR2 & ADC_CR2_CAL);
ADC_SQR3 &= ~ADC_SQR3_SQ1;
ADC_SQR3 |= 0x0A;
ADC_CR2 |= ADC_CR2_EXTSEL;
ADC_CR2 |= ADC_CR2_EXTTRIG;
ADC_CR2 |= ADC_CR2_ADON;
}
```
定时器初始化函数如下:
```
void tim_init(void)
{
RCC_APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2_CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
TIM2_PSC = 72 - 1;
TIM2_ARR = 1000 - 1;
TIM2_DIER |= TIM_DIER_UIE;
TIM2_EGR |= TIM_EGR_UG;
TIM2_CR1 |= TIM_CR1_CEN;
}
```
定时器中断函数如下:
```
void TIM2_IRQHandler(void)
{
if (TIM2_SR & TIM_SR_UIF)
{
TIM2_SR &= ~TIM_SR_UIF;
uint16_t adc_value = ADC_DR;
filter_sum -= filter[filter_index];
filter_sum += adc_value;
filter[filter_index] = adc_value;
filter_index = (filter_index + 1) % FILTER_SIZE;
uint16_t avg_value = filter_sum / FILTER_SIZE;
}
}
```
在定时器中断函数中,先读取ADC值,然后将其加入到滤波器中,并计算滤波器的平均值。
注意:在使用TIM2_CR1寄存器之前,需要先将RCC_APB1ENR中的TIM2EN位置1,以使能TIM2定时器。同样,在使用ADC_CR2寄存器之前,需要将RCC_APB2ENR中的ADC1EN位置1,以使能ADC1模块。
以上就是一个简单的使用C语言实现平均值滤波的程序,采用定时中断进行AD采样及滤波,适用于STM32开发板。
阅读全文