armok 发表于 2008-6-27 11:28:20

【阿莫AVR芯片检测系列文章6】ADC检测器制作资料

本资料包括:

   1. 功能描述
   2. 实物图
   3. 电路图
   4. AVR源代码(GCC)


http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_328265.jpg
(原文件名:ADC检测器.jpg)



功能描述:

本检测器的经验数据:

器件:ATmega16-8AI/8AU/16AI/16AU
熔丝位设置: D9D4 (高低位)

使用ISP接口写入数据后,如果通过ADC检测,在半秒内绿灯长亮。否则红灯长亮。

第一个版本是ADC0-ADC7均是检测同一个参考电压,这个方法有个缺陷:如果两只管脚间有锡短路,会测试不出来。这个版本改进成每个ADC输入不同的电压。

根据线路图,测试出的输入数据如下 (由于电阻有点误差,可能理理论值有点区别):

      ADC0                0x0053-- 0.304V
      ADC1                0x00A9-- 0.619V
      ADC2                0x00FD-- 0.927V
      ADC3                0x0153 -- 1.241V
      ADC4                0x01A8 -- 1.553V
      ADC5                0x01FD -- 1.864V
      ADC6                0x0252 -- 2.175V
      ADC7                0x02A7 -- 2.487V

程序里设置了一个 unsigned int error_range=0x0002;   //允许误差范围。经测试,2比较适合。如果是1会有些芯片过不了此测试(稍有干扰便过不了)。 设置成2是必需的,原因是插入ISP后,容易造成外来的干扰。有时发现没有ISP时,容错=1也能通过,但插入后就通过不了。



http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_328246.jpg
(原文件名:SNAG-0000.jpg)

http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_328264.jpg
(原文件名:SNAG-0001.jpg)

http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_328248.jpg
(原文件名:SNAG-0003.jpg)

http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_328249.jpg
(原文件名:SNAG-0004.jpg)

http://cache.amobbs.com/bbs_upload782111/files_10/ourdev_328250.jpg
(原文件名:SNAG-0005.jpg)





/***********************************************
****             AVR ADC使用范例             ***
****                                           ***
**** 编译器:WINAVR20050214                  ***
**** 时钟:内部RC 8MHz                     ***
**** 2008.06.16by armok阿莫                ***
****                 www.OurAVR.com                   ***
***********************************************/


#include <avr/io.h>


//管脚定义
#define LED_GRREN          0         //PB0
#define LED_RED                        3         //PB1
#define in_Diff_N                2         //

//常量定义
//单端通道,不放大
#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


#define Vref                                 2464                //mV 实测的Vref引脚电压@3.75 (1+R1/R2)*.25V供电

unsigned int LED_Volt;                                        //变换后的电压mV
int LED_Curr;                                                        //变换后的电流100uA
//仿真时在watch窗口,监控这些全局变量。

unsigned int read_adc(unsigned char adc_input)//查询方式读取ADC单端通道
{
    ADMUX=(0x00|adc_input);                                        //adc_input:单端通道 0x00~0x07
                                          //0x00:选择AREF参考电压
    ADCSRA|=(1<<ADSC);                                                //启动AD转换
    loop_until_bit_is_set(ADCSRA,ADIF);                //方法1 等待AD转换结束
    ADCSRA|=(1<<ADIF);                                                //写1清除标志位
    return ADC;                                                        //ADC=ADCH:ADCL
}

void green_led(void)
        {
       DDRB|=(1<<0);
           PORTB|=(1<<0);
        }

void red_led(void)
        {

       DDRB|=(1<<1);
           PORTB|=(1<<1);
           check_end:;
           goto check_end;
        }

void check_adc_value(unsigned int ADC_Value_input,unsigned int standard_value_input,unsigned int error_range_input)

{
            if (ADC_Value_input<(standard_value_input-error_range_input) || ADC_Value_input>(standard_value_input+error_range_input)) red_led();
}

int main(void)
{
    unsigned int ADC_Value =0;//ADC的数值。计算方法是转成十进制/1024 * 3.75
        unsigned int c=500;
        unsigned int error_range=0x0002;   //允许误差范围。经测试,2比较适合。如果是1会有些芯片过不了此测试(稍有干扰便过不了)。
        unsigned int standard_value=0;   //标准数值

    //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
    //PORTB=0xFF;                        //不用的管脚使能内部上拉电阻。
    //PORTC=0xFF;
    //PORTD=0xFF;
        DDRA=0x00;
    PORTA=0x00;         //作ADC输入时,不可使能内部上拉电阻。

        DDRB&=~(1<<PB0);
        PORTB&=~(1<<PB0);
        DDRB&=~(1<<PB1);
        PORTB&=~(1<<PB1);

    ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1);                //使能ADC,时钟8分频 125KHz@1MHz system clock -- 011
                                                    // 64分步 125KHZ@ 8M system clock    -- 110
          
        while (c>1)
        {

/*
ADC0                53-- 0.304V
ADC1                A9-- 0.619V
ADC2                FD-- 0.927V
ADC3                153 -- 1.241V
ADC4                1A8 -- 1.553V
ADC5                1FD -- 1.864V
ADC6                252 -- 2.175V
ADC7                2A7 -- 2.487V
*/

                        ADC_Value=read_adc(0);
                        standard_value=0x0053;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(1);
                        standard_value=0x00A9;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(2);
                        standard_value=0x00FD;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(3);
                        standard_value=0x0153;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(4);
                        standard_value=0x01A8;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(5);
                        standard_value=0x01FD;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(6);
                        standard_value=0x0252;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                        ADC_Value=read_adc(7);
                        standard_value=0x02A7;//标准数值
            check_adc_value(ADC_Value,standard_value,error_range);

                c--;
        }
       
        green_led();
       
}

rqiang 发表于 2008-6-28 01:32:11

【楼主位】 armok 阿莫
不错,不错,等全部完成了,做个全功能版本,工厂品质部门可以需要的。

xk2yx 发表于 2008-6-28 11:10:05

loop_until_bit_is_set(ADCSRA,ADIF);                //方法1 等待AD转换结束
会不会造成死循环?

armok 发表于 2008-6-28 11:20:58

【2楼】 xk2yx 笑看人生,

会的。不过不影响使用。发生死循环视为芯片已经损坏。

下一个版本会改进。

Forever 发表于 2008-6-30 13:18:10

当ad切换通道后,采样的第一个数据要不要舍去,会不会有误差?

armok 发表于 2008-6-30 13:31:01

【4楼】 Forever ,

经过我们几十K的拆机AVR芯片的实际检验,采样的第一个数据不用舍去。证明这些拆机件的质量是过硬的 :)

Forever 发表于 2008-6-30 13:52:23

呵呵,不错,为ad程序设计也提供了实践支持!

kingsabbit 发表于 2008-7-8 15:51:15

建议阿莫ADC输入采用同相跟随器和二阶滤波来提高去除ADC干扰作用

kingsabbit 发表于 2008-7-8 15:56:47

如果要判断锡是否短路引脚,请参考附件(本用用于测试一个12Pin连接器的接入后是否开路或者有短路的电路)
开短路测试ourdev_342643.pdf(文件大小:64K) (原文件名:TM372_12Pin连接器开短路检测.pdf)
原理就是:判断引脚是否开路后再判断是否有短路,前提是引出的引脚正常是高电平的输出信号

armok 发表于 2008-7-8 16:09:44

非常感谢 【8楼】 kingsabbit 的资料与建议。

1。短路的问题,我的前一个检测已经比较完美的解决了::【阿莫AVR芯片检测系列文章4】发布我近一个月不眠夜搞的AVR拆机IO测试器全套资料(V3.0版)

2。ADC的检测,由于简化线路的目标,的确是可以进一步加强效果。下一个版本会考虑在内。

qkj1575 发表于 2008-7-8 16:31:32

这回AVR公司要倒闭了

armok 发表于 2010-1-13 01:57:21

以下蓝色文字由坛主:armok 于:2010-01-13,01:57:21 加入。<font color=black>请发贴人注意:本贴放在这分区不合适,即将移走
原来分区:AVR (原ourAVR.com) 技术论坛
即将移去的分区:开源雕刻机DIY活动(及机械分论坛)
移动执行时间:自本贴发表0小时后
任何的疑问或咨询,请可随时联系站长。谢谢你的支持!</font>
页: [1]
查看完整版本: 【阿莫AVR芯片检测系列文章6】ADC检测器制作资料