CH32V307用rt-thread,ADC+DMA采样,采集到的数据只有8位,怎么回事
代码:
uint16_t AD_Value[5]; //ADC采样数据 /* 线程 3 的入口函数,ADC数据处理 */ static void thread3_ADC_entry(void *parameter) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //启用ADC1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //启用GPIOA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //启用DMA1时钟 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADC时钟分配配置,6分频(72Mhz/6=12Mhz),ADC时钟频率不能大于14Mhz GPIO_InitTypeDef GPIO_InitStructure; //定义结构体配置GPIO GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //设置GPIO口为AIN模拟输入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //设置GPIO口 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO口速度50Mhz GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); //配置ADC规则组,在规则组的序列1写入通道0,采样时间55.5个周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5); //配置ADC规则组,在规则组的序列2写入通道1,采样时间55.5个周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5); //配置ADC规则组,在规则组的序列3写入通道2,采样时间55.5个周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239Cycles5); //配置ADC规则组,在规则组的序列4写入通道3,采样时间55.5个周期 ADC_InitTypeDef ADC_InitStructure; //定义结构体配置ADC ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //设置ADC模式,独立模式 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //设置数据对齐模式,右对齐 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发源选择,不使用外部触发(使用软件触发) ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //启用连续转换模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //启用扫描模式 ADC_InitStructure.ADC_NbrOfChannel = 4; //扫描模式下用到的通道数目 ADC_Init(ADC1, &ADC_InitStructure); //初始化ADC1 DMA_InitTypeDef DMA_InitStructure; //定义结构体配置DMA DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &ADC1->RDATAR; //外设基地址(源数据地址),设置为ADC1_RDATAR寄存器 DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord; //外设数据宽度,设置为半字,16位 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址是否自增,不自增 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) AD_Value; //内存基地址,数组变量为地址,需强制转换为uint32_t DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存数据宽度,设置为为半字,16位 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址是否自增,设置为自增 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //指定外设地址为源端,传输方向为外设到内存 DMA_InitStructure.DMA_BufferSize = 4; //传输计数器,设置传输4次 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //设置DMA模式为循环模式(自动重装计数器)与软件触发不能同时使用。 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //设置不使用软件触发,即硬件触发 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //设置通道的转运优先级为中等 DMA_Init(DMA1_Channel1, &DMA_InitStructure); //初始化DMA1的通道1,ADC1的硬件触发接在DMA1的通道1上,所以必须使用DMA1通道1 DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA1通道1 ADC_DMACmd(ADC1, ENABLE); //开启ADC1的DMA触发信号 ADC_Cmd(ADC1, ENABLE); //开启ADC1 ADC_ResetCalibration(ADC1); //复位校准ADC1 while (ADC_GetResetCalibrationStatus(ADC1) == SET) ; //等待复位校准完成 ADC_StartCalibration(ADC1); //开始校准ADC1 while (ADC_GetCalibrationStatus(ADC1) == SET) ; //等待校准完成 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发ADC转换 while (1) { rt_thread_mdelay(100); } } /* 线程 2 的入口函数,OLED屏显示信息 */ static void thread2_OLED_entry(void *parameter) { while (1) { char String[16]; u8g2_ClearBuffer(&u8g2); u8g2_SetFont(&u8g2, u8g2_font_wqy15_t_chinese3); // 设置中文字符集 sprintf(String, "AD0:%d", AD_Value[0]); // 格式化字符串输出到字符串变量 u8g2_DrawStr(&u8g2, 0, 15, String); sprintf(String, "AD1:%d", AD_Value[1]); // 格式化字符串输出到字符串变量 u8g2_DrawStr(&u8g2, 0, 31, String); sprintf(String, "AD2:%d", AD_Value[2]); // 格式化字符串输出到字符串变量 u8g2_DrawStr(&u8g2, 0, 47, String); sprintf(String, "AD3:%d", AD_Value[3]); // 格式化字符串输出到字符串变量 u8g2_DrawStr(&u8g2, 0, 63, String); u8g2_SendBuffer(&u8g2); // 发送缓冲区数据 rt_thread_mdelay(100); // 延时100毫秒 } }
用rt-thread的Fin SH命令读取的数据是正常的
用DMA读取到的数据只有8位
热门产品 :
CH32L103: 32位PDUSB低功耗单片机