nrgizer79

Ацп Attiny13

6 сообщений в этой теме

nrgizer79    0

Всех приветствую!

БП для автомобильного компьютера.

Все работает, кроме.....

Для контроля напряжения на аккумуляторе, когда все устройства "спят", подаю напряжение через делитель на АЦП1 (нога 7).

При напряжении 10,5В на входе на ноге 7 д.б. 2,625В или значение 537 на АЦП1.

Т.е. при значении менее 537 хотелось бы обесточивать всю схему.

На деле АЦП правильно не считает:

- если задавать int bat_volt_min в диапазоне меньше 500, то схема обесточивается при напряжении менее 10,4 В;

- если в диапазоне более 500, то схема обесточивается при напряжении менее 11,5В.

Т.е. не АЦП какое то, а триггер.

Что я неправильно делаю ?

Вот моя схемка БП:

3b4fc1b02ae6t.jpg

Вот код:

#include <tiny13a.h>
#define F_CPU 1200000UL
#include <delay.h>
// Назначим константы
int bat_volt_min = 537;
// Глобальные переменные
bit first_start=0;
bit batt_bad=0;
bit power_on=0;
bit LCD_state=0;
unsigned int timer0_sec=0;
unsigned int timer0_count=0;
unsigned int batt_volt=0;
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
timer0_count++;
 if (timer0_count==146)
 {
 timer0_sec+=1;
 timer0_count=0;
 }
//	 if (PORTB.3==1 && power_on==1)
//	 {
//	 timer0_sec=0;
//	 }
}
// Bandgap Voltage Reference: Off
#define ADC_VREF_TYPE ((0<<REFS0) | (0<<ADLAR))
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}
// Выключение всего
void all_off ()
{
 PORTB.4=1;
 LCD_state=0;
 PORTB.0=LCD_state;
 first_start=0;
 power_on=0;
}	
// Нажатие кнопки Power на плате Odroid
void power_on_off ()
{
PORTB.1=1;
delay_ms (300);
PORTB.1=0;
power_on=!power_on;
}
//Включение/выключение LCD & HUB
void lcd_hub_on_off ()
{
 LCD_state=!LCD_state;
 PORTB.0=LCD_state;
}

// Проверка батареи
void check_bat ()
{
batt_volt = read_adc (1);
if (batt_volt < bat_volt_min)
 {
 batt_bad=1;
 }
else {
 batt_bad=0;
	 };					
}
// Первый старт
void first_start_func ()
{
 check_bat ();
 if (batt_bad==1)
 {
	 all_off ();
 }
 if (PINB.3==1 && batt_volt>=bat_volt_min)
 {
 PORTB.4=0;
 LCD_state=1;
 PORTB.0=LCD_state;
 first_start=1;
 power_on=1;	
 }
 timer0_count=0;
 timer0_sec=0;	
}
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port B initialization
// Function: Bit5=In Bit4=Out Bit3=In Bit2=In Bit1=Out Bit0=Out
DDRB=(0<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit5=T Bit4=1 Bit3=T Bit2=T Bit1=0 Bit0=0
PINB=(0<<PINB5) | (1<<PINB4) | (0<<PINB3) | (0<<PINB2) | (0<<PINB1) | (0<<PINB0);
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 37,500 kHz
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 6,8267 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=(0<<INT0) | (0<<PCIE);
MCUCR=(0<<ISC01) | (0<<ISC00);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIS1) | (0<<ACIS0);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR0=(0<<AIN0D) | (0<<AIN1D);
// ADC initialization
// ADC Clock frequency: 600,000 kHz
// ADC Bandgap Voltage Reference: Off
// ADC Auto Trigger Source: ADC Stopped
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
DIDR0|=(0<<ADC0D) | (0<<ADC2D) | (0<<ADC3D) | (0<<ADC1D);
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);

// Global enable interrupts
#asm("sei")
while (1)
 {
 if (first_start==0)
 {
	 first_start_func ();
 }
 if (PINB.3==0 && timer0_sec>=10 && power_on==1)
 {
	 power_on_off ();
 }
 if (PINB.3==0 && timer0_sec>=15 && LCD_state==1)
 {
	 lcd_hub_on_off ();
 }			
 if (PINB.3==0 && timer0_sec>=30)
	 {
	 check_bat ();
	 }
 if (batt_bad==1)
 {
	 all_off ();
 }
 if (PINB.3==0 && timer0_sec>=51000)
 {
	 all_off ();
 }
 if (PINB.3==1 && power_on==0 && LCD_state==0 && batt_bad==0 && first_start==1)
 {
	 lcd_hub_on_off ();
	 timer0_sec=0;
 }
 if (PINB.3==1 && power_on==0 && timer0_sec>=5 && LCD_state==1 && batt_bad==0 && first_start==1)
 {
	 power_on_off ();		
	 timer0_sec=0;
 }
 if (PINB.3==1 && power_on==1 && LCD_state==1)
 {
 timer0_sec=0;
 }
 }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
salyamkamrad    451

Схему не смотрел, программу тоже, в проблему особо не вникал, но абсолютная погрешность преобразования тинек плюс/минус 2 LSB, то есть реально можно рассчитывать на использование только 8 бит результата АЦ преобразования. 9 бит возможно осилит, если отправлять ее спать на время преобразования и обеспечить минимум помех в питающем напряжении.

Изменено пользователем salyamkamrad

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
nrgizer79    0

Подумал вот что.

Может на время преобразования надо отключать прерывания.

У меня используется прерывание по таймеру.

Может это АЦП сбивает ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
salyamkamrad    451

На время преобразования нужно отключать все, кроме АЦП. Хотя бы потому, что у Attiny13 нет отдельных земель и питания для аналоговой и цифровой частей. А просыпаться по прерыванию от окончания преобразования АЦП.

Изменено пользователем salyamkamrad

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
nrgizer79    0

В общем так:

- понизил частоту работы АЦП до минимума

- выбрал режим только с 8-ю битами

Работает как надо.

Всем спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Загрузка...