电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
[网友问答3]STM32驱动ADC0809详解
分 享
扫描二维码分享
[网友问答3]STM32驱动ADC0809详解
ADC0809
STM32
网友问答
嵌入式从0到1
关注
发布时间: 2021-01-25
丨
阅读: 769
### 问题原由 粉丝提问,`STM32如何驱动ADC0809芯片`,恰好我有空,时间来得及,粉丝有需求,小哈哥必须安排,这次发文总结一下,希望可以帮助大家。 ![](https://img-blog.csdnimg.cn/20210124201450223.png) ### 开发环境与工具 * Keil 5 * 主芯片为STM32F103RET6 * 下载工具为JLINK * XCOM V2.0串口助手 * PC为Win10 ### 程序源码 微信公众号后台回复“**Q&A3**”,可以下载工程源码。 ### 准备工作 #### 购买ADC0809芯片 习惯购买元器件多买一个,方便替换验证。 因为做过一次验证之后,这个板子就没有用了,所以购买DIP-28宽体底座,让底座焊板子上,芯片插底座上,方便芯片的二次使用,节约成本。 ![](https://img-blog.csdnimg.cn/20210124201555744.png) #### PCB打板 粉丝买的下图这种模块: ![](https://img-blog.csdnimg.cn/2021012420161458.png) STM32要想驱动ADC0809这个芯片需要很多个引脚(不考虑复用的话,需要16个引脚),如果这些引脚都用杜邦线连接的话会很乱,如果哪个杜邦线再接触不好,那么对于程序的调试很不方便,所以我就采用**核心板+底板**的形式来实现,避免使用过多的杜邦线。 ![](https://img-blog.csdnimg.cn/20210124201632743.png) 现在打样很便宜,线很多,时间来得及的话,推荐使用线路板的方式来验证。 我这次网友问答超时了,买件+PCB打样+调试程序,一共用了9天时间,如果不需要打样的实例,一周之内应该可以完成的。 ### ADC0809简介 ADC0809是采样精度为8位的、以逐次逼近原理进行模—数转换的器件。其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8路模拟输入信号中的一个进行A/D转换。 ![](https://img-blog.csdnimg.cn/2021012420175264.png) ### 主要特性 1)8通道输入,拥有一个8位的A/D转换器,即分辨率8位。 2)具有转换起停控制端。 3)转换时间为100μs(时钟为640KHz时),130μs(时钟为500KHz时)。 4)单个+5V电源供电 5)模拟输入电压范围0~+5V,不需零点和满刻度校准。 6)工作温度范围为-40~+85摄氏度 7)低功耗,约15mW。 ### 引脚图与功能 ![](https://img-blog.csdnimg.cn/20210124201810368.png) 管脚功能说明: **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**:地 。 ### 原理图 ![](https://img-blog.csdnimg.cn/20210124201828954.png) 数据手册中的典型应用图: ![](https://img-blog.csdnimg.cn/2021012420184675.png) #### STM32与ADC0809接线 | **ADC0809引脚** | **STM32引脚** | **GPIO方向** | | :---: | :---: | :---: | | START | PA2 | 输出 | | EOC | PA3 | 输入 | | OE | PA4 | 输出 | | CLOCK | PA7 | 输出 | | ALE | PA6 | 输出 | | ADD A | PA5 | 输出 | | ADD B | PB10 | 输出 | | ADD C | PB11 | 输出 | | ADC0809_D0 | PA11 | 输入 | | ADC0809_D1 | PA12 | 输入 | | ADC0809_D2 | PC10 | 输入 | | ADC0809_D3 | PC11 | 输入 | | ADC0809_D4 | PC12 | 输入 | | ADC0809_D5 | PD2 | 输入 | | ADC0809_D6 | PB13 | 输入 | | ADC0809_D7 | PB12 | 输入 | **注意**:ADC0809_D0为输出数据的最低位,ADC0809_D7为输出数据的最高位。 ### 时序图 ![](https://img-blog.csdnimg.cn/20210124201915148.png) #### 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转换的代码实现 ```C 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[i]; } adc = (float)sum*5/256; printf("sum=%d ad=%0.2f V\r\n",sum,adc); return adc; } ``` ### CLOCK时钟信号 要想ADC0809芯片能够正常的进行AD转换,必须给CLOCK引脚提供一个时钟脉冲信号,脉冲的频率范围为: ![](https://img-blog.csdnimg.cn/20210124201935666.png) 这个脉冲信号可以采用定时器中断的方式来产生脉冲信号或者使用PWM的方式来产生PWM信号,本实例采用PWM的方式,引脚选择了一个带有PWM功能的引脚**PA7:TIM3_CH2**。 ![](https://img-blog.csdnimg.cn/20210124201944254.png) #### PWM初始化 PWM初始化之后,直接使能PWM的输出,即始终有占空比50%的脉冲信号输入到ADC0809芯片的CLOCK引脚中。 ```C //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函数中调用如下: ```C 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;** 。 具体换算的代码如下: ```C 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[i]; } adc = (float)sum*5/256; printf("sum=%d ad=%0.2f V\r\n",sum,adc); ``` ### 结果展示 我们用杜邦线将IN0与板子上的GND、3.3V、5V依次相连,串口助手输出结果如下: ![](https://img-blog.csdnimg.cn/20210124202002562.png) 好了,今天的**网友问答**就分享到这里,各位可以利用咱们的核心板,自己做一个底板,玩起来哈。 ### 欢迎关注 一个专注于嵌入式知识分享,学习路上不迷路的公众号。 欢迎关注【嵌入式从0到1】。 还有技术交流群等你加入。 ### 参考阅读 [利用PWM原理,实现呼吸灯功能](https://mp.weixin.qq.com/s/2OTa4W1IitxGkR_xZ5bZqA) [STM32驱动RGB全彩LED](https://mp.weixin.qq.com/s/592KWGQ8ZQIUYrwd2bhURg) [SG90舵机驱动原理和实现](https://mp.weixin.qq.com/s/wa6EqEsNYSdo9KlhMku3-g) [语音识别LD3320模块控制LED和舵机](https://mp.weixin.qq.com/s/VoWc_XztSepgqjAMZYY_1Q)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
嵌入式从0到1
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交