它使用STM32控制4通道规则转换ADC和DMA,并实现了模拟看门狗。使用库函数
时间: 2024-05-07 14:15:18 浏览: 173
,实现了以下功能:
1. 初始化ADC和DMA,设置转换规则和采样时间;
2. 启动ADC和DMA,等待转换完成;
3. 在转换完成后,触发DMA传输完成中断,并将转换结果存储在指定的缓冲区中;
4. 定时器中断用于模拟看门狗,定时器溢出时触发中断,并重新启动看门狗计时器。
下面是代码实现:
```
#include "stm32f10x.h"
#define ADC_NUM_CHANNELS 4
#define ADC_BUF_SIZE 100
__IO uint16_t adc_buf[ADC_NUM_CHANNELS][ADC_BUF_SIZE];
void ADC_DMA_Init(void);
void TIM_Init(void);
void WDG_Init(void);
int main(void) {
ADC_DMA_Init();
TIM_Init();
WDG_Init();
while (1) {
// do something
}
}
void ADC_DMA_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
// Enable GPIO clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// Configure ADC input pins
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Enable ADC1 clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// Configure ADC parameters
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = ADC_NUM_CHANNELS;
ADC_Init(ADC1, &ADC_InitStructure);
// Configure ADC channel sampling time
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239Cycles5);
// Enable DMA1 clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// Configure DMA parameters
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(ADC1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) adc_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = ADC_NUM_CHANNELS * ADC_BUF_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// Enable DMA1 channel1 interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable DMA1 channel1 transfer complete interrupt
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
// Enable ADC and DMA
ADC_Cmd(ADC1, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
// Start ADC conversions
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void TIM_Init(void) {
TIM_TimeBaseInitTypeDef TIM_InitStructure;
// Enable TIM2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// Configure TIM2 parameters
TIM_InitStructure.TIM_Period = 2000;
TIM_InitStructure.TIM_Prescaler = 7200; // 10 kHz
TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
// Enable TIM2 interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable TIM2
TIM_Cmd(TIM2, ENABLE);
// Enable TIM2 update interrupt
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
void WDG_Init(void) {
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_256);
IWDG_SetReload(0xFFF);
IWDG_ReloadCounter();
IWDG_Enable();
}
void DMA1_Channel1_IRQHandler(void) {
if (DMA_GetITStatus(DMA1_IT_TC1)) {
// DMA transfer complete
DMA_ClearITPendingBit(DMA1_IT_TC1);
// do something with adc_buf
}
}
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update)) {
// TIM2 update interrupt
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
IWDG_ReloadCounter();
}
}
```
阅读全文