Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

Как инвертировать семисегментик с ОК на ОА?

Вс июл 01, 2012 10:52:37

Всем доброго времени суток, и к делу, я собираю вольтметр на attiny26, от него есть исходник на Си (написан через кодвижен), но проблема в том что прошивка рассчитана на ОК индикатор, а не на ОА, подскажите как инвертировать в ИСХОДНИКЕ логические уровни у портов МК.

p.s. у меня вышло лишь инвертировать PORTB который переключает цифры для динамической индикации (где оператор case), а PORTA выдаётся крякозябры, при смене таблицы констант для индикатора с ОА, однако я правильно инвертировал константы цифр, не пойму почему так, кому не лень, помогите плиз :(

Спойлер//сам исходник
#include <tiny26.h>
#include <delay.h>
#define digit3 PORTB.4 //3 катод
#define digit2 PORTB.5 //2 катод
#define digit1 PORTB.6 //1 катод
#define ADC_AVERAGE (50)

char digit_out[3], cur_dig;
unsigned long indication;
unsigned int volt;

flash char digits[] = {0xE7, 0x24, 0xAB, 0xAE, 0x6C, 0xCE, 0xCF, 0xA4, 0xEF, 0xEE, 0x00}; //для индикатора с ОК
//flash char digits[] = {0x18, 0xDB, 0x54, 0x51, 0x93, 0x31, 0x30, 0x5B, 0x10, 0x11, 0x00}; //для индикатора с ОА
void recoding(void) { //тут разделение на сотые, десятые и единичные доли, это понятно
digit_out[0]=indication/100%10;
digit_out[1]=indication/10%10;
digit_out[2]=indication%10;
}

#define ADC_VREF_TYPE 0x80
// Read the AD conversion result
//собственно дальше не особо понимаю что происходит и как влияет всё это на индикацию

//тут видать кроется проблема несовместимости с таблицей знаков
unsigned int read_adc(unsigned char adc_input)
{
unsigned char i;
unsigned int result = 0;
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
for(i=0; i<ADC_AVERAGE;i++){
// Start the AD conversion
ADCSR|=0x40;
// Wait for the AD conversion to complete
while ((ADCSR & 0x10)==0);
ADCSR|=0x10;
result += ADCW;
}
return result/ADC_AVERAGE;;
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{

PORTA=0x00; //тут видно попеременное переключение цифр и вывода в порт А
switch (cur_dig){
case 0:{digit3=1;digit1=0;break;};
case 1:{digit1=1;digit2=0;break;};
case 2:{digit2=1;digit3=0;break;};

//сделал для ОА - работает
//case 0:{digit3=0;digit1=1;break;};
//case 1:{digit1=0;digit2=1;break;};
//case 2:{digit2=0;digit3=1;break;};


}
PORTA=digits[digit_out[cur_dig]];
cur_dig++;
if (cur_dig==3) cur_dig=0;
}

void main(void)
{

// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=Out Func5=Out Func4=In Func3=Out Func2=Out Func1=Out Func0=Out

PORTA=0x00;
DDRA=0xEF;

// Port B initialization
// Func7=In Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In

PORTB=0xFF;
DDRB=0x70;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 4000,000 kHz
TCCR0=0x01;
TCNT0=0x00;
PLLCSR=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x00;
OCR1C=0x00;
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: Int., AREF discon.
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSR=0x85;

// Global enable interrupts
#asm("sei")
//volt=read_adc(3);
while (1)
{

volt=read_adc(3)/3;
indication=volt;
recoding();
delay_ms(500); //задержка, это понятно
};
}
Вложения
Безымянный.jpg
Схемка
(208.37 KiB) Скачиваний: 734

Re: Как инвертировать семисегментик с ОК на ОА?

Вс июл 01, 2012 17:15:59

Посмотри как у меня сделано

Re: Как инвертировать семисегментик с ОК на ОА?

Вс июл 01, 2012 18:04:08

Попробуй вместо PORTA=0x00; //тут видно попеременное переключение цифр и вывода в порт А

сделать PORTA=0xFF; //тут видно попеременное переключение цифр и вывода в порт А

Re: Как инвертировать семисегментик с ОК на ОА?

Вс июл 01, 2012 19:22:55

Насколько я понял код, тебе надо проинвертировать сигналы на анодах твоих индикаторов (сегменты ты уже проинвертировал). Примерно таким макаром:
Код:
case 0:{digit3=0;digit1=1;break;};
case 1:{digit1=0;digit2=1;break;};
case 2:{digit2=0;digit3=1;break;};

То, что в коде выделено красным - это собственно замер напряжения.

Re: Как инвертировать семисегментик с ОК на ОА?

Ср июл 04, 2012 20:18:09

всё разобрался, тут в области case было написано

case 0:{digit3=1;digit1=0;break;};
case 1:{digit1=1;digit2=0;break;};
case 2:{digit2=1;digit3=0;break;};

а, как мне подсказали, надо было написать

case 0:{digit1=1;digit2=0;digit3=0;break;};
case 1:{digit1=0;digit2=1;digit3=0;break;};
case 2:{digit1=0;digit2=0;digit3=1;break;};

получается ровное, попеременное засвечивание цифр, при учёте констант цифр для ОА
так что вопрос решён, всем спасибо за участие :))
Тема закрыта