中级会员
TA的每日心情 | 奋斗 2023-9-29 16:43 |
---|
签到天数: 12 天 [LV.3]偶尔看看II
|
发表于 2023-9-9 20:08:35
|
查看: 2839 |
回复: 6 IP:中国 中国广播电视网络有限公司
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位
|
|