|
急求有谁用过ATtiny24ADC转换,麻烦分析一下下面的程序,感谢!
#include "macros.h"
#include "iot24v.h"
#include "DATA_TYPES.h"
//============PORT define=============//
//#define COM1 PB0
//#define COM2 PB1
//#define SPK PB3
//#define SEG_G PB2
#define BAT_VREF 500
#define VV_JS_COUNT 5 //采集电压作平均的次数 //电流电压作平均的次数
INT8U Adc_Mux; //ADC通道切换
INT8U Js_Count; //ADC转换计数
INT8U Scan_Count; //扫描计数
INT8U Scan_Times; //扫描时间
INT8U ShangDian_Count;
INT16U Count_Timems; //ms计时
INT16U Adc_Rel[2];
INT16U Adc_Jsrel;//[2]; //ADC缓存
//=======定义一个结构体类型变量=======//
struct
{ //定义位变量
unsigned bit0:1; //ADC完成标志
unsigned bit1:1; //上电标志
unsigned bit2:1; //电压与温度的切换标志
unsigned bit3:1; //上电显示A、F用标志位
unsigned bit4:1;
unsigned bit5:1;
unsigned bit6:1;
unsigned bit7:1;
}Bit_Variable;
void Display(void);
void Clr_Wdt(void);
void ADC_Init(void);
void Port_Init(void);
//void Water_Count(void);
void Timer0_Init(void);
//void Time_Manage(void);
void Bat_Water_Test(void);
INT8U SMG_Buf[2];
const INT8U SMG_Tabel[]={0x00,0xe7,0x93,0xc3,0x67,
0x4b,0x0b,0xe3,0x03,0x43, //"0-9"
0x23,0x3b,0x8f //A、F、U
};
void Port_Init(void)
{
INT8U i;
// Clr_Wdt();
DDRA = 0xfc; //0为输入,1为输出
PORTA = 0xfc; //PA2_PA7输出高电平,PA0_PA1关闭上拉,为ADC输入
DDRB = 0x07; //reset暂时为输入
PORTB = 0x04; //PB2输出为高,PB0_1_3输出低电平
for(i=0;i<250;i++); //上电延时
// SMG_Buf[0] = SMG_Tabel[9];
// SMG_Buf[1] = SMG_Tabel[0];
Adc_Mux = 0;
Js_Count = 0;
Scan_Count = 0;
Bit_Variable.bit1 = 1; //上电标志置1
Bit_Variable.bit2 = 1; //电压与温度的切换标志置1
// Bit_Variable.bit3 = 1;
ShangDian_Count = 10;
}
void Adc_Init(void)
{
DDRA = 0xfc;
PORTA = 0xfc; //PA2_PA7输出高电平,PA0_PA1关闭上拉,为ADC输入
// PRR &= 0x0e;
ADCSRA = 0x00;
// ADCSRB = 0x00;
ADMUX = (0<<REFS1)|(0<<REFS0)|(Adc_Mux&0x0f); //VCC做为参考电压,开始选择通道0
ACSR = (1<<ACD); //模拟比较器禁用
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); //使能ADC,ADC开始转换,ADC中断使能,64分频
}
//=============定时器T0初始化函数============
void Timer0_Init(void)
{
TCCR0B = 0x00;
TCNT0 = 0x9c;
TCCR0B = (1<<CS01)|(1<<CS00); //64分频
TIMSK0 = (1<<TOIE0); //T0溢出中断使能
}
void Bat_Water_Test(void)
{
INT16U ADC_Bat_Temp;
if((Bit_Variable.bit0==1)&&(Bit_Variable.bit1==0)) //转换完成且非刚上电
{
// if(Bit_Variable.bit2==1) //显示电压
// {
ADC_Bat_Temp = (INT16U)(((INT32U)((INT32U)Adc_Jsrel*BAT_VREF))/0x3FF);
ADC_Bat_Temp = (ADC_Bat_Temp*133/33);
SMG_Buf[0] = SMG_Tabel[ADC_Bat_Temp/10]; //十位
SMG_Buf[1] = SMG_Tabel[ADC_Bat_Temp%10]; //个位
// }
}
}
/*
void Bat_Water_Test(void)
{
INT16U ADC_Bat_Temp,ADC_Water_Temp;
if((Bit_Variable.bit0==1)&&(Bit_Variable.bit1==0)) //转换完成且非刚上电
{
if(Bit_Variable.bit2==1) //显示电压
{
ADC_Bat_Temp = (INT16U)(((INT32U)((INT32U)Adc_Jsrel[0]*BAT_VREF))/0x3FF);
ADC_Bat_Temp = (ADC_Bat_Temp*133/33);
SMG_Buf[0] = SMG_Tabel[ADC_Bat_Temp/10]; //十位
SMG_Buf[1] = SMG_Tabel[ADC_Bat_Temp%10]; //个位
}
else //显示水温
{
ADC_Water_Temp = (INT16U)(((INT32U)((INT32U)Adc_Jsrel[1]*BAT_VREF))/0x3FF);
SMG_Buf[0] = SMG_Tabel[ADC_Water_Temp/10]; //十位
SMG_Buf[1] = SMG_Tabel[ADC_Water_Temp%10]; //个位
}
// Bit_Variable.bit0 = 0;
}
}
*/
void Display(void)
{
if(Scan_Times>=1) //1.5ms到
{
Scan_Times = 0;
PORTB &= 0x0c; //先关显示
if(Bit_Variable.bit1==1) //如果是上电则显示AF 1S钟
{
// PORTA &= SMG_Buf[Scan_Count]; //*****有问题*****
PORTA = (PORTA|0xfc)&(SMG_Tabel[ShangDian_Count]);
PORTB = (PORTB|0x04)&0x0b; //点亮g段
switch(ShangDian_Count) //位选通
{
case 10: PORTB = (PORTB&0x0c)|0x01; break;
case 11: PORTB = (PORTB&0x0c)|0x02; break;
// case 10: PORTB |= 0x01; break; //*****有问题*****
// case 11: PORTB |= 0x02; break;
}
ShangDian_Count++;
if(ShangDian_Count>11)
ShangDian_Count = 10;
}else{
PORTA = (PORTA|0xfc)&(SMG_Buf[Scan_Count]);
// PORTA &= SMG_Buf[Scan_Count];
if((SMG_Buf[Scan_Count]==0x93)|(SMG_Buf[Scan_Count]==0xc3)|
(SMG_Buf[Scan_Count]==0x67)|(SMG_Buf[Scan_Count]==0x4b)|
(SMG_Buf[Scan_Count]==0x0b)|(SMG_Buf[Scan_Count]==0x03)|
(SMG_Buf[Scan_Count]==0x43))
PORTB = (PORTB|0x04)&0x0b; //点亮g段
else
PORTB = PORTB|0x04; //否则关断g段
switch(Scan_Count) //位选通
{
case 0: PORTB = (PORTB&0x0c)|0x01; break;
case 1: PORTB = (PORTB&0x0c)|0x02; break;
}
Scan_Count++;
if(Scan_Count>1)
Scan_Count = 0;
Bit_Variable.bit0 = 0;
}
}
}
/*
void Clr_Wdt(void)
{
_WDR();
WDTCSR = 0x18;
WDTCSR = 0x07;
_WDR();
}
*/
#pragma interrupt_handler timer0_ovf_isr:iv_TIMER0_OVF //Timer0中断服务程序 1.5ms/1次
void timer0_ovf_isr(void)
{
Scan_Times++;
Count_Timems++;
if(Count_Timems>=400)
{Count_Timems = 0;
Bit_Variable.bit1 = 0;}
// if((Count_Timems>=15000)&&(Bit_Variable.bit2==1)) //20s到切换为显示温度
// Bit_Variable.bit2 = 0;
TCNT0 += 0x9c; //重装定时值
}
#pragma interrupt_handler ADC_ovf_isr:iv_ADC //ADC中断服务程序
void ADC_ovf_isr(void)
//{
// INT16U Temp;
// INT8U i;
{
Adc_Jsrel = ADC&0x3ff;
ADMUX = (0<<REFS1)|(0<<REFS0)|(Adc_Mux&0x0f);
ADCSRA |= (1<<ADSC);
}
/* Adc_Rel = ADC&0x3ff;
ADMUX = (Adc_Mux&0x0f);
ADCSRA |= (1<<ADSC);*/
/* if(Js_Count==0)
Adc_Rel[Adc_Mux] = ADC&0x3ff;
else
{
Temp = ADC&0x3ff;
Adc_Rel[Adc_Mux]=(Adc_Rel[Adc_Mux]+Temp)/2;
}
if(Adc_Mux>=1)
{
Adc_Mux = 0;
if(Js_Count<VV_JS_COUNT)
Js_Count++;
else
{
Js_Count = 0;
for(i=0;i<2;i++)
Adc_Jsrel=Adc_Rel;
Bit_Variable.bit0 = 1; //ADC完成标志置1
}
}
else Adc_Mux++;
ADMUX = (0<<REFS1)|(0<<REFS0)|(Adc_Mux&0x0f);
ADCSRA |= (1<<ADSC);
}
*/
void main()
{
Port_Init();
Adc_Init();
Timer0_Init();
SEI(); //使能全局中断
while(1)
{
Bat_Water_Test();
Display();
}
} |
|