stm32ADC多通道采样例程HAL库_第1页
stm32ADC多通道采样例程HAL库_第2页
stm32ADC多通道采样例程HAL库_第3页
stm32ADC多通道采样例程HAL库_第4页
stm32ADC多通道采样例程HAL库_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Stm32基于HAL库ADC多通道采样例程1、用cubemx建立工程,cubemx5.3.0版本,芯片型号:stm32f103zet6(1)开启外部高速时钟HSE,配置系统时钟为72MSystemCareRCCModeandConfiguration□MAGPIOIWDGConfiguration「.F酿rMH(H呻1fMdNWT40<M*E岬SystemCareRCCModeandConfiguration□MAGPIOIWDGConfiguration「.F酿rMH(H呻1fMdNWT40<M*E岬ElrircKm<W1c]FkFdTFCLM|iiH4ClKtRhiFCLKnw热小玷%|UHE注意:ADC1时钟配置为9MHz(2)配置串口1,设置好波特率并开启串口中断USART1ModeandConfiguraliDnCategoriesA->IModeAnalogModeAsynchroncusHardwareFlowControl(RS232)DisableTimersConnectivity▼oModeAsynchronous.AnalogHaid^ait-owCentral(RS232:-DisableTimersConfigurationResetConfigurationUSART11152D0Hitse8Bits(includingParity)None1CategoriesA->IModeAnalogModeAsynchroncusHardwareFlowControl(RS232)DisableTimersConnectivity▼oModeAsynchronous.AnalogHaid^ait-owCentral(RS232:-DisableTimersConfigurationResetConfigurationUSART11152D0Hitse8Bits(includingParity)None1ReceiveandT^nsmir1SSamples♦IWICSettings•DMASet-tings •CTIDSo:trgsQParameterSailings•UserConstantsConfigurethebelowparameters:□ART』UART5USART2USART3WordLengthvAdvancedParameters□alaDirectionOverSamplingConnect^/vCANHSP/1CI2C1SDIOSPI1SPI2SPI3UART4UARTSUSART1USART2USART3USBCanfigurationResetConfigurationSNVICSettings•DMASettingsCANHSP/1CI2C1SDIOSPI1SPI2SPI3UART4UARTSUSART1USART2USART3USBCanfigurationResetConfigurationSNVICSettings•DMASettings•GPIOSettings♦ParameterSettingsNVICInterruptTabeUSART1globalmternjpitPreemptionPriorit/♦Ua甘「Constaint号SubPriority2、启用ADC1通道1,3,4,5,6注意要先设置好通道数量才能配置,各自ADC通道的参数。Rank是转换顺序,我们按1,2,3,4,5的顺序分别对应ADC1通道0,1,4,5,6。多通道采样要开启扫描工作模式,在这里我们还有开启连续转换方式,连续转换是在ADC转换按照

约定的转换顺序全部通道完成一次转换后,又自动启动下一次转换。ADC1ModeandConfi-gurationQINOQIN1□IN2□IN3QIN4□IN5QIN6□IN7C.onfigiura.tianResetConfiguration•ParameterSettings♦UserConstants••ParameterSettings♦UserConstants•NVICSettings♦DMASettings♦GPIOSeltingsConfigurethebelowparameters:Search(Cft.+FlDataAlignmentRightalignment数据右对齐ScanConversionModeEnabled便能扫描模式ContinuousConversionMedeEnabled使能连缅獭模式DiscontinuousConversionModeDisabledR0gular_Conv0rsionModgEnableRegularC&nversionsEnable使育羸换国首规则NumberOfComersicn5^WADC涉为5ExternalTriggerConversionSourceRegularConversionlaunchedbysoftwareADCy Rank1转换顺序1ChannelChannel0ffiioSamplingTine239.6Cycles栗祥时间7 Rank2ChannelChannel1通道1SamplingTine239.5Cycles> Rank> Rank3 ,余下通道按顺序配置> Rank5>ADC_njected_ConversionMode3、启用ADC转换DMA传输,多通道转换时要启用ADC的DMA传输,才能在相应的通道转换完成后,DMA自动去获取转换值。中断方式没法在多通道采样时使用,因为在多通道扫描模式下,只有在最后一个通道转换结束时才会产生中断请求。而ADC数据寄存器是共用的,这时候进入中断取值只能得到一个通道的数值。

DataWidthMemoryI~IIHIT门ADC1DMA1Channel1PeripheralTdMemoryLow■■DMARequestSettingsPeripheralModeIncrementAddress□Circular7HalfWt>rd▼HalfWord”DataWidthMemoryI~IIHIT门ADC1DMA1Channel1PeripheralTdMemoryLow■■DMARequestSettingsPeripheralModeIncrementAddress□Circular7HalfWt>rd▼HalfWord”ConfigurationResetConfi3Lrator□MARequestDeleteDirection♦ParameterS&ttiigs*Use,Corstan:s■NVICSettings•DMASettings♦CPIC1EiettncsChanrel4、到此,基础配置和ADC通道配置已经完成,接着我们设置工程名称和保存路径等就可以了,一般工程名和保存路径最好不要有中文,不然可能会出现一些意想不到的问题,在测试的过程中就遇到工程名或者保存路径中都用英文但是词组名称之间用空格隔开,在打开生成的工程文件后,向新建的分类文件夹中添加自己写的xxx.c文件,就导致keil软件卡死,不知道是keil软件还是cubemx的问题。-ProjectSettingsProjectNameFiveChannelsVoltageSaEplingProjectLtxalionC:\Users^senty\Desktop^jcubemx^adcSamplingC:\Us9ns^s□nty\Desktopk:ubenriiX:\a.dcSamplingVFh/eChanneIsVoltageSamplinglToDl^hainFdd台「LacationApplicationStructureTookhain/-ProjectSettingsProjectNameFiveChannelsVoltageSaEplingProjectLtxalionC:\Users^senty\Desktop^jcubemx^adcSamplingC:\Us9ns^s□nty\Desktopk:ubenriiX:\a.dcSamplingVFh/eChanneIsVoltageSamplinglToDl^hainFdd台「LacationApplicationStructureTookhain/IDEMinVersion□GeneraleL□DonotgeneratethemainQMDK-ARMI yV5.27BasicPpjectCodeG白血「式。「-STM32CuteMCUpackagesandembeddedsoftwarepacks OCopyallusedlibrariesintotheprojRttfolderProjectCodeGenegE「(*)CnpyrnlytheProjectCodeGenegE「OAddnecessarylibraryfilesasreferenceinthetoolchainprojectccnfigurationfileGeneratedfiles SGenerateperipheralinitializationas日pairof".€:/.h'filesperperipheral□Backuppreviouslygeneratedfileswhenre-generatingS&叩UserCodewhenre-generatingDeletepreviouslygeneratedfileswhennotre-generated5、设置好工程名称和路径后就可以生成代码了,生成代码后我们选择打开工程。„国CodeGeneration XThsCode/successfullygen@rat@dunderCrs/senty/Desktop/cubemx/adcSampling/FrvsChanneVoItageSamplingOpenFoldsrIOpenProjectIClose接着我们开始编写代码(1)首先我们要修改main函数的一个错误,就是在初始化时要把MX_DMA_Init()函数放在MX_ADC1_Init()函数之前执行,cubemx生成代码时MX_DMA_Init()是在ADC初始化函数之后。如果在后面则转换时打印输出的ADC值,大多数都为0,具体原因就不知道是怎么回事了,应该是cubemx这个版本还不太稳定。接下来我们在usart.c文件中增加一些代码1)增加printf重定向到串口的代码,并定义一个串口接收到数据的标志变量和数据缓冲数组。作用是在我们用串口调试助手给单片机发送数据时才打印输出ADC数据。uint8_tRecFlag,RxBuf[512];

21222324252€27221222324252€272329SO3132333435363738394041f'USERCODE3EGIN07#in.cl-jde"st-dio.#in.cl'ade"atrinc.tinuin.t8_tRecFlag,RxBaf[512];〃〃堂定向C库函数8i^tfg.USARTxstruct_FILE"标准库需要的支持函数EHinthandle;intfputcflntch,FILE-fJ早]while(2115工七1.工11日仁311仁已-:>酬&0乂40)^口):,/循环发送,直到发送完毕ri'jaitJ..Instance->DR=(nint3_t}cn;refarnfcri);/':USERCODEEND0〃【代码】:////重定向c库函数printf到USARTxstruct__FILE//标准库需要的支持函数{inthandle;};intfputc(intch,FILE*f){while((huart1.Instance->SR&0X40)==0);//循环发送,直到发送完毕huart1.Instance->DR=(uint8_t)ch;return(ch);}2)编写串口数据接收函数voidMy_UsartDateRec(UART_HandleTypeDef*huart),这里就不在回调函数中编写了,然后stm32f1xx_it.c文件中的串口中断函数中调用这个函数来接收串口数据。此外我们还需要在串口初始化函数voidHAL_UART_MspInit(UART_HandleTypeDef*uartHandle)中,增力口使能串口接收中断和空闲中断。__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//使能接收中断__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);〃使能空闲中断

E5tt5r7tS69707.L727373757tE5tt5r7tS69707.L727373757t777375803.L乳S3B4853t378339SQ91929354359t973三95日{GFID_InitTypeDefSPIO_I^itStract={j?;日{if^uartHandle—:>Instance==USARTl)□!/*USERCODE3EGZNUSARTl_M5pInit/*USERCODEEIJDUSAKTl_MEpInlt0*7/、USART1clackenable*/_HAL_RCC_USART2_CLZ_EETAELE();HALRCC_GFIOA_CLK_ENABLE\;IE] 7^*USART1-GFIOConfigurationPA3 :>USART1_TXPA10 >USART1RX-*/一GPIQ_I^itStruct.Pin=&PID_PIN_S;GPID^I^itStrj.ct.Mode=GPZO_MDDE_AF_PP;SPIO^I^itStr-JCt.Speed=3PID_5FEED_FREQ_HZS?i;HAL_GFIC_Init(GPIOAf£G-PIO_InitStract);GPIO_Initserver.Fin=&PID_PIM_1Q;GPIO_InitStrJ.ct.Mode=GPIO_M0DE_INPUT;GPIo2lTiitSCrj.ct.Pull=GPIO^NOPUKL;HM._GFI0_l7Lit(GPIO-A,£&PID_InitSt:rJGb);汴U5ART1inteiiapt二3it7HAL_NVIC_SetPriority(USART1_IRQnf二.二斗;HAL2NVIC2E^ableIRQ(USART1_IRQnJ;/*USERCODE三EGHHUSART1Msplnit1'/__HAL_HART_ERAELE_工T(.hua^ta;UART_工R_RXNEjT 史音,理夜甲肝二HALluART二ENABLe]工T(ihaarZlrUART二工T二工DLE1:'/便肓苣空闲中断1001Q1■Lm1过1001Q1130131130131132133134135A13613713B1391^0141」1^2IL里31仃1^5146!■€7JLTB//EntH_CC£B,E=OJstar1cunsignedintnum;"接收计裁/*USEftCODEEEGLUT1*/voidMJ/JSdILDiteElec(BARIBdDdLleT^-tEtef*hUd£cF门登询是否发生了空闲中断ifIHALUC&KTSETFLAS(kuaitHDARTETJidrIDLEJ!-E£5ET££H1LHARTSETITSCCTRCE|huaztrUAETITIDLE)!-RESET]ReoF二却=二门收到数Wnum=C';_HAL_UAP.T_CLEAP._rDLEFLAG(nuarrJ:门滑降空闲中断elseIT|&LB.LUBcRTSETIT5DCJRCE(Jiu.ar-ErUAET_IT_RKNT>!・旺3口卜『了帧传轮未完成;接字节接收if(mm<5izea.f(RkBll£)jJ।1'港冲区未;芮]U:Eur|nKnL+*]=(uintac|sftiuarc->liL3T;arice->Dn)jelse打键冲区溢出_,CETHp=nuari:->Instance->ER;HAZQAHTCLEARFTA&(huazt,UART_FLfijG_RM:EfE|>;150L>151/*口非KCODEEm17152记得在stm32f1xx_it.c文件开始部分包含usart.h头文件。

29 /*USSRCOD:EENDHeadei2021 /*Incl'ades 22#incl'ade^main.hn23#incl-aderrstm3211xx_it.24 /*Piivateincl'iides 25八USSRCOD:EBEGINIzicl-ades72€#incl'ade"'ma工七.三开27 /*USSRCOD:EENDIncl-Jdes黄/22522022122222322422522€22522022122222322422522€22722322-9236/*USERCODE3EGINUSARTlIRQnQ*//*USERCODEENDUSARTl_IRQnQ*/HAI._UART_IRQHandler(S:riaartl);/*UBE及UCEiE三EG工M口5或11工£Ori1*/My_UsartD3t&Rec;^^^^^SEm55T3E^!Tn^W!EI^^^n!Si17/*USERCODEBEGIN1*■'/【代码】:voidMy_UsartDateRec(UART_HandleTypeDef*huart){//uint8_ttemp=0;staticunsignedintnum;//接收计数//查询是否发生了空闲中断if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)!=RESET&&__HAL_UART_GET_IT_SOURCE(huart,UART_IT_IDLE)!=RESET){RecFlag=1;//收到数据num=0;_HAL_UART_CLEAR_IDLEFLAG(huart);//清除空闲中断}elseif(_HAL_UART_GET_IT_SOURCE(huart,UART_IT_RXNE)!=RESET)//帧传输未完成,按字节接收{if(num<sizeof(RxBuf))//缓冲区未满RxBuf[num++]=(uint8_t)(huart->Instance->DR);// else//缓冲区溢出// temp=huart->Instance->DR;__HAL_UART_CLEAR_FLAG(huart,UART_FLAG_RXNE);}}(2)在adc.c文件中增加代码

1)定义采样次数和通道数量,ADC数据保存数组2021222320212223242S262723293。3132333435363丁#include"adc.?1rl/*USERCODE3EGIMQ*/|includenstring.h"^defi^eM23”采样次数^defi^eKS”通道数EJ#ifK>_volatileJiin七工E_tNDCJJal/]H];〃多个通道定义成数组^FelsejintlttADCValje;^endifGet;ADCtiir.es=2QfdiannelHums;//采样次数和通道数volatile ADC_Val3uf[LQC]={Q?;//1QQ=2Q--5ADC_VaLB^f/£USERCODEENDQ*/【代码】:#include"adc.h"/*USERCODEBEGIN0*/#include"string.h"defineM20//采样次数defineN5//通道数ifN>1volatileuint16_tADC_Value[N];//多个通道定义成数组#elseuint16_tADC_Value;#endif//uint8_tGetADCtimes=20,ChannelNums;//采样次数和通道数volatileuint16_tADC_ValBuf[100]={0};//100=20*5ADC_ValBuf/*USERCODEEND0*/ADC_HandleTypeDefhadc1;DMA_HandleTypeDefhdma_adc1;2)编写ADC计算平均值函数voidGet_ADC_AverageValue(void),并在adc.h中声明。

1811321831811321831341351861ST13313919019119219315419519€1971981992GG2Q12Q22G32042Q5"多通道按顺序循环转换,皿二值也按顺序存放在ADJVml峰数组中"voidGetADCAverageVaIue(void}{ _ _lJint32_tsun[N;={j>;aintl6tifj;for//for(j=0;j工;j++)5uiu[j]+=ABC_ValBjf[i-W+j];“获取各个通道AD匚值总和for(i=j;i<N;i44)ADC_Val.ie[ ■计算平均值#elsevoidGetADCAvexdgeValae(void){——aint32_tsum;alnt16ti;for(i=^;i<M;i44)suir.+=ADC_Va13af[i];ADC_Valae=suiiL/N;//计算平均值L#endif/*'USERCODEEMD1*7【代码】:/*USERCODEBEGIN1*/#ifN>1/*多通道按顺序循环转换,ADC值也按顺序存放在ADC_Value数组中*/voidGet_ADC_AverageValue(void){uint32_tsum[N]={0};uint16_ti,j;for(i=0;i<M;i++) //sum[0]对应通道0,sum[1]对应通道1for(j=0;j<N;j++)sum[j]+=ADC_ValBuf[i*N+j];//获取各个通道ADC值总和for(i=0;i<N;i++)ADC_Value[i]=sum[i]/M;//计算平均值}#elsevoidGet_ADC_AverageValue(void){uint32_tsum;uint16_ti;for(i=0;i<M;i++)sum+=ADC_ValBuf[i];ADC_Value=sum/N;//计算平均值#endif/*USERCODEEND1*/(3)最后我们就可以编写main函数了Length变量是数据的个数,所以直接通过sizeof(ADC_ValBuf)/2来计算得出。首先,我们要在main函数开头的初始化部分调用ADCDMA启动函数,HAL_ADC_Start_DMA()函数中HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_ValBuf,sizeof(ADC_ValBuf)/2);gg100101102Initzalxzsallconfigoiedp=riph=rals百,MX_GPIC_IniL():MX二;!£X"ADCl_Init();I€K_U5JIRTl_nART_In1r(>://id£_DH?t_Iniit(7;八USERCODEBEGIS2*/HALADCStartCHl(;badc_,iuLnz32t^};ALCVa:LBu:f,m二zcof:AD「ValBuf^2);/DM1/•USERCODEE5IDZ"接着我们编写while循环中的函数。103工口鼻105Z016~1/士Infiniteloop7/'U5ERCODEBE3IETWHILE*/while|1|10710810911011111211311411511€117113119120121122123124125-]12612712S129130131132133134135136137-138-139140141/*,USER3ODEZNDWHILEV/*'USERCODEBEGIN3*/if《RuuFLug--!.}EecFlai^O;Get_ADC_AverageValue();for(i=D7i<sizeof(ADCValBuf卜/2:T++]if兹葭易-An]打印出每个通道”次采样的豫值prinEi(rr^d,"'fadcvaiBur[1]);printf(;r:+算平均数后各通道的山口二信为二n:fox(i=3;i<5;SWl匚二」1)“打印出计笄平均数后每个通道的AEcttcase0:printf(nADClChannel0Value:%d\n,T,ADC_Value[i]Mbreak;1:r-rintf(TIADCLCTianneL1;二m"1r入DCVa1二耳]:[卜;casecasebreak?Z;printfbreak?3:printfbreak;4:printfbreak?C"ADC_(nADCl(r,ADClChannelChannelCbamnelYal-jc; AEC¥a1上亡[:]卜;Value: ADCValue[i]|;Value: 1T.ADCValue[i]»;/*USERCODEEND3*/【代码】:while(1){/*USERCODEENDWHILE*//*USERCODEBEGIN3*/if(RecFlag==1){RecFlag=0;Get_ADC_AverageValue();for(i=0;i<sizeof(ADC_ValBuf)/2;i++){if(i>4&&i%5==0)printf("\n");//打印出每个通道20次采样的数值printf("%d",ADC_ValBuf[i]);}printf("\n\n");printf("计算平均数后各通道的ADC值为:\n");for(i=0;i<5;i++){switch(i)//打印出计算平均数后每个通道的ADC值{case0:printf("ADC1Channel0Value:%d\n",ADC_Value[i]);break;case1:printf("ADC1Channel1Value:%d\n",ADC_Value[i]);break;case2:printf("ADC1Channel4Value:%d\n",ADC_Value[i]);break;case3:printf("AD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论