历史上的今天
返回首页

历史上的今天

今天是:2024年10月28日(星期一)

正在发生

2019年10月28日 | ATmega16单片机ad电流和电压采样程序

2019-10-28 来源:51hei

四通道PWM


8路10位ADC,8个单端通道,2个具有可编程增益(1x, 10x, 或200x)的差分通道   


端口A(PA7..PA0) 端口A 做为A/D 转换器的模拟输入端。端口A 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口A 处于高阻状态。


端口B(PB7..PB0) 端口B 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口B 处于高阻状态。


端口B 也可以用做其他不同的特殊功能.


端口C(PC7..PC0) 端口C 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口C 处于高阻状态。如果JTAG接口使能,即使复位出现引脚 PC5(TDI)、 PC3(TMS)与 PC2(TCK)的上拉电阻被激活。端口C 也可以用做其他不同的特殊功能.


端口D(PD7..PD0) 端口D 为8 位双向I/O 口,具有可编程的内部上拉电阻。其输出缓冲器具有对称的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,则端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口D 处于高阻状态。端口D 也可以用做其他不同的特殊功能.



硬件方面基本懂了,剩下的是程序了,以下是该死的ADC数模转换器的大致使用,不太懂

***************************************************************************************************************************************

本程序简单的示范了如何使用ATMEGA16的ADC模数转换器     普通的单端输入     差分输入及校准    基准电压的校准    查询方式    中断方式    数据格式的变换  出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器


***************************************************************************************************************************************

以下是例程

****************************************************/

#include

#include

#include

#include /*宏INTERRUPT 的用法与SIGNAL 类似,区别在于    SIGNAL 执行时全局中断触发位被清除、其他中断被禁止    INTERRUPT 执行时全局中断触发位被置位、其他中断可嵌套执另外avr-libc 提供两个API 函数用于置位和清零全局中断触发位,它们是经常用到的。分别是:void sei(void) 和void cli(void) 由interrupt.h定义 */

//管脚定义

#define in_Single 0 //PA0(ADC0)

#define in_Diff_P 3 //PA3(ADC3)

#define in_Diff_N 2 //PA2(ADC2)

//常量定义

//单端通道,不放大

#define AD_SE_ADC0 0x00 //ADC0

#define AD_SE_ADC1 0x01 //ADC1

#define AD_SE_ADC2 0x02 //ADC2

#define AD_SE_ADC3 0x03 //ADC3

#define AD_SE_ADC4 0x04 //ADC4

#define AD_SE_ADC5 0x05 //ADC5

#define AD_SE_ADC6 0x06 //ADC6

#define AD_SE_ADC7 0x07 //ADC7

//差分通道ADC0作负端,10/200倍放大

#define AD_Diff0_0_10x 0x08 //ADC0+ ADC0-, 10倍放大,校准用

#define AD_Diff1_0_10x 0x09 //ADC1+ ADC0-, 10倍放大

#define AD_Diff0_0_200x 0x0A //ADC0+ ADC0-,200倍放大,校准用

#define AD_Diff1_0_200x 0x0B //ADC1+ ADC0-,200倍放大

//差分通道ADC2作负端,10/200倍放大

#define AD_Diff2_2_10x 0x0C //ADC2+ ADC2-, 10倍放大,校准用

#define AD_Diff3_2_10x 0x0D //ADC3+ ADC2-, 10倍放大

#define AD_Diff2_2_200x 0x0E //ADC2+ ADC2-,200倍放大,校准用

#define AD_Diff3_2_200x 0x0F //ADC3+ ADC2-,200倍放大

//差分通道ADC1作负端,不放大

#define AD_Diff0_1_1x 0x10 //ADC0+ ADC1-

#define AD_Diff1_1_1x 0x11 //ADC1+ ADC1-,校准用

#define AD_Diff2_1_1x 0x12 //ADC2+ ADC1-

#define AD_Diff3_1_1x 0x13 //ADC3+ ADC1-

#define AD_Diff4_1_1x 0x14 //ADC4+ ADC1-

#define AD_Diff5_1_1x 0x15 //ADC5+ ADC1-

#define AD_Diff6_1_1x 0x16 //ADC6+ ADC1-

#define AD_Diff7_1_1x 0x17 //ADC7+ ADC1-

//差分通道ADC2作负端,不放大

#define AD_Diff0_2_1x 0x18 //ADC0+ ADC2-

#define AD_Diff1_2_1x 0x19 //ADC1+ ADC2-

#define AD_Diff2_2_1x 0x1A //ADC2+ ADC2-,校准用

#define AD_Diff3_2_1x 0x1B //ADC3+ ADC2-

#define AD_Diff4_2_1x 0x1C //ADC4+ ADC2-

#define AD_Diff5_2_1x 0x1D //ADC5+ ADC2-

//单端通道,不放大

#define AD_SE_VBG 0x1E //VBG 内部能隙1.22V电压基准,校准用

#define AD_SE_GND 0x1F //接地 校准用

//注:

//差分通道,如果使用1x或10x增益,可得到8位分辨率。如果使用200x增益,可得到7位分辨率。

//在PDIP封装下的差分输入通道器件未经测试。只保证器件在TQFP与MLF封装下正常工作。

#define Vref 2556 //mV 实测的Vref引脚电压@5.0V供电

//#define Vref 2550 //mV 实测的Vref引脚电压@3.3V供电

//全局变量

unsigned int ADC_SingleEnded; //单端输入的ADC值

int ADC_Diff; //差分输入的ADC值

volatile unsigned int ADC_INT_SE; //中断模式用的单端输入ADC值,会在中断服务程序中被修改,

                                  //须加volatile限定

volatile unsigned char ADC_OK; //ADC状态,会在中断服务程序中被修改,须加volatile限定

unsigned int LED_Volt; //变换后的电压mV

int LED_Curr; //变换后的电流100uA

//仿真时在watch窗口,监控这些全局变量。

unsigned int read_adc(unsigned char adc_input)//查询方式读取ADC单端通道

   {

      ADMUX=(0xc0|adc_input); //adc_input:单端通道 0x00~0x07,0x1E,0x1F

      //0xc0:选择内部2.56V参考电压

      ADCSRA|=(1<      loop_until_bit_is_set(ADCSRA,ADIF); //方法1 等待AD转换结束

      // while ((ADCSRA&(1<      // loop_until_bit_is_clear(ADCSRA,ADSC); //方法2 检测ADSC=0也行

      ADCSRA|=(1<      return ADC; //ADC=ADCH:ADCL

   }

int read_adc_diff(unsigned char adc_input)//查询方式读取ADC差分通道

  {

      unsigned int ADC_FIX;

      ADMUX=(0xc0|adc_input); //adc_input:差分通道 0x08~0x1D

      _delay_ms(1); //等待差分增益稳定>125uS

      ADCSRA|=(1<      loop_until_bit_is_set(ADCSRA,ADIF);

      ADCSRA|=(1<      //当切换到差分增益通道,由于自动偏移抵消电路需要沉积时间,

      //第一次转换结果准确率很低。

      //用户最好舍弃第一次转换结果。

      ADCSRA|=(1<      loop_until_bit_is_set(ADCSRA,ADIF);

      ADCSRA|=(1<      ADC_FIX=ADC;

      //输出结果用2的补码形式表示

      //可正可负 +/-9bit -512~+511

      //即M16差分通道的ADC+输入端的电压可以大于ADC-,也可以小于ADC-。

      //Tiny26就不行,ADC+输入端的电压必须大于或等于ADC-,为+10bit

   

     if (ADC_FIX>=0x0200) //负数要变换,正数不用

        {

           ADC_FIX|=0xFC00; //变换成16位无符号整数

         }

     return (int)ADC_FIX;

    }


SIGNAL(SIG_ADC) //ADC中断服务程序

   {

      //硬件自动清除ADIF标志位

      ADC_INT_SE=ADC; //读取结果

      ADC_OK=1;

   }

        

int main(void)

   {

     long temp32;

     ADC_SingleEnded =0;

     ADC_Diff=0;

     ADC_INT_SE=0;

     //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻

     PORTB=0xFF; //不用的管脚使能内部上拉电阻。

     PORTC=0xFF;

     PORTD=0xFF;

     PORTA=~((1<     //作ADC输入时,不可使能内部上拉电阻。

     ADCSRA=(1<     sei(); //使能全局中断

     

     while (1)

       {

         //实测的Vref引脚电压 =2556mV

         ADC_SingleEnded=read_adc(AD_SE_ADC0);

         //查询方式读取ADC0

         temp32=(long)ADC_SingleEnded*Vref;

         LED_Volt=(unsigned int)(temp32/1024);

         ADC_Diff =read_adc_diff(AD_Diff3_2_10x);

         ADC_Diff-=read_adc_diff(AD_Diff2_2_10x);//校准OFFSET

         temp32=(long)ADC_Diff*Vref;

         LED_Curr=(unsigned int)(temp32/(512*10)); //[单位为100uA]

         //查询方式读取ADC3+,ADC2- 10倍放大 max +/-255.6mV

         //10欧姆 1mA=10mV max +/-25.56mA

         //分辨率约0.5mV=50uA,显示取整为100uA单位

         ADCSRA|=(1<         ADMUX=0xC0|AD_SE_ADC0; //单端输入ADC0

         ADC_OK=0; //软件标志清零

         ADCSRA|=(1<         while(ADC_OK==0); //等待ADC完成,实际程序中可以运行其它任务

         ADCSRA&=~(1<         //查询方式和中断方式要注意 ADIF标志位的处理。

      }


推荐阅读

史海拾趣

Geyer Electronic E K公司的发展小趣事

Geyer Electronic E.K.公司的发展故事

故事一:创立与初步发展

Geyer Electronic E.K.公司由Rudolf Geyer于1964年创立,最初是一家位于慕尼黑莱姆区的电子产品零售店。在那个年代,电子产品行业正处于快速发展阶段,Geyer凭借其敏锐的市场洞察力和对技术的热情,逐渐在市场中站稳了脚跟。起初,店铺销售各类电子产品,从简单的收音机到复杂的电子设备,一应俱全。随着时间的推移,Geyer Electronic凭借其优质的服务和丰富的产品线,逐渐赢得了当地消费者的信任和支持。

故事二:转型与专业化

1992年,Geyer Electronic经历了一次重要的转折点。在Jürgen Reichmann的领导下,公司被收购并进行了战略调整,正式转型为一家专门从事频率产品和特殊电池的公司。这一转型标志着Geyer Electronic开始专注于某一特定领域,并致力于在该领域成为行业的领导者。公司投入大量资源进行技术研发和产品创新,不断推出符合市场需求的高质量频率产品和特殊电池,逐渐在行业内树立了良好的口碑。

故事三:全球化布局

随着业务的不断扩展,Geyer Electronic开始将目光投向全球市场。公司不仅在欧洲建立了稳固的市场地位,还逐渐将业务拓展到亚洲和美国等其他地区。为了实现全球化战略,Geyer Electronic加强了与全球合作伙伴的合作与交流,共同推动频率产品和特殊电池技术的创新与发展。同时,公司还建立了完善的全球销售网络,确保产品能够在短时间内送达全球各地的客户手中。

故事四:认证与品质保证

为了进一步提升产品质量和客户满意度,Geyer Electronic积极寻求国际认证。公司通过了DIN ISO 9001:2015等国际质量管理体系认证,这标志着Geyer Electronic在质量管理方面已经达到了国际先进水平。通过严格的质量控制和持续的技术创新,Geyer Electronic不断推出高品质的频率产品和特殊电池,赢得了全球客户的广泛认可和信赖。

故事五:搬迁与未来发展

为了满足未来发展的需要,Geyer Electronic于2022年搬到了位于Planegg的新公司所在地。这次搬迁不仅为公司提供了更加宽敞和现代化的办公和生产环境,还为公司未来的发展奠定了坚实的基础。在新的起点上,Geyer Electronic将继续秉承“质量第一、客户至上”的经营理念,不断推动技术创新和产品升级,为全球客户提供更加优质、高效的服务和解决方案。同时,公司还将积极探索新的市场领域和发展机遇,努力成为全球电子行业中的佼佼者。

安路科技(Anlogic)公司的发展小趣事

随着技术的不断积累和市场的逐步开拓,安路科技在XXXX年成功推出了其首款高性能FPGA产品。这款产品以其优异的性能、稳定的品质和良好的性价比,迅速赢得了市场的青睐。此后,安路科技的产品线不断丰富,逐渐覆盖了更多应用领域,公司的市场份额也逐年攀升。

Amperite Co公司的发展小趣事

安路科技(Anlogic)的创立可以追溯到XXXX年,由一群具有深厚技术背景的工程师共同创立。起初,公司规模虽小,但怀揣着在国产FPGA(现场可编程门阵列)领域实现技术突破的梦想。早期,安路科技面临着资金短缺、市场竞争激烈等挑战,但团队凭借着对技术的执着和不懈的努力,逐步研发出了具有竞争力的FPGA产品,并在市场上获得了一定的认可。

芯佰微(Corebai)公司的发展小趣事

作为一家有社会责任感的企业,芯佰微始终关注环境保护和可持续发展。公司积极推广绿色生产技术和资源循环利用方案,减少生产过程中的能源消耗和废弃物排放。同时,芯佰微也积极参与社会公益活动,为社区和环境贡献自己的力量。这些举措不仅体现了公司的社会责任担当,也为其赢得了更多客户和合作伙伴的信任和支持。

康龙(CONCRAFT)公司的发展小趣事

康龙(CONCRAFT)公司成立于XXXX年,创始人XXX凭借其敏锐的商业眼光和对电子行业的深入理解,决定专注于电子连接器的研发和生产。公司初始阶段面临资金、技术和市场的重重挑战,但创始人带领团队夜以继日地工作,成功开发出了具有竞争力的连接器产品。随着产品的不断完善和市场推广的加强,康龙逐渐在电子连接器领域崭露头角。

Electrolube公司的发展小趣事

在电子行业的激烈竞争中,Electrolube公司始终坚持以客户需求为导向,不断创新和拓展产品线。除了UVCL涂层外,公司还推出了一系列树脂、涂料和热管理解决方案的产品组合,为EV电池提供全面保护。

这些产品不仅具有优异的性能表现,而且能够满足不同客户的需求。例如,某些产品具有优异的耐高温性能,适用于高温环境下的电子设备;而另一些产品则具有出色的耐化学腐蚀性能,能够在恶劣的工作环境中保持稳定的性能。

Electrolube公司通过不断的技术创新和产品优化,成功拓展了市场份额,并在电子行业中树立了良好的品牌形象。同时,公司还积极与各大汽车制造商合作,共同推动电动汽车产业的发展。

问答坊 | AI 解惑

帮分析个简单的程序。。实在扛不住弄出来了

用定时器1做的简单输出,友善micro2440的板子 请帮我分析下,搞了好长时间,还是出不来 流驱动:#include \"options.h\" #include #include #include #include #include #include #include #include #include \"time.h\"  ...…

查看全部问答>

C语言与单片机C语言(C51)有啥不同?

请问一下各位 学校里学的C语言和单片机C语言(C51)有啥子不一样的?哪个好学一点. 在学校里学了C语言后感觉没有学到啥子,挺浮浅的,现在只记得一些简单的规则和语法。 不知道现在是继续学它基础打扎实点呢,还是就开始学C51,希望大家给点建 ...…

查看全部问答>

wince界面设计问题

请问要设计出这样的界面需要使用什么软件? 这种界面设计使用的什么方法。都是贴的图吗? 那具体设计过程是怎么样的? 好像是先设计整个界面,然后在截图。 …

查看全部问答>

在WINCE60里面把CELLCORE组件加进了NK,怎么测试这块是不是可以正常工作?有没简单的测试AP可用?怎么测试RIL组件绑定了物理通信的串口?

在WINCE60里面把CELLCORE组件加进了NK,怎么测试这块是不是可以正常工作?有没简单的测试AP可用?怎么测试RIL组件绑定了物理通信的串口?…

查看全部问答>

ppc2003可以直接访问sql2000 server中的数据吗?

ppc2003通过wifi跟局域网连接后,可以通过编程直接访问服务器上sql2000 server中的数据吗?有人说必须在ppc上安装sql CE,然后通过sql CE跟服务器上的sql2000交换数据?真的是这样?…

查看全部问答>

立即报名预约2010吉时利新能源与新材料测试技术研讨会

2010年度吉时利测试测量技术全国巡回研讨会将从9月初开始,在成都、重庆、合肥、南京、哈尔滨、武汉、兰州举办届时吉时利资深技术专家将与您深入交流: 绿色电子革命中的光电测试/新能源测试方案 新材料的测试方案 微弱信号测量难点与应对方 ...…

查看全部问答>

uCADCDMA通道4中断问题!

使用uC2.86   ADC使用DMA中断的模式,在DMA1_CH1 初始化以及 中断 都没问题,都可以进中断, 但是改成 DMA1_CH4 就再也不进中断了,为什么?? 难道 DR_ADDRESS 地址不对?? RCC,等其他设置应该都没问题请大家看下我的初始化函 ...…

查看全部问答>

问高手一个关于STM8 I2C的问题

最近在调STM8 的I2C(不想搞模拟的I2C),结果I2C没有调通,不知道问题所在,软件是参考I2C EEPROM固件那个程序写的。初始化如下: void IIC_Init(void) { UCHAR temp; CLK_PCKENR1 |= 0x01; I2C_CR1    = 0x00;  &n ...…

查看全部问答>

关于vca810的放大增益

本帖最后由 dontium 于 2015-1-23 12:51 编辑 我这两天用面包板按照vca810芯片的datasheet中的figure2 电路搭建了一个压控放大,将8脚的50欧姆电阻去掉,并在8脚加了一个vpp=30mv,f=800hz的正弦波(函数发生器产生),并在1脚直接接地。但是在Vc= ...…

查看全部问答>

《TMS320C28x系列DSP》读书笔记--通用目标文件格式,段

      TMS320系列DSP的目标文件各式为通用目标文件格式 COFF (Command Object File Format,简称COFF)。 采用这种目标文件各式的优点是:将指令和数据按照段的概念进行组织和存储,这使得程序的可读性大大增强,更容易编写 ...…

查看全部问答>