CH32V307用rt-thread,ADC+DMA采樣,采集到的數(shù)據(jù)只有8位,怎么回事

CH32V307用rt-thread,ADC+DMA采樣,采集到的數(shù)據(jù)只有8位,怎么回事

代碼:

uint16_t?AD_Value[5];???????????//ADC采樣數(shù)據(jù)

/*?線程?3?的入口函數(shù),ADC數(shù)據(jù)處理?*/
static?void?thread3_ADC_entry(void?*parameter)
{
????RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,?ENABLE);????//啟用ADC1時(shí)鐘
????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,?ENABLE);???//啟用GPIOA時(shí)鐘
????RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,?ENABLE);??????//啟用DMA1時(shí)鐘

????RCC_ADCCLKConfig(RCC_PCLK2_Div6);???????//ADC時(shí)鐘分配配置,6分頻(72Mhz/6=12Mhz),ADC時(shí)鐘頻率不能大于14Mhz

????GPIO_InitTypeDef?GPIO_InitStructure;????????????????//定義結(jié)構(gòu)體配置GPIO
????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AIN;???????//設(shè)置GPIO口為AIN模擬輸入模式
????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_0?|?GPIO_Pin_1?|?GPIO_Pin_2?|?GPIO_Pin_3;????//設(shè)置GPIO口
????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;???//設(shè)置GPIO口速度50Mhz
????GPIO_Init(GPIOA,?&GPIO_InitStructure);??????????????//初始化GPIOA

????ADC_RegularChannelConfig(ADC1,?ADC_Channel_0,?1,?ADC_SampleTime_239Cycles5);?//配置ADC規(guī)則組,在規(guī)則組的序列1寫入通道0,采樣時(shí)間55.5個(gè)周期
????ADC_RegularChannelConfig(ADC1,?ADC_Channel_1,?2,?ADC_SampleTime_239Cycles5);?//配置ADC規(guī)則組,在規(guī)則組的序列2寫入通道1,采樣時(shí)間55.5個(gè)周期
????ADC_RegularChannelConfig(ADC1,?ADC_Channel_2,?3,?ADC_SampleTime_239Cycles5);?//配置ADC規(guī)則組,在規(guī)則組的序列3寫入通道2,采樣時(shí)間55.5個(gè)周期
????ADC_RegularChannelConfig(ADC1,?ADC_Channel_3,?4,?ADC_SampleTime_239Cycles5);?//配置ADC規(guī)則組,在規(guī)則組的序列4寫入通道3,采樣時(shí)間55.5個(gè)周期

????ADC_InitTypeDef?ADC_InitStructure;??????????????????????//定義結(jié)構(gòu)體配置ADC
????ADC_InitStructure.ADC_Mode?=?ADC_Mode_Independent;??????//設(shè)置ADC模式,獨(dú)立模式
????ADC_InitStructure.ADC_DataAlign?=?ADC_DataAlign_Right;??//設(shè)置數(shù)據(jù)對齊模式,右對齊
????ADC_InitStructure.ADC_ExternalTrigConv?=?ADC_ExternalTrigConv_None;?//外部觸發(fā)源選擇,不使用外部觸發(fā)(使用軟件觸發(fā))
????ADC_InitStructure.ADC_ContinuousConvMode?=?ENABLE;??????//啟用連續(xù)轉(zhuǎn)換模式
????ADC_InitStructure.ADC_ScanConvMode?=?ENABLE;????????????//啟用掃描模式
????ADC_InitStructure.ADC_NbrOfChannel?=?4;?????????????????//掃描模式下用到的通道數(shù)目
????ADC_Init(ADC1,?&ADC_InitStructure);?????????????????????//初始化ADC1

????DMA_InitTypeDef?DMA_InitStructure;??????????????????????//定義結(jié)構(gòu)體配置DMA
????DMA_InitStructure.DMA_PeripheralBaseAddr?=?(uint32_t)?&ADC1->RDATAR;?//外設(shè)基地址(源數(shù)據(jù)地址),設(shè)置為ADC1_RDATAR寄存器
????DMA_InitStructure.DMA_PeripheralDataSize?=?DMA_MemoryDataSize_HalfWord;?//外設(shè)數(shù)據(jù)寬度,設(shè)置為半字,16位
????DMA_InitStructure.DMA_PeripheralInc?=?DMA_PeripheralInc_Disable;????//外設(shè)地址是否自增,不自增
????DMA_InitStructure.DMA_MemoryBaseAddr?=?(uint32_t)?AD_Value;??????????//內(nèi)存基地址,數(shù)組變量為地址,需強(qiáng)制轉(zhuǎn)換為uint32_t
????DMA_InitStructure.DMA_MemoryDataSize?=?DMA_MemoryDataSize_HalfWord;?//內(nèi)存數(shù)據(jù)寬度,設(shè)置為為半字,16位
????DMA_InitStructure.DMA_MemoryInc?=?DMA_MemoryInc_Enable;?????????????//內(nèi)存地址是否自增,設(shè)置為自增
????DMA_InitStructure.DMA_DIR?=?DMA_DIR_PeripheralSRC;??????????????????//指定外設(shè)地址為源端,傳輸方向?yàn)橥庠O(shè)到內(nèi)存
????DMA_InitStructure.DMA_BufferSize?=?4;???????????????????????????????//傳輸計(jì)數(shù)器,設(shè)置傳輸4次
????DMA_InitStructure.DMA_Mode?=?DMA_Mode_Circular;?????????????????????//設(shè)置DMA模式為循環(huán)模式(自動重裝計(jì)數(shù)器)與軟件觸發(fā)不能同時(shí)使用。
????DMA_InitStructure.DMA_M2M?=?DMA_M2M_Disable;????????????????????????//設(shè)置不使用軟件觸發(fā),即硬件觸發(fā)
????DMA_InitStructure.DMA_Priority?=?DMA_Priority_Medium;???????????????//設(shè)置通道的轉(zhuǎn)運(yùn)優(yōu)先級為中等
????DMA_Init(DMA1_Channel1,?&DMA_InitStructure);????????????????????????//初始化DMA1的通道1,ADC1的硬件觸發(fā)接在DMA1的通道1上,所以必須使用DMA1通道1

????DMA_Cmd(DMA1_Channel1,?ENABLE);?//啟動DMA1通道1
????ADC_DMACmd(ADC1,?ENABLE);???????//開啟ADC1的DMA觸發(fā)信號
????ADC_Cmd(ADC1,?ENABLE);??????????//開啟ADC1

????ADC_ResetCalibration(ADC1);?????????????????????????//復(fù)位校準(zhǔn)ADC1
????while?(ADC_GetResetCalibrationStatus(ADC1)?==?SET)
????????;?//等待復(fù)位校準(zhǔn)完成
????ADC_StartCalibration(ADC1);?????????????????????????//開始校準(zhǔn)ADC1
????while?(ADC_GetCalibrationStatus(ADC1)?==?SET)
????????;??????//等待校準(zhǔn)完成

????ADC_SoftwareStartConvCmd(ADC1,?ENABLE);?????????????//軟件觸發(fā)ADC轉(zhuǎn)換
????while?(1)
????{

????????rt_thread_mdelay(100);
????}
}

/*?線程?2?的入口函數(shù),OLED屏顯示信息?*/
static?void?thread2_OLED_entry(void?*parameter)
{
????while?(1)
????{
????????char?String[16];
????????u8g2_ClearBuffer(&u8g2);
????????u8g2_SetFont(&u8g2,?u8g2_font_wqy15_t_chinese3);?//?設(shè)置中文字符集
????????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);?//?發(fā)送緩沖區(qū)數(shù)據(jù)
????????rt_thread_mdelay(100);??//?延時(shí)100毫秒
????}
}


用rt-thread的Fin SH命令讀取的數(shù)據(jù)是正常的

1689188661152084.png

用DMA讀取到的數(shù)據(jù)只有8位

1689188661927673.jpg


你仿真一下試試,可能是你顯示的問題,你把(AD_Value&0xf00)>>8,把這個(gè)數(shù)格式化輸出一下看看是不是0.


直接串口打印輸出也是8位的數(shù)據(jù),應(yīng)該不是顯示問題


(AD_Value&0xf00)>>8這個(gè)格式輸出,確實(shí)是輸出0了,證明確實(shí)只讀取到8位數(shù)據(jù)


AD接口接3.3V時(shí)顯示255,接GND時(shí)顯示5左右


好像是DMA搬運(yùn)的問題,我將ADC數(shù)據(jù)對齊設(shè)為左對齊,應(yīng)該讀取到數(shù)據(jù)為0xFFF0,但DMA搬運(yùn)后讀取到的是0xF0,只搬了8位數(shù)據(jù)


將DMA部分的代碼復(fù)制官方的就可以了,但是我沒發(fā)現(xiàn)跟我原先的代碼有區(qū)別

官方的:

????DMA_InitTypeDef?DMA_InitStructure;??????????????????????//定義結(jié)構(gòu)體配置DMA
????DMA_InitStructure.DMA_PeripheralBaseAddr?=?(u32)?&ADC1->RDATAR;?//配置外設(shè)地址為ADC數(shù)據(jù)寄存器地址
????DMA_InitStructure.DMA_MemoryBaseAddr?=?(u32)?AD_Value;??????????//配置存儲器地址為讀取ADC值地址
????DMA_InitStructure.DMA_DIR?=?DMA_DIR_PeripheralSRC;??????????????//配置數(shù)據(jù)源為外設(shè),即DMA傳輸方式為外設(shè)到存儲器
????DMA_InitStructure.DMA_BufferSize?=?4;???????????????????????????//設(shè)置DMA數(shù)據(jù)緩沖區(qū)大小
????DMA_InitStructure.DMA_PeripheralInc?=?DMA_PeripheralInc_Disable;//設(shè)置DMA外設(shè)遞增模式關(guān)閉
????DMA_InitStructure.DMA_MemoryInc?=?DMA_MemoryInc_Enable;?????????//設(shè)置DMA存儲器遞增模式開啟
????DMA_InitStructure.DMA_PeripheralDataSize?=?DMA_PeripheralDataSize_HalfWord;?//設(shè)置外設(shè)數(shù)據(jù)大小為半字,即兩個(gè)字節(jié)
????DMA_InitStructure.DMA_MemoryDataSize?=?DMA_MemoryDataSize_HalfWord;?????????//設(shè)置存儲器數(shù)據(jù)大小為半字,即兩個(gè)字節(jié)
????DMA_InitStructure.DMA_Mode?=?DMA_Mode_Circular;?????//設(shè)置DMA模式為循環(huán)傳輸模式
????DMA_InitStructure.DMA_Priority?=?DMA_Priority_High;?//設(shè)置DMA傳輸通道優(yōu)先級為高,當(dāng)使用一?DMA通道時(shí),優(yōu)先級設(shè)置不影響
????DMA_InitStructure.DMA_M2M?=?DMA_M2M_Disable;????????//因?yàn)榇薉MA傳輸方式為外設(shè)到存儲器,因此禁用存儲器到存儲器傳輸方式
????DMA_Init(DMA1_Channel1,?&DMA_InitStructure);????????//初始化DMA1的通道1,ADC1的硬件觸發(fā)接在DMA1的通道1上,所以必須使用DMA1通道1


原先的:

DMA_InitTypeDef?DMA_InitStructure;??????????????????????//定義結(jié)構(gòu)體配置DMA
????DMA_InitStructure.DMA_PeripheralBaseAddr?=?(u32)?&ADC1->RDATAR;?//外設(shè)基地址(源數(shù)據(jù)地址),設(shè)置為ADC1_RDATAR寄存器
????DMA_InitStructure.DMA_PeripheralDataSize?=?DMA_MemoryDataSize_HalfWord;?//外設(shè)數(shù)據(jù)寬度,設(shè)置為半字,16位
????DMA_InitStructure.DMA_PeripheralInc?=?DMA_PeripheralInc_Disable;????//外設(shè)地址是否自增,不自增
????DMA_InitStructure.DMA_MemoryBaseAddr?=?(u32)?AD_Value;??????????//內(nèi)存基地址,數(shù)組變量為地址,需強(qiáng)制轉(zhuǎn)換為uint32_t
????DMA_InitStructure.DMA_MemoryDataSize?=?DMA_MemoryDataSize_HalfWord;?//內(nèi)存數(shù)據(jù)寬度,設(shè)置為為半字,16位
????DMA_InitStructure.DMA_MemoryInc?=?DMA_MemoryInc_Enable;?????????????//內(nèi)存地址是否自增,設(shè)置為自增
????DMA_InitStructure.DMA_DIR?=?DMA_DIR_PeripheralSRC;??????????????????//指定外設(shè)地址為源端,傳輸方向?yàn)橥庠O(shè)到內(nèi)存
????DMA_InitStructure.DMA_BufferSize?=?4;???????????????????????????????//傳輸計(jì)數(shù)器,設(shè)置傳輸4次
????DMA_InitStructure.DMA_Mode?=?DMA_Mode_Circular;?????????????????????//設(shè)置DMA模式為循環(huán)模式(自動重裝計(jì)數(shù)器)與軟件觸發(fā)不能同時(shí)使用。
????DMA_InitStructure.DMA_M2M?=?DMA_M2M_Disable;????????????????????????//設(shè)置不使用軟件觸發(fā),即硬件觸發(fā)
????DMA_InitStructure.DMA_Priority?=?DMA_Priority_High;???????????????//設(shè)置通道的轉(zhuǎn)運(yùn)優(yōu)先級為中等
????DMA_Init(DMA1_Channel1,?&DMA_InitStructure);????????????????????????//初始化DMA1的通道1,ADC1的硬件觸發(fā)接在DMA1的通道1上,所以必須使用DMA1通道1



明顯是DMA外設(shè)寬度與地址寬度不一致,

?DMA_PeripheralDataSize_HalfWord
DMA_MemoryDataSize_HalfWord;

用錯(cuò)宏了你


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频