找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

帖子
查看: 1761|回復(fù): 6
收起左側(cè)

STM32單片機(jī)使用寄存器配置ADC讀取不到數(shù)據(jù)問(wèn)題

[復(fù)制鏈接]
ID:831673 發(fā)表于 2023-3-22 00:46 | 顯示全部樓層 |閱讀模式
如題,樓主在使用stm32寄存器配置ADC電壓采樣,使用中斷獲取采樣數(shù)據(jù),實(shí)際效果中,adc配置后無(wú)法讀取不到寄存器DR的值,單片機(jī)使用stm32f103vet6

單片機(jī)代碼如下:
使用的gpio口是PC1,對(duì)應(yīng)的adc1是通道11
引腳配置:
  1. void ADC_GPIO_INIT(void)
  2. {

  3. SET_BIT(RCC->APB2ENR,RCC_APB2ENR_IOPCEN);//**開(kāi)GPIOC端口時(shí)鐘
  4. GPIOC->CRL &= ~(0xf<<4);//**模擬輸入模式 PC1
  5. }
復(fù)制代碼

ADC初始化配置
  1. void ADC_Mode_Config(void)
  2. {
  3. SET_BIT(RCC->APB2ENR,RCC_APB2ENR_ADC1EN);//**開(kāi)ADC1外設(shè)時(shí)鐘
  4. SET_BIT(RCC->CFGR,RCC_CFGR_ADCPRE_DIV6);//設(shè)置ADC分頻因子,6分頻,72/6=12MHZ[indent]
  5. ADC1->CR1=0;//**初始化
  6. ADC1->CR2=0;[/indent][indent]
  7. SET_BIT(ADC1->CR1,ADC_CR1_EOCIE);//**轉(zhuǎn)換結(jié)束后產(chǎn)生中斷
  8. SET_BIT(ADC1->CR2,ADC_CR2_CONT);//**配置連續(xù)轉(zhuǎn)換模式

  9. ADC1->SMPR1|=7<<(3*1);//**采樣周期為239.5個(gè)周期
  10. ADC1->SQR1|=0<<20;//**1個(gè)轉(zhuǎn)換

  11. SET_BIT(ADC1->CR2,ADC_CR2_ADON);//**開(kāi)啟AD轉(zhuǎn)換器[/indent][indent]
  12. SET_BIT(ADC1->CR2,ADC_CR2_RSTCAL);//**使能復(fù)位校準(zhǔn)
  13. while(READ_BIT(ADC1->CR2,ADC_CR2_RSTCAL));//**等待校準(zhǔn)結(jié)束
  14. SET_BIT(ADC1->CR2,ADC_CR2_CAL);//**使能A/D校準(zhǔn)
  15. while(READ_BIT(ADC1->CR2,ADC_CR2_CAL));//**等待校準(zhǔn)結(jié)束[/indent]
  16. ADC1->SQR3&=0XFFFFFFE0
  17. ADC1->SQR3|=11;//**通道配置

  18. NVIC_SetPriority(ADC1_2_IRQn, 1);//配置中斷優(yōu)先級(jí)
  19. NVIC_EnableIRQ(ADC1_2_IRQn);//開(kāi)中斷

  20. }

復(fù)制代碼
中斷函數(shù)
  1. void ADC_IRQHandler(void)
  2. {        
  3. if (READ_BIT(ADC1->SR,ADC_SR_EOC))
  4.   {
  5.   // 讀取ADC的轉(zhuǎn)換值
  6.   ADC_ConvertedValue = ADC1->DR;
  7.   }
  8. }
復(fù)制代碼

主函數(shù):
1.png

問(wèn)題出在ADC初始化函ADC_Mode_Config()上,我的想法是轉(zhuǎn)換完成后EOCIE產(chǎn)生一個(gè)中斷,在中斷中讀取DR寄存器的值,實(shí)際效果是讀取到的dr的值始終為0:
2.png


也試圖使用軟件開(kāi)啟配置:
ADC1->CR2|=7<<17; //軟件控制轉(zhuǎn)換
ADC1->CR2|=1<<20; //使用外部觸發(fā)(SWSTART)
SET_BIT(ADC1->CR2,ADC_CR2_SWSTAR);//**軟件設(shè)置開(kāi)始轉(zhuǎn)換
while(!(ADC1->SR&1<<1)); //等待完成

當(dāng)開(kāi)啟外部觸發(fā)EXTTRIG,并配置EXTSEL為SWSTART,在中斷優(yōu)先級(jí)配置后啟用SWSTART,串口接收不到任何信息。
回復(fù)

使用道具 舉報(bào)

ID:301191 發(fā)表于 2023-3-22 15:12 | 顯示全部樓層
頂一下
回復(fù)

使用道具 舉報(bào)

ID:123289 發(fā)表于 2023-3-22 16:27 | 顯示全部樓層
再讀CPU手冊(cè),特別關(guān)注AD部分。
回復(fù)

使用道具 舉報(bào)

ID:831673 發(fā)表于 2023-3-23 00:22 | 顯示全部樓層
yzwzfyz 發(fā)表于 2023-3-22 16:27
再讀CPU手冊(cè),特別關(guān)注AD部分。

找到原因了,問(wèn)題出在中斷上
回復(fù)

使用道具 舉報(bào)

ID:831673 發(fā)表于 2023-3-23 00:31 | 顯示全部樓層
問(wèn)題補(bǔ)充更新:
我將ADC的中斷觸發(fā)關(guān)閉,設(shè)置成單次轉(zhuǎn)換模式,直接在轉(zhuǎn)換結(jié)束后讀取DR寄存器的值,沒(méi)有通過(guò)觸發(fā)來(lái)讀取,發(fā)現(xiàn)可以正常讀取到ADC的值:
  1. static void ADCx_Mode_Config(void)
  2. {
  3. RCC->APB2ENR|=1<<9; //ADC1 時(shí)鐘使能
  4. RCC->APB2RSTR|=1<<9; //ADC1 復(fù)位
  5. RCC->APB2RSTR&=~(1<<9);//復(fù)位結(jié)束
  6. RCC->CFGR&=~(3<<14); //分頻因子清零
  7. //SYSCLK/DIV2=12M ADC 時(shí)鐘設(shè)置為 12M,ADC 最大時(shí)鐘不能超過(guò) 14M!
  8. //否則將導(dǎo)致 ADC 準(zhǔn)確度下降!
  9. RCC->CFGR|=2<<14;
  10. ADC1->CR1&=0XF0FFFF; //工作模式清零
  11. ADC1->CR1|=0<<16; //獨(dú)立工作模式
  12. ADC1->CR1&=~(1<<8); //非掃描模式
  13.        
  14. ADC1->CR2&=~(1<<1);//單次轉(zhuǎn)換模式
  15.        
  16. //ADC1->CR2|=1<<1; //連續(xù)轉(zhuǎn)換模式
  17. //ADC1->CR1|=1<<5;//開(kāi)中斷
  18.        
  19. ADC1->CR2&=~(7<<17);
  20. ADC1->CR2|=7<<17; //軟件控制轉(zhuǎn)換
  21. ADC1->CR2|=1<<20; //使用用外部觸發(fā)(SWSTART)!!! 必須使用一個(gè)事件來(lái)觸發(fā)
  22. ADC1->CR2&=~(1<<11); //右對(duì)齊
  23. ADC1->SQR1&=~(0XF<<20);
  24. ADC1->SQR1|=0<<20; //1 個(gè)轉(zhuǎn)換在規(guī)則序列中 也就是只轉(zhuǎn)換規(guī)則序列 1
  25. //設(shè)置通道 11 的采樣時(shí)間
  26. ADC1->SMPR1&=~(3*1); //通道 11 采樣時(shí)間清空
  27. ADC1->SMPR1|=7<<(3*1); //通道 11 239.5 周期,提高采樣時(shí)間可以提高精確度
  28. ADC1->CR2|=1<<0; //開(kāi)啟 AD 轉(zhuǎn)換器
  29. ADC1->CR2|=1<<3; //使能復(fù)位校準(zhǔn)
  30. while(ADC1->CR2&1<<3); //等待校準(zhǔn)結(jié)束
  31. //該位由軟件設(shè)置并由硬件清除。在校準(zhǔn)寄存器被初始化后該位將被清除。
  32. ADC1->CR2|=1<<2; //開(kāi)啟 AD 校準(zhǔn)
  33. while(ADC1->CR2&1<<2); //等待校準(zhǔn)結(jié)束
  34. //該位由軟件設(shè)置以開(kāi)始校準(zhǔn),并在校準(zhǔn)結(jié)束時(shí)由硬件清除
  35. }

  36. u16 Get_Adc(void)
  37. {
  38. ADC1->SQR3&=0XFFFFFFE0;//???? 1 ?? ch
  39. ADC1->SQR3|=ADC_Channel_11;
  40. ADC1->CR2|=1<<22; //????????
  41. while(!(ADC1->SR&1<<1)); //??????
  42. return ADC1->DR; //?? adc ?
  43. }
復(fù)制代碼


由此可見(jiàn)在串口調(diào)試助手中無(wú)法輸出內(nèi)容是由于中斷的問(wèn)題
以下是中斷EOCIE的說(shuō)明:

EOCIE:允許產(chǎn)生EOC中斷 (Interrupt enable for EOC)
該位由軟件設(shè)置和清除,用于禁止或允許轉(zhuǎn)換結(jié)束后產(chǎn)生中斷。
0:禁止EOC中斷;
1:允許EOC中斷。當(dāng)硬件設(shè)置EOC位時(shí)產(chǎn)生中斷。

那么,理論上ADC轉(zhuǎn)化完成后將產(chǎn)生EOC中斷,進(jìn)入中斷函數(shù),在中斷函數(shù)中讀取到DR的值,而實(shí)際效果是ADC在中斷這里卡死,具體原因還在尋找。
回復(fù)

使用道具 舉報(bào)

ID:831673 發(fā)表于 2023-3-23 01:14 | 顯示全部樓層
找到最終原因了,是我中斷函數(shù)名寫(xiě)錯(cuò)導(dǎo)致EOC中斷產(chǎn)生后沒(méi)法進(jìn)入中斷函數(shù)。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表