初中生
最后登录1970-1-1
在线时间 小时
注册时间2023-9-8
|
楼主 |
发表于 2023-9-21 15:05:02
|
显示全部楼层
这是我的代码
#include "adc.h"
#include "delay.h"
DMA_HandleTypeDef g_DMA_Handler; //DMA句柄
ADC_HandleTypeDef g_ADC1_Handler;//ADC句柄
u8 g_adc_dma_sta = 0; /* DMA传输状态标志, 0: 未完成 1: 已完成 */
//初始化ADC DMA
void adc_dma_init(uint32_t mar)
//void adc_dma_init(void)
{
GPIO_InitTypeDef gpio_instruct;
ADC_ChannelConfTypeDef adc_channel_conf = {0};
__HAL_RCC_ADC12_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择 选择per_ck==64MHz
/* 初始化DMA */
g_DMA_Handler.Instance = DMA1_Stream7; /* 数据流选择 */
g_DMA_Handler.Init.Request = DMA_REQUEST_ADC1; /* DMA请求ADC */
g_DMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY; /* 外设到存储器 */
g_DMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; /* 外设非增量模式 */
g_DMA_Handler.Init.MemInc = DMA_MINC_ENABLE; /* 存储器增量模式 */
g_DMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* 外设数据长度:16位 */
g_DMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; /* 存储器数据长度:16位 */
g_DMA_Handler.Init.Mode = DMA_NORMAL; /* 普通模式 */
g_DMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM; /* 中等优先级 */
g_DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
// g_DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
// g_DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE; /* 存储器突发单次传输 */
// g_DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; /* 外设突发单次传输 */
HAL_DMA_Init(&g_DMA_Handler);
__HAL_LINKDMA(&g_ADC1_Handler, DMA_Handle, g_DMA_Handler);
/* 初始化ADC */
g_ADC1_Handler.Instance=ADC1;
g_ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PER_CK/4=64/4=16MHZ
g_ADC1_Handler.Init.Resolution=ADC_RESOLUTION_10B; //10位模式
g_ADC1_Handler.Init.ScanConvMode=ADC_SCAN_DISABLE; //非扫描模式
g_ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV; //关闭EOC中断
g_ADC1_Handler.Init.LowPowerAutoWait=DISABLE; //自动低功耗关闭
g_ADC1_Handler.Init.ContinuousConvMode=ENABLE; //开启连续转换
g_ADC1_Handler.Init.NbrOfConversion=1; //1个转换在规则序列中 也就是只转换规则序列1
g_ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式
g_ADC1_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0
g_ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //软件触发
g_ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发
g_ADC1_Handler.Init.BoostMode=DISABLE; //BOOT模式关闭
g_ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN; //有新的数据的之后直接覆盖掉旧数据
g_ADC1_Handler.Init.OversamplingMode=DISABLE; //过采样关闭
g_ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_ONESHOT; //规则通道的数据选择DMA单次传输ADC数据模式
HAL_ADC_Init(&g_ADC1_Handler); //初始化
HAL_ADCEx_Calibration_Start(&g_ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准
gpio_instruct.Pin=GPIO_PIN_5; //PA5
gpio_instruct.Mode=GPIO_MODE_ANALOG; //模拟
gpio_instruct.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&gpio_instruct);
/* 配置ADC相关通道的相关函数 */
adc_channel_conf.Channel=ADC_CHANNEL_19; //通道
adc_channel_conf.Rank=ADC_REGULAR_RANK_1; //1个序列
adc_channel_conf.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样时间
adc_channel_conf.SingleDiff=ADC_SINGLE_ENDED; //单边采集
adc_channel_conf.OffsetNumber=ADC_OFFSET_NONE;
adc_channel_conf.Offset=0;
HAL_ADC_ConfigChannel(&g_ADC1_Handler,&adc_channel_conf); //通道配置
/* 配置DMA数据流请求中断优先级 */
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 3, 3);
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);
HAL_DMA_Start_IT(&g_DMA_Handler, (uint32_t)&ADC1->DR, mar, 0 ); /* 启动DMA 开启传输,完成中断 */
HAL_ADC_Start_DMA(&g_ADC1_Handler, &mar, 0); /* 触发ADC转换 使用DMA传输数据 */
}
void adc_dma_enable(uint16_t ndtr)
{
ADC1->CR &= ~(1 << 0); /* 先关闭ADC */
// DMA1_Stream7->CR &= ~(1 << 0); /* 关闭DMA传输 */
__HAL_DMA_DISABLE(&g_DMA_Handler);
while (DMA1_Stream7->CR & 0X1); /* 确保DMA可以被设置 */
DMA1_Stream7->NDTR = ndtr; /* 要传输的数据项数目 */
__HAL_DMA_ENABLE(&g_DMA_Handler);
// DMA1_Stream7->CR |= 1 << 0; /* 开启DMA传输 */
ADC_ENABLE(&g_ADC1_Handler);
// ADC1->CR |= 1 << 0; /* 重新启动ADC */
ADC1->CR |= 1 << 2; /* 启动常规转换通道 */
}
void DMA1_Stream7_IRQHandler(void)
{
if (__HAL_DMA_GET_FLAG(&g_DMA_Handler, DMA_FLAG_TCIF3_7))
{
g_adc_dma_sta = 1; /* 标记DMA传输完成 */
__HAL_DMA_CLEAR_FLAG(&g_DMA_Handler, DMA_FLAG_TCIF3_7); /* 清除DMA1 数据流7 传输完成中断 */
}
}
主函数代码:
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "sdram.h"
#include "ltdc.h"
#include "adc.h"
#define ADC_DMA_BUF_SIZE 200 /* ADC DMA采集 BUF大小 */
u16 g_adc_dma_buf[ADC_DMA_BUF_SIZE];
extern u8 g_adc_dma_sta; /* DMA传输状态标志, 0: 未完成 1: 已完成 */
int main(void)
{
uint16_t i;
Cache_Enable(); //打开L1-Cache
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz
delay_init(400); //延时初始化
uart_init(115200); //串口初始化
LED_Init(); //初始化LED时钟
KEY_Init();
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //初始化LCD
adc_dma_init((uint32_t)&g_adc_dma_buf); /* 初始化ADC DMA采集 */
// adc_dma_init();
adc_dma_enable(ADC_DMA_BUF_SIZE); /* 启动ADC DMA采集 */
while(1)
{
if (g_adc_dma_sta == 1)
{
/* 清D Cache */
SCB_InvalidateDCache();
for (i = 0;i <ADC_DMA_BUF_SIZE;i++)
{
printf("%0.3f v\r\n",((float)g_adc_dma_buf)*(3.3 / 1024));
}
g_adc_dma_sta = 0; /* 清除DMA采集完成状态标志 */
adc_dma_enable(ADC_DMA_BUF_SIZE); /* 启动下一次ADC DMA采集 */
}
// temp = adc_get_result();
// printf("V1=%0.3f v\r\n",temp*(3.3 / 4096));
LED0_Toggle;
delay_ms(100);
}
} |
|