adc转换程序
- 格式:doc
- 大小:42.50 KB
- 文档页数:6
中微单片机多通道adc程序
中微电子公司的单片机常用的多通道ADC程序可以使用它们的STM32系列单片机为例进行说明。
在STM32系列单片机中,多通道ADC程序通常涉及以下几个步骤:
1. 初始化ADC模块,首先需要初始化ADC模块,包括设置时钟、引脚配置、转换模式、采样时间等。
这些参数会影响ADC的精度和
采样速度。
2. 配置多通道,接下来需要配置ADC的多通道转换,即选择要
转换的通道和通道顺序。
在STM32中,可以通过设置SQR寄存器来
配置多通道转换的顺序。
3. 启动转换,配置完成后,可以启动ADC转换。
可以选择单次
转换模式或连续转换模式,根据应用需求来决定。
4. 读取转换结果,当转换完成后,可以从数据寄存器中读取转
换结果。
在多通道转换中,需要根据设置的转换顺序逐个读取各个
通道的转换结果。
5. 数据处理,最后,根据应用需求对转换结果进行处理,比如数据滤波、数据存储、数据传输等。
需要注意的是,不同型号的单片机可能会有不同的寄存器和配置方法,因此在编写多通道ADC程序时需要参考具体的芯片手册和相关资料。
以上是关于中微电子公司单片机多通道ADC程序的基本步骤,希望能对你有所帮助。
py32 adc 例程对于Python 3.2版本的ADC(模数转换器)例程,我们可以使用单片机或者嵌入式开发板来进行ADC的示例程序编写。
以下是一个简单的示例程序,假设我们使用的是树莓派(Raspberry Pi)开发板,并且已经连接了一个模拟信号源到ADC引脚。
python.import spidev.import time.# 初始化SPI.spi = spidev.SpiDev()。
spi.open(0, 0)。
# 从ADC读取数据。
def read_adc(channel):adc = spi.xfer2([1, (8 + channel) << 4, 0])。
data = ((adc[1] & 3) << 8) + adc[2]return data.try:while True:# 读取ADC值。
val = read_adc(0)。
print("ADC值: {}".format(val))。
time.sleep(1)。
except KeyboardInterrupt:spi.close()。
这个示例程序使用了spidev库来进行SPI通信,并通过SPI接口读取ADC转换的数值。
在主循环中,我们不断读取ADC的值并打印出来。
当用户按下Ctrl+C时,程序会捕获KeyboardInterrupt异常并关闭SPI连接。
需要注意的是,具体的ADC连接方式和通信协议可能因硬件而异,上述示例仅供参考。
在实际应用中,需要根据所使用的具体硬件和ADC芯片的规格来编写相应的ADC读取程序。
除了SPI接口外,还有其他的ADC接口和通信协议,如I2C、UART等,具体的例程会根据不同的接口和硬件而有所不同。
希望这个简单的示例程序能够帮助到你理解如何在Python 3.2中编写ADC 例程。
九齐单片机AD转换程序代码解析与优化引言单片机的模数转换(Analog-to-Digital Conversion,简称ADC)是许多嵌入式系统中的重要功能之一。
九齐单片机广泛应用于各种应用领域,因此了解如何有效地进行ADC转换至关重要。
本文将深入探讨九齐单片机的AD转换程序代码,并提供优化建议,以确保高质量、高效率的ADC数据采集。
九齐单片机AD转换简介九齐单片机是一种常用的嵌入式系统开发平台,其内置模数转换器(ADC)允许用户将模拟信号转换为数字值,以供微控制器进行处理。
通常,AD转换程序代码的目标是获取模拟信号的准确数字表示。
以下是一个简单的九齐单片机AD转换程序代码的示例:#include <stdio.h>#include "jz_adc.h"int main() {jz_adc_init(); // 初始化ADCint result;while (1) {result = jz_adc_read(); // 读取ADC值printf("ADC Value: %d\n", result);}return 0;}在这个示例中,我们首先包含了必要的库和头文件,然后初始化了ADC,接着在一个无限循环中读取ADC值,并将其打印出来。
虽然这个代码足够简单,但它可以进一步优化以提高性能和可维护性。
代码优化建议1. 错误处理在上述代码中,没有包含错误处理机制。
如果初始化或读取过程中出现错误,代码将无法处理,这可能导致不稳定的系统行为。
我们建议添加错误处理代码,以确保程序可以适当地处理异常情况。
#include <stdio.h>#include "jz_adc.h"int main() {if (jz_adc_init() != 0) {printf("ADC initialization failed.\n");return 1;}int result;while (1) {result = jz_adc_read();if (result < 0) {printf("ADC reading failed.\n");return 2;}printf("ADC Value: %d\n", result);}return 0;}2. 中断处理上述代码是一个简单的轮询方式来读取ADC值,但这种方式会占用CPU时间,不适用于需要高效率的应用。
三相电压电流adc算法程序
三相电压电流ADC算法程序。
在电力系统中,对三相电压和电流进行准确的测量和采集是非
常重要的。
为了实现对三相电压和电流的准确采集,通常会使用
ADC(模数转换器)来进行数字化处理。
ADC算法程序是用来对采集
到的模拟信号进行数字化处理的关键工具。
首先,我们需要对三相电压和电流进行采集。
这可以通过传感
器或者变压器来实现。
采集到的模拟信号需要经过滤波和放大处理,然后再输入到ADC中进行数字化处理。
ADC算法程序需要考虑到电压和电流的波形特性,以及系统的
采样率和精度要求。
通常会采用差分输入方式来对三相电压和电流
进行采集,以提高抗干扰能力和准确性。
在数字化处理过程中,需要进行采样、量化和编码等步骤,以
将模拟信号转换为数字信号。
此外,还需要考虑到数据通信和存储
的需求,以便将采集到的数据传输给上位机或者进行存储和分析。
ADC算法程序的设计需要综合考虑系统的实际需求和性能指标,以确保对三相电压和电流的准确采集和处理。
同时,还需要考虑到
系统的稳定性和可靠性,以确保系统在各种工作条件下都能够正常
运行。
总之,三相电压电流ADC算法程序是实现对三相电压和电流准
确采集和数字化处理的关键技术,它对于电力系统的运行和监测具
有重要意义。
通过不断优化和改进ADC算法程序,可以提高电力系
统的运行效率和安全性,为电力系统的智能化和自动化发展提供有
力支持。
二,ADC0808/0809與8031單片機的介面設計ADC0808/0809與8031單片機的硬體介面有三種方式,查詢方式,中斷方式和等待延時方式.究竟採用何種方式,應視具體情況,按總體要求而選擇.1.延時方式ADC0809編程模式在軟體編寫時,應令p2.7=A15=0;A0,A1,A2給出被選擇的模擬通道的地址;執行一條輸出指令,啟動A/D轉換;執行一條輸入指令,讀取A/D轉換結果.通道地址:7FF8H~7FFFH下麵的程式是採用延時的方法,分別對8路模擬信號輪流採樣一次,並依次把結果轉存到數據存儲區的採樣轉換程式.START: MOV R1, #50H ;置數據區首地址MOV DPTR, #7FF8H ;P2.7=0且指向通道0MOV R7, #08H ;置通道數NEXT: MOVX @DPTR,A ;啟動A/D轉換MOV R6, #0AH ;軟體延時DLAY: NOPNOPNOPDJNZ R6, DLAYMOVX A, @DPTR ;讀取轉換結果MOV @ R1, A ;存儲數據INC DPTR ;指向下一個通道INC R1 ;修改數據區指針DJNZ R7, NEXT ;8個通道全採樣完了嗎........2.中斷方式將ADC0808/0809作為一個外部擴展的並行I/O口,直接由8031的P2.0和脈衝進行啟動.通道地址為FEF8H~FEFFH用中斷方式讀取轉換結果的數字量,模擬量輸入通路選擇端A,B,C分別與8031的P0.0,P0.1,P0.2(經74LS373)相連,CLK由8031的ALE提供.INTADC:SETB IT1 ;選擇為邊沿觸發方式SETB EA ;開中斷SETB EX1 ;MOV DPTR, #0FEF8H ;通道地址送DPTRMOVX @DPTR,A ;啟動A/D轉換……PINT1: ……MOV DPTR, #0FEF8H ; 通道地址送DPTRMOVX A, @ DPTR;讀取從IN0輸入的轉換結果存入MOV 50H, A ;50H單元MOVX @DPTR,A ;啟動A/D轉換RETI ;中斷返回3.2 主程序主程序主要是設置數據區的起始地址為60H ,模擬路數為8路,設置外部中斷方式是下降沿觸發,開總中斷,向ADC0809寫數據啟動AD 轉換圖1 主流程圖的設計框架3.3中斷服務程式中斷服務程式主要完成取AD 轉換結果存儲,模擬路數自增1,存儲區自增1,判斷8路是否轉換完畢,若完畢則返回。
网上很多类似资料,总结就是要么给出不完整的一部分,要么就是没有标注说明之类的,鞋面我给大家贴出实用型的,包括如何配置DMA和ADC,如何采集数据,如何处理数据//系统时钟使用72MHZunsigned short AD_Value[5]={0};//定义成半字节数组void RCC_Config(void){ErrorStatus HSEStartUpStatus;//定义枚举型变量RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus==SUCCESS){RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);FLASH_SetLatency(FLASH_Latency_2);FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource()!=0x08);}//---打开设备时钟---//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Pe riph_GPIOF,ENABLE);//RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//开串口1和ADC1的时钟}void ADC_Start(void){DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件启动转换}void DMA_ADC_Config(void){ADC_InitTypeDef ADC_InitStructure;DMA_InitTypeDef DMA_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //设置成模拟输入GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //设置成模拟输入GPIO_Init(GPIOB, &GPIO_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开ADC1的时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //开DMA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟,为PCLK2的8分频,即9MHzDMA_DeInit(DMA1_Channel1);//ADC挂接在DMA的通道1上DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_ADDRESS; //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地DMA_InitStructure.DMA_BufferSize = 5; //DMA通道的DMA缓存的大小系统用5个通道DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变即地址ADC1->DR不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增即数组AD_Value地址增加DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位,这里尤其注意因为选择的是半字节的,所以定义数组的时候也要定义成半字节数组,否则采集数据出乱,很多人是贴出资料来了,但是根本没有把这些注意点写明DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道x拥有高优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x设置为非内存到内存传输DMA_Init(DMA1_Channel1, &DMA_InitStructure);//DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);ADC_DeInit(ADC1);ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模数转换工作在扫描模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换//ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //注意不要使用持续转换模式,否则只要触发一次后续的转换就会永不停歇(除非CONT清0),这样第一次以后的ADC,就不是由TIM1_CC1来触发了ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 5; //顺序进行规则转换的ADC通道的数目ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4, ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 5, ADC_SampleTime_239Cycles5);ADC_ExternalTrigInjectedConvCmd(ADC1,DISABLE);ADC_DMACmd(ADC1, ENABLE); // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1ADC_ResetCalibration(ADC1);//复位校准寄存器while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1复位校准寄存器的状态,设置状态则等待ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待ADC_Start();}//数据采集处理void ADC_DateProcess(void){unsigned char i,k,h;unsigned int Buf=0;//递推先进先出原理ADCCollect.PVVoltageBuf[9]=get_ChannelVale(ADC_Channel_4)&0xfff;ADCCollect.BatteryVoltageBuf[9]=get_ChannelVale(ADC_Channel_5)&0xfff;ADCCollect.CirTem1Buf[9]=get_ChannelVale(ADC_Channel_6)&0xfff;ADCCollect.BatteryChargeCurrentBuf[9]=get_ChannelVale(ADC_Channel_7)&0xfff;ADCCollect.BatteryDisChargeCurrentBuf[9]=get_ChannelVale(ADC_Channel_8)&0xfff;for(i=0;i<9;i++){ADCCollect.PVVoltageBuf[i]=ADCCollect.PVVoltageBuf[1+i];ADCCollect.BatteryVoltageBuf[i]=ADCCollect.BatteryVoltageBuf[1+i];ADCCollect.CirTem1Buf[i]=ADCCollect.CirTem1Buf[1+i];ADCCollect.BatteryChargeCurrentBuf[i]=ADCCollect.BatteryChargeCurrentBuf[1+i];ADCCollect.BatteryDisChargeCurrentBuf[i]=ADCCollect.BatteryDisChargeCurrentBuf[1+i];}//排序for(k=0; k<9; k++ )//{for(h=0 ; h<9 - k ; h++)//{Buf=0;if(ADCCollect.PVVoltageBuf[h] > ADCCollect.PVVoltageBuf[h+1]){Buf = ADCCollect.PVVoltageBuf[h+1];ADCCollect.PVVoltageBuf[h+1] = ADCCollect.PVVoltageBuf[h];ADCCollect.PVVoltageBuf[h] = Buf;}Buf=0;if(ADCCollect.BatteryVoltageBuf[h] > ADCCollect.BatteryVoltageBuf[h+1]){Buf = ADCCollect.BatteryVoltageBuf[h+1];ADCCollect.BatteryVoltageBuf[h+1] = ADCCollect.BatteryVoltageBuf[h];ADCCollect.BatteryVoltageBuf[h] = Buf;}Buf=0;if(ADCCollect.CirTem1Buf[h] > ADCCollect.CirTem1Buf[h+1]){Buf = ADCCollect.CirTem1Buf[h+1];ADCCollect.CirTem1Buf[h+1] = ADCCollect.CirTem1Buf[h];ADCCollect.CirTem1Buf[h] = Buf;}Buf=0;if(ADCCollect.BatteryChargeCurrentBuf[h] > ADCCollect.BatteryChargeCurrentBuf[h+1]){Buf = ADCCollect.BatteryChargeCurrentBuf[h+1];ADCCollect.BatteryChargeCurrentBuf[h+1] = ADCCollect.BatteryChargeCurrentBuf[h];ADCCollect.BatteryChargeCurrentBuf[h] = Buf;}}}ADCCollect.CirTem1=0;ADCCollect.BatteryChargeCurrent=0;ADCCollect.BatteryDisChargeCurrent=0;ADCCollect.BatteryVoltage=0;ADCCollect.PVVoltage=0;//去掉最大值和最小值取平均值for(i=3;i<7;i++)//{ADCCollect.CirTem1+=ADCCollect.CirTem1Buf[i];ADCCollect.BatteryChargeCurrent+=ADCCollect.BatteryChargeCurrentBuf[i];ADCCollect.BatteryDisChargeCurrent+=ADCCollect.BatteryDisChargeCurrentBuf[i];ADCCollect.BatteryVoltage+=ADCCollect.BatteryVoltageBuf[i];ADCCollect.PVVoltage+=ADCCollect.PVVoltageBuf[i];}ADCCollect.CirTem1=ADCCollect.CirTem1/4;ADCCollect.BatteryChargeCurrent=ADCCollect.BatteryChargeCurrent/4;ADCCollect.BatteryDisChargeCurrent=ADCCollect.BatteryDisChargeCurrent/4;ADCCollect.BatteryVoltage=ADCCollect.BatteryVoltage/4;ADCCollect.PVVoltage=ADCCollect.PVVoltage/4;//充电电流ADCCollect.BatteryChargeCurrent=(ADCCollect.BatteryChargeCurrent*33)/4096;ADCCollect.BatteryChargeCurrent=(ADCCollect.BatteryChargeCurrent*30)/31;if(ADCCollect.BatteryChargeCurrent<0.2){ADCCollect.BatteryChargeCurrent=0;}//电池电压ADCCollect.BatteryVoltage=ADCCollect.BatteryVoltage*33/40960;ADCCollect.BatteryVoltage=ADCCollect.BatteryVoltage*3068/68;//放电电流ADCCollect.BatteryDisChargeCurrent=(ADCCollect.BatteryDisChargeCurrent*33)/4096;ADCCollect.BatteryDisChargeCurrent=(ADCCollect.BatteryDisChargeCurrent*30)/31;if(ADCCollect.BatteryDisChargeCurrent<0.2){ADCCollect.BatteryDisChargeCurrent=0;}//PV电压ADCCollect.PVVoltage=ADCCollect.PVVoltage*33/40960;ADCCollect.PVVoltage=ADCCollect.PVVoltage*3068/68;//温度ADCCollect.CirTem1=NTC_Temperature(ADCCollect.CirTem1);ADCCollect.CirTem1=ADCCollect.CirTem1/10;}。
前言:本文详细说明了ADC0804工作原理及过程,还附有一个ADC0804在单片机中的典型应用,包含原理图,源程序,程序注释详细清楚,这有助于更好地理解与应用ADC0804芯片。
1、A/D转换概念:即模数转换(Analog to DigitalConversion),输入模拟量(比如电压信号),输出一个与模拟量相对应的数字量(常为二进制形式)。
例如参考电压VREF为5V,采用8位的模数转换器时,当输入电压为0V时,输出的数字量为0000 0000,当输入的电压为5V时,输出的数字量为1111 1111。
当输入的电压从从0V到5V变化时,输出的数字量从0000 0000到1111 1111变化。
这样每个输入电压值对应一个输出数字量,即实现了模数转换。
2、分辨率概念:分辨率是指使输出数字量变化1时的输入模拟量,也就是使输出数字量变化一个相邻数码所需输入模拟量的变化值。
分辨率与A/D转换器的位数有确定的关系,可以表示成FS / 2 n 。
FS表示满量程输入值,n为A/D转换器的位数。
例如,对于5V的满量程,采用4位的ADC时,分辨率为5V/16=0.3125V (也就是说当输入的电压值每增加0.3125V,输出的数字量增加1);采用8位的ADC时,分辨率为5V/256=19.5mV(也就是说当输入的电压值每增加19.5mV,则输出的数字量增加1);当采用12位的ADC时,分辨率则为5V/4096=1.22mV(也就是说当输入的电压值每增加1.22mV ,则输出的数字量增加1)。
显然,位数越多,分辨率就越高。
3、ADC0804引脚功能:CS:芯片片选信号,低电平有效。
即CS=0时,该芯片才能正常工作,高电平时芯片不工作。
在外接多个ADC0804芯片时,该信号可以作为选择地址使用,通过不同的地址信号使能不同的ADC0804芯片,从而可以实现多个ADC通道的分时复用。
WR:启动ADC0804进行ADC采样,该信号低电平有效,即WR信号由低电平变成高电平时,触发一次ADC转换。
STM32使⽤HAL库实现ADC单通道转换 STM32的ADC转换还是很强⼤的,它具有多个通道选择,这⾥我就不细说,不了解的可以⾃⾏百度,这⾥只是选取单通道,实现ADC 转换。
在⽂章开始之前,我说⼀下数据左对齐跟右对齐的差别,以前⼀直糊⾥糊涂的,记录下来以免以后⾃⼰忘记。
12位⼆进制最⼤值为0x0FFF 左对齐操作后的结果是 0xFFF0,右对齐后还是0x0FFF。
反过来看,若寄存器⾥左对齐的数据值X (相当于实际数据*16,所以左对齐转换的值要/16才是实际的值),则X>>4才是实际的数据。
⽽右对齐,则是数据保持不变,采集到多少就多少。
⾄于是按左对齐保存到寄存器还是按照右对齐,就看你的配置⾥如何选了。
好了,下⾯就开始说明怎么⽤STM32CUBEMX实现ADC单通道转换吧。
利⽤中断模式1、配置ADC引脚2、开定时跟串⼝,定时器⽤来定时打开ADC转换,这样可以达到1S内控制ADC转换次数的⽬的,不过有个限制,这⾥样⼦控制ADC转换次数的话,如果采样次数多,配置ADC采样速度时⼀定要够快,正常配置ADC的采样频率可以通过改变其采样速度来设置的,这⾥我是为了⽅便处理,就直接⽤定时器去开启了;⽽串⼝则是打印转换后的电压⽤的。
3、配置时钟4、配置ADC设置 `5、开启中断模式6、串⼝配置默认即可7、定时器配置,定时器配置的是进⼊定时器中断的频率,定时时间可以根据这个频率换算出来,这⾥定时器的频率 = 72M / 72 /1000=1000Hz,所以定时时间为 T = 1S/f = 1S/1000 = 1ms,所以我这⾥配置定时为1ms。
8、基本配置我们完成了,现在我们⽣成⼯程⽤KEIL5打开9、打开⼯程,我们现在进⼊代码部分 这⾥我们只需要重写定时器中断回调函数跟,ADC转换回调中断函数即可。
在main⽂件⾥添加这下⾯这两个函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //定时器中断回调{HAL_ADC_Start_IT(&hadc1); //定时器中断⾥⾯开启ADC中断转换,1ms开启⼀次采集}void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //ADC转换完成回调{HAL_ADC_Stop_IT(&hadc1); //关闭ADCHAL_TIM_Base_Stop_IT(&htim3); //关闭定时器AD_Value=HAL_ADC_GetValue(&hadc1); //获取ADC转换的值Value_1=(float)(AD_Value*3.3/4096); //ADC换算,这⾥参考电压3.3V,12位的ADC满量程为2^12=4096,转换出来的单位是Vprintf("%.4f\r\n",Value_2[j-10000]); //串⼝打印信息HAL_TIM_Base_Start_IT(&htim3); //开启定时器} 到这⾥就完成单通道ADC中断转换的所有步骤啦,通过串⼝助⼿实测转换结果误差为0.0008v。