1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
问题原由
粉丝提问,STM32如何驱动ADC0809芯片,恰好我有空,时间来得及,粉丝有需求,小哈哥必须安排,这次发文总结一下,希望可以帮助大家。 开发环境与工具
微信公众号后台回复“Q&A3”,可以下载工程源码。 准备工作 购买ADC0809芯片 习惯购买元器件多买一个,方便替换验证。 因为做过一次验证之后,这个板子就没有用了,所以购买DIP-28宽体底座,让底座焊板子上,芯片插底座上,方便芯片的二次使用,节约成本。 PCB打板 粉丝买的下图这种模块: STM32要想驱动ADC0809这个芯片需要很多个引脚(不考虑复用的话,需要16个引脚),如果这些引脚都用杜邦线连接的话会很乱,如果哪个杜邦线再接触不好,那么对于程序的调试很不方便,所以我就采用核心板+底板的形式来实现,避免使用过多的杜邦线。 现在打样很便宜,线很多,时间来得及的话,推荐使用线路板的方式来验证。 我这次网友问答超时了,买件+PCB打样+调试程序,一共用了9天时间,如果不需要打样的实例,一周之内应该可以完成的。 ADC0809简介 ADC0809是采样精度为8位的、以逐次逼近原理进行模—数转换的器件。其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8路模拟输入信号中的一个进行A/D转换。 主要特性 1)8通道输入,拥有一个8位的A/D转换器,即分辨率8位。 2)具有转换起停控制端。 3)转换时间为100μs(时钟为640KHz时),130μs(时钟为500KHz时)。 4)单个+5V电源供电 5)模拟输入电压范围0~+5V,不需零点和满刻度校准。 6)工作温度范围为-40~+85摄氏度 7)低功耗,约15mW。 引脚图与功能 管脚功能说明: IN0-IN7:模拟量输入通道,共计8个通道; ADD A-C:通道选择引脚,通过这三根地址线的不同组合选择IN0 - IN7中的一个作为模拟量的输入通道; ALE:地址锁存允许信号; START:启动A/D转换信号; D0-D7:数据输出口,ADC转换后的结果通过这8个引脚并行输出; OE(OUTPUT ENABLE):输出允许信号,此引脚为输入端,高电平有效。当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量; CLOCK:时钟信号,输入脉冲。ADC0809内部没有时钟电路,需由外部提供时钟脉冲信号。时钟频率范围为10KHz-1280KHz,典型值640KHz; EOC:转换结束状态信号。输出信号,EOC=0,正在进行转换。EOC=1,转换结束,可以进行下一步输出操作;即当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平); Vref(+)、Vref(-):参考电压(基准电压)。参考电压用来与输入的模拟量进行比较,作为测量的基准。一般Vref(+)=5v ,Vref(-)=0V; VCC:电源引脚,单电源 +5V; GND:地 。 原理图 数据手册中的典型应用图: STM32与ADC0809接线 [tr]ADC0809引脚STM32引脚GPIO方向[/tr]
时序图 ADC0809工作过程 (1)控制与ADDA~ADDC相连的引脚,选择一个模拟输入端; (2)CLOCK端输入一个时钟信号,本文通过STM32的PWM实现此脉冲,脉冲频率采样100 KHz; (3)将ALE由低电平置为高电平,从而将ADDA-ADDC送进的通道代码锁存,经译码后被选中的通道的模拟量送给内部转换单元; (4)给START一个正脉冲。当上升沿时,所有内部寄存器清零。下降沿时,开始进行A/D转换;在转换期间,START保持低电平; (5)读取EOC引脚的状态,A/D转换期间,EOC输入低电平;A/D转换结束,EOC引脚输入高电平; (6)当A/D转换结束后,将OE设置为1,这时D0-D7的数据便可以读取了。 AD转换的代码实现 float get_adc0809(){ int i=0; u8 sum=0; float adc=0; int AD_DATA[8] = {0}; ADC0809_ALE=0; ADC0809_START=0; delay_us(10); ADC0809_ALE=1; ADC0809_START=1; delay_us(10); ADC0809_ALE=0; ADC0809_START=0; //启动AD转换 while(0==ADC0809_EOC); //等待转换结束 ADC0809_OE=1; AD_DATA[0]=ADC0809_D0*1 ; AD_DATA[1]=ADC0809_D1*2 ; AD_DATA[2]=ADC0809_D2*4 ; AD_DATA[3]=ADC0809_D3*8 ; AD_DATA[4]=ADC0809_D4*16 ; AD_DATA[5]=ADC0809_D5*32 ; AD_DATA[6]=ADC0809_D6*64 ; AD_DATA[7]=ADC0809_D7*128 ; ADC0809_OE=0; for(i=0; i<8; i++) { sum += AD_DATA; } adc = (float)sum*5/256; printf("sum=%d ad=%0.2f Vrn",sum,adc); return adc;} CLOCK时钟信号 要想ADC0809芯片能够正常的进行AD转换,必须给CLOCK引脚提供一个时钟脉冲信号,脉冲的频率范围为: 这个脉冲信号可以采用定时器中断的方式来产生脉冲信号或者使用PWM的方式来产生PWM信号,本实例采用PWM的方式,引脚选择了一个带有PWM功能的引脚PA7:TIM3_CH2。 PWM初始化 PWM初始化之后,直接使能PWM的输出,即始终有占空比50%的脉冲信号输入到ADC0809芯片的CLOCK引脚中。 //arr为重载值//psc为预分频系数void Clock_PWM_Init(u16 arr,u16 psc){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_DeInit(TIM3); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler = psc; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM3, &TIM_OCInitStructure); //TIM3_CH2 TIM_CtrlPWMOutputs(TIM3, ENABLE); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE); TIM_SetCompare2(TIM3,arr/2);} main函数中调用如下: Clock_PWM_Init(720-1,0); //PWM频率=72000/720 = 100Khz AD结果转换 因为ADC0809为8位的AD芯片,所以我们将8位数据中的每一位数据缓存至一个数组中,然后对这个数组中的值求和即为此次AD的采样值。 因为参考电压Vref(+)=5v ,Vref(-)=0V ,所以8位数的最大值0xFF对应5V,0x00对应0V,所以AD采样值和电压值的换算公式为:adc = (float)sum*5/256; 。 具体换算的代码如下: u8 sum=0;float adc=0; int AD_DATA[8] = {0}; AD_DATA[0]=ADC0809_D0*1 ;AD_DATA[1]=ADC0809_D1*2 ;AD_DATA[2]=ADC0809_D2*4 ;AD_DATA[3]=ADC0809_D3*8 ;AD_DATA[4]=ADC0809_D4*16 ;AD_DATA[5]=ADC0809_D5*32 ;AD_DATA[6]=ADC0809_D6*64 ;AD_DATA[7]=ADC0809_D7*128 ;for(i=0; i<8; i++){ sum += AD_DATA;}adc = (float)sum*5/256;printf("sum=%d ad=%0.2f Vrn",sum,adc); 结果展示 我们用杜邦线将IN0与板子上的GND、3.3V、5V依次相连,串口助手输出结果如下: 好了,今天的网友问答就分享到这里,各位可以利用咱们的核心板,自己做一个底板,玩起来哈。 |
||
|
||
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1767 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1069 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 01:57 , Processed in 0.701245 second(s), Total 76, Slave 60 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号