完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
MAX4372是什么?MAX4372模块电路有何功能?
如何使用STC12C5A60S2芯片的AD转换功能? 怎样通过MAX4372与STC12C5A60S2来检测输入电压及其电流?并最终使用LCD1602显示? |
|
相关推荐
1个回答
|
|
本篇文章是介绍通过高端电流检测放大器MAX4372与芯片STC12C5A60S2组合电路来检测输入电压、输出电压、输出电流,并最终使用LCD1602显示,要求做到误差小于正负0.1。
那么下面我们先从MAX4372这个模块电路说起: 1、MAX4372概述 MAX4375是MAXIM公司最新推出的高端电流检测放大器,工作电压+2.7V到+28V,电源电流30uA,放大器增益分20/50/100三档,具有与电源电压无关的0V+28V共模输入范围,输出电压2V10V,满刻度准确性0.18%,输出阻抗1.5Ω,容性负载1000PF,可应用与电流保护/电流检测设备、4~20mA电流环系统、可编程电流源、智能电池/充电器等系统中。 2、引脚排列及功能 典型应用电路图 3实际应用图片 实际电路图: 排版图: 接下来介绍的是使用STC12C5A60S2芯片的AD转换功能,来实现输入电压、输出电压、输出电流的显示。 1、STC12C5A60S2 AD转换功能原理知识 先来一张引脚图: 再来看下一张: 整理出来的重点有如下几点: 一、 AD转换结束后,最终的转换结果保存到ADC转换结果寄存器ADC_RES和ADC_RESL,同时,置位ADC控制寄存器ADC_CONTR中的A/D转换结束标志位ADC_FLAG,以供程序查询或发出中断申请。 二、 模拟通道的选择控制由ADC控制寄存器ADC_CONTR中的CHS2~CHS0确定。 三、 ADC的转换速度由ADC控制寄存器中的SPEED1和SPEED0确定。 四、 在使用ADC之前,应先给ADC上电,也就是置位ADC控制寄存器中的ADC_POWER位。 五、 AUXR1辅助寄存器的ADRJ位是A/D转换结果寄存器(ADC_RES、ADC_RESL)的数据格式调整控制位。当ADRJ=0时,10位A/D转换结果的高8位存放在ADC_RES中,低2位存放在ADC_RESL的低2位中。当ADRJ=1时,10位A/D转换结果的高2位存放在ADC_RES中,低8位存放在ADC_RESL的低2位中。 P1口模拟功能控制寄存器P1ASF ADC控制寄存器ADC_CONTR ADC_POWER: ADC电源控制位: 0:关闭A/D转换器电源 1:打开A/D转换器电源 STC12C5A60S2系列单片机的A/D转换模块所使用的时钟是内部R/C振荡器所产生的系统时钟。 ADC_FLAG: 数模转换器转换结束标志位,当A/D转换完成后,ADC_FLAG=1,一定要软件清零。 ADC_START: 数模转换器(ADC)转换启动控制位,设置为1时,开始转换,转换结束后为零。 设置ADC_CONTP控制寄存器后,要加4个空操作延时才可以正确读到ADC_CONTR寄存器的值。 EA: CPU的中断开放标志位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。 EADC: A/D转换中断允许位。 EADC=1,允许A/D转换中断; EADC=0,禁止A/D转换中断。 PADCH,PADC: A/D转换中断优先级控制位。 当PADCH=0且PADC=0时,A/D转换中断为最低优先级中断(优先级0) 当PADCH=0且PADC=1时,A/D转换中断为较低优先级中断(优先级1) 当PADCH=1且PADC=1时,A/D转换中断为较高优先级中断(优先级2) 当PADCH=1且PADC=1时,A/D转换中断为最高优先级中断(优先级3) 2、STC12C5A60S2 AD转换、LCD显示核心代码 #include “reg51.h” #include “intrins.h” #include “1602.h” #include “ADC.H” #include “Display.h” /*****************主函数*****************/ unsigned char set; void main() { unsigned int a; double VIN,VOUT,VOI; //输入、输出电压、电流存放变量 unsigned int UIN,UOUT,UOI; //定义ADC结果读回存放变量 LcdInit(); //LCD初始化 InitADC(); //ADC初始化 set = 32; //设置默认关断电流阀值 while(1) { UIN = GetADCResult(0); //读取输入电压 UOUT = GetADCResult(1); //读取输出电压 UOI = filter(2); //读取输出电流值,并采用中位值滤波 VIN = (float)UIN*5/1024*4; //计算输入电压 VIN *=10000; if(VIN》160000) VIN += 1000; if(VIN》10000) VIN += 1000; VOUT = (float)UOUT*5/1024*3; //计算输出电压 VOUT *=10000; VOI = (float)UOI*5/1024; //计算输出电流 VOI /= 0.128; VOI *= 10000; if(VOI》30000) VOI += 2000; if(VOI》14500) VOI += 1000; if(VOI》6000) VOI += 200; if(VOI》100) VOI += 2000; /********显示结果*************/ V_IN(VIN); V_OUT(VOUT); V_OI(VOI); SET(set); } } 下面为ADC.c代码 //++++++++++++++++++++++++++++++++++++++++++++++ //+以下代码中ADC及串口配置部分引用了STC的代码+ //++++++++++++++++++++++++++++++++++++++++++++++ #include “reg52.h” #include “intrins.h” /******ADC功能寄存器*********/ sfr ADC_CONTR = 0xBC; //ADC控制寄存器 //BC 地址 sfr ADC_RES = 0xBD; //ADC高8位结果 //转换结果 sfr ADC_RESL = 0xBE; //ADC低2位结果 //转换结果 sfr P1ASF = 0x9D; //P1口第2功能控制寄存器 模拟功能配置寄存器 #define ADC_POWER 0x80 //ADC电源控制位 #define ADC_FLAG 0x10 //ADC完成标志 #define ADC_START 0x08 //ADC起始控制位 #define ADC_SPEEDLL 0x00 //540个时钟 #define ADC_SPEEDL 0x20 //360个时钟 #define ADC_SPEEDH 0x40 //180个时钟 #define ADC_SPEEDHH 0x60 //90个时钟 #define N 21 //ADC中值滤波次数,必须为基数 /*---------------------------- 软件延时 ----------------------------*/ void Delay(unsigned int n) { unsigned int x; while (n--) { x = 5000; while (x--); } } /*---------------------------- 初始化ADC ----------------------------*/ void InitADC() { P1ASF = 0x07; //设置P1口为AD口 0000 0111 //P1ASF 模拟功能配置寄存器 ADC_RES = 0; //清除结果寄存器(高位) ADC_RESL= 0; //清除结果寄存器(低位) ADC_CONTR = ADC_POWER | ADC_SPEEDLL; Delay(2); //ADC上电并延时 //yan:ADC_POWER=1; //yan:ADC_FLAG=1; } /*---------------------------- 读取ADC结果 ----------------------------*/ unsigned int GetADCResult(unsigned char ch) { unsigned int rew; ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; _nop_(); //等待4个NOP _nop_(); _nop_(); _nop_(); while (!(ADC_CONTR & ADC_FLAG)); //等待ADC转换完成 ADC_CONTR &= ~ADC_FLAG; //Close ADC rew=ADC_RES*4+ADC_RESL; //组合成10位 _nop_(); _nop_(); //return ADC_RES; //返回ADC结果 return rew; } unsigned int filter(unsigned char dat) //中位值滤波 { unsigned int value_buf[N]; unsigned int count,i,j,temp; for(count=0;count《N;count++) { InitADC(); //初始化ADC value_buf[count] = GetADCResult(dat);//读ADC数值 Delay(1); } for (j=0;j《N-1;j++) { for (i=0;i《N-j;i++) { if ( value_buf[i]》value_buf[i+1] ) { temp = value_buf[i]; value_buf[i] = value_buf[i+1]; value_buf[i+1] = temp; } } } return value_buf[(N-1)/2]; } void timer_init(void)//定时器初始化 { TMOD=0x01;/设置工作方式1 TH0=(65536-50000)/256;///赋值 TL0=(65536-50000)%256; EA=1;ET0=1;//开总中断;开定时器中断 TR0=1;启动计数器 } |
|
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 09:59 , Processed in 0.521012 second(s), Total 45, Slave 38 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号