|
本资料包括:
1. 功能描述
2. 实物图
3. 电路图
4. AVR源代码(GCC)
(原文件名: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也能通过,但插入后就通过不了。
(原文件名:SNAG-0000.jpg)
(原文件名:SNAG-0001.jpg)
(原文件名:SNAG-0003.jpg)
(原文件名:SNAG-0004.jpg)
(原文件名:SNAG-0005.jpg)
/***********************************************
**** AVR ADC使用范例 ***
**** ***
**** 编译器:WINAVR20050214 ***
**** 时钟: 内部RC 8MHz ***
**** 2008.06.16 by 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();
} |
|