Страница 1 из 1

Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 25 июл 2012, 14:16
ASDFG123
Помогите допилить код часов из примера, на семисегментном индикаторе. Моделирую в протэусе, проблема в том что идут не точно.
Вот код

Код: Выделить всё

#define F_CPU 8000000UL
#include <avr/io.h> 
#include <util/delay.h>
#include <avr/interrupt.h>
#include "display.h"

volatile unsigned char second, minute, hour, level;

ISR(TIMER2_COMP_vect)	// обработчик прерывания по совпадению Т2
{                       
second++;				// увеличиваем секунды
if(second == 60)        // если second = 60, second = 0
{  second = 0;
   minute++;            // увеличиваем минуты
if(minute == 60)        // если minute = 60, minute = 0
{  minute = 0;
   hour++;              // увеличиваем часы
if(hour == 24)          // если hour = 24, hour = 0
   hour = 0;
}
}

set_time(hour,minute,second);

}

int main(void)
{
hour = 12;	// начальная установка времени
minute = 0;
second = 0;

DDRB |= (0 << PB5)|(0 << PB4);
PORTB |= (1 << PB5)|(1 << PB4);
TCNT2=0;  
TCCR2|=(1<<CS20)|(1<<CS21)|(1<<CS22)|(1<<WGM21); // 32768/256 =32hz запуск Т2 (CTC ?)
ASSR|=(1<<AS2); //ассинхронный режим
 
OCR2=25-1; //регистр сравнения (пришлось поставить так, точность ближе)

sei();                 // глобально разрешам прерывания

set_brightness(80);   // начальная установка яркости дисплея
display_init();        // инициализация дисплея

shift_in('t'); // выводим бегущую строку "test display"
_delay_ms(50);
shift_in('E');
_delay_ms(50);
shift_in('s');
_delay_ms(50);
shift_in('t');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
shift_in('d');
_delay_ms(50);
shift_in('i');
_delay_ms(50);
shift_in('s');
_delay_ms(50);
shift_in('p');
_delay_ms(50);
shift_in('L');
_delay_ms(50);
shift_in('a');
_delay_ms(50);
shift_in('y');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
clear_screen();
_delay_ms(100);

TIMSK |= (1<<OCIE2); // разрешаем прерывание по совпадению Т2


while(1)
{	
unsigned char i, dr;

if((PINB&(1 << PB4))==0 && (PINB&(1 << PB5))==0)// если кнопка Часы+ и Минуты+ нажаты
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(5);
   if((PINB&(1 << PB4))==0 && (PINB&(1 << PB5))==0) 
   dr++;
  } 
if(dr > 5) 
  {
   if(level != 99) 
   level++;	// увеличиваем яркость
   else level = 0;
   set_brightness(level);
  }
} 

if((PINB&(1 << PB4))==0 && PINB&(1 << PB5)) // если кнопка Часы+ нажата
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(5);
   if((PINB&(1 << PB4))==0) 
   dr++;
  } 
if(dr > 5) 
  {
   if(hour != 23) hour++;	// увеличиваем часы
   else hour = 0;
   set_time(hour,minute,second);
  }
} 

if((PINB&(1 << PB5))==0 && PINB&(1 << PB4)) // если кнопка Минуты+ нажата
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(5);
   if((PINB&(1 << PB5))==0) 
   dr++;
  } 
if (dr > 5) 
  {
   if(minute != 59) minute++;	// увеличиваем минуты
   else minute = 0;
   set_time(hour,minute,second);
  }
}

}
}

Прогу я чуть поменял, запустил асинхроный режим Т2, обратите внимание на регистр сравнения при таком значении через 2-3 часа прогона в протэусе часы начинают спешить на 1-2 минуты. (если ставить больше то отстают, если поставить как положено (32-1) то отстают очень сильно.
Часы хочу сделать в железе, но нужно чтоб они шли точно, возможно постараюсь еще чем нб их функционал повысить. Всем спасибо

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 25 июл 2012, 18:27
boogyman
Асинхронный режим таймера это правильно. Попробуй поставь часовой кварц. Девайс лучше налаживать в железе.

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 25 июл 2012, 19:16
ASDFG123
Если собрать в железе будет ли свобода маневра? для модификации и т.д (меги 8 я уже заказал терь жду)
На микрах в железе ничего не делал еще :(
Как можно сделать чтоб контроллер сидел в плате впаян, и его можно было перепрошивать и т.д может выводы какие в разьем ввести ?
п.с что значит часовой кварц ? в протэусе в настройках поставил 32768 Гц

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 25 июл 2012, 19:26
boogyman
ASDFG123 писал(а):п.с что значит часовой кварц ? в протэусе в настройках поставил 32768 Гц
Ставишь кварц на 32768 Гц, настраиваешь предделитель таймера на 128 и у тебя таймер будет прерываться точно раз в секунду, это как вариант.
ASDFG123 писал(а):Как можно сделать чтоб контроллер сидел в плате впаян, и его можно было перепрошивать и т.д может выводы какие в разьем ввести ?
программатор подключаешь к выводам Reset, Mosi, Miso, SCK, подключаешь питание вот тебе и внутрисхемное программирование

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 31 авг 2012, 19:22
ASDFG123
Уже купил большую часть деталей, индикатор не брал еще но скорее всего ОА. Еще купил DS18b20, хотелось бы, приделать термометр и будильник, конечно не ущерб в точности часов. Попытался к готовой проге часов с библиотекой для 7сегментиков, приделать прогу для DS18b20 не заработало ничего, хотел сделать так, по нажатию кнопки на дисплей выводится темпа которая уже была расчитана заранее, а часы продолжали тикать, и через секунд 5 обратно выводились часы. А еще ключ в протэусе хотел проверить на Р-Н-Р для ОА, в симуляторе показывает крякозябы, в библиотеке порты инвертировал не помогло

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 31 авг 2012, 21:57
AntonChip
Хочешь точные часы используй DS1307.

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 31 авг 2012, 22:58
ASDFG123
их я тоже рассматривал но у нас они дорого стоят раза в 2 больше чем мега8, да и всех функций ее реализовать не смогу.
а точности я думаю можно добится если на пример каждые 10 часов прибавлять 1 сек,(эмпирически высчитать) это ведь можно реализовать?

В библиотеке что надо поправить для запуска индикации через ключи, р-н-р и н-р-н транзы в наличии, sbi cbi в самом начале библиотекики менял не помогло.
вот код

Код: Выделить всё

#define F_CPU 8000000UL
#include <avr/io.h> 
#include <util/delay.h>
#include <avr/interrupt.h>
#include "display.h"

 
#include "OWIPolled.h"
#include "OWIHighLevelFunctions.h"
#include "OWIBitFunctions.h"
#include "OWIcrc.h"

#define DS18B20_CONVERT_T                0x44
#define DS18B20_READ_SCRATCHPAD          0xbe
#define BUS   OWI_PIN_0

unsigned char scratchpad[9];
volatile unsigned char second, minute, hour, level;
 
ISR(TIMER2_COMP_vect)	// обработчик прерывания по совпадению Т2
{                       
second++;				// увеличиваем секунды
if(second == 60)        // если second = 60, second = 0
{  second = 0;
   minute++;            // увеличиваем минуты
if(minute == 60)        // если minute = 60, minute = 0
{  minute = 0;
   hour++;              // увеличиваем часы
if(hour == 24)          // если hour = 24, hour = 0
   hour = 0;
}
}
 
set_time(hour,minute,second);
 
}
 
int main(void)
{
hour = 12;	// начальная установка времени
minute = 0;
second = 0;
 
unsigned int tmp = 0;
  unsigned char temperature;
unsigned int tempint = 0,tempint1,tempint2,tempint3;
unsigned int temppoint = 0,temppoint1;
OWI_Init(BUS);
 
DDRB |= (0 << PB5)|(0 << PB4);
PORTB |= (1 << PB5)|(1 << PB4);
DDRC |= (0<<PC1);
PORTC |= (1 << PC1);
TCNT2=0;  
TCCR2|=(1<<CS20)|(0<<CS21)|(1<<CS22)|(1<<WGM21); // 32768/128 =256hz запуск Т2 (CTC ?)
ASSR|=(1<<AS2); //ассинхронный режим
 
OCR2=(203); //регистр сравнения (пришлось поставить так, точность ближе)
 
sei();                 // глобально разрешам прерывания
 
set_brightness(80);   // начальная установка яркости дисплея
display_init();        // инициализация дисплея
 
shift_in('t'); // выводим бегущую строку "test display"
_delay_ms(50);
shift_in('E');
_delay_ms(50);
shift_in('s');
_delay_ms(50);
shift_in('t');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
shift_in('d');
_delay_ms(50);
shift_in('i');
_delay_ms(50);
shift_in('s');
_delay_ms(50);
shift_in('p');
_delay_ms(50);
shift_in('L');
_delay_ms(50);
shift_in('a');
_delay_ms(50);
shift_in('y');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
shift_in(' ');
_delay_ms(50);
clear_screen();
_delay_ms(100);
 
TIMSK |= (1<<OCIE2); // разрешаем прерывание по совпадению Т2
while(1)
{	
 
 
 
unsigned char i, dr;
 
 
 
if((PINB&(1 << PB4))==0 && (PINB&(1 << PB5))==0)// если кнопка Часы+ и Минуты+ нажаты
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(10);
   if((PINB&(1 << PB4))==0 && (PINB&(1 << PB5))==0) 
   dr++;
  } 
if(dr > 5) 
  {
   if(level != 99) 
   level++;	// увеличиваем яркость
   else level = 0;
   set_brightness(level);
  }
} 
 
if((PINB&(1 << PB4))==0 && PINB&(1 << PB5)) // если кнопка Часы+ нажата
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(10);
   if((PINB&(1 << PB4))==0) 
   dr++;
  } 
if(dr > 5) 
  {
	  second = 0;
   if(hour != 23) hour++;	// увеличиваем часы
   else hour = 0;
   set_time(hour,minute,second);
  }
} 
 
if((PINB&(1 << PB5))==0 && PINB&(1 << PB4)) // если кнопка Минуты+ нажата
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(10);
   if((PINB&(1 << PB5))==0) 
   dr++;
  } 
if (dr > 5) 
  {
	  second = 0;
   if(minute != 59) minute++;	// увеличиваем минуты
   else minute = 0;
   set_time(hour,minute,second);
  }
  }
 
 
 
 
 
 
if((PINC&(1 << PC1))==0) // если кнопка темп нажата
{
dr=0;
for (i=0;i<10;i++)
  { // программный антидребезг контактов
   _delay_ms(10);
   if((PINC&(1 << PC1))==0) 
   dr++;
  } 
if (dr > 5) 
  {
	OWI_DetectPresence(BUS); //а тут программа термодатчика
    OWI_SkipRom(BUS);
    OWI_SendByte(DS18B20_CONVERT_T ,BUS);
	/*ждем, когда датчик завершит преобразование*/ 
    while (!OWI_ReadBit(BUS));
 
    /*подаем сигнал сброса
    команду для адресации всех устройств на шине
    команду - чтение внутренней памяти
    затем считываем внутреннюю память датчика в массив
    */
    OWI_DetectPresence(BUS);
    OWI_SkipRom(BUS);
    OWI_SendByte(DS18B20_READ_SCRATCHPAD, BUS);
    scratchpad[0] = OWI_ReceiveByte(BUS);
    scratchpad[1] = OWI_ReceiveByte(BUS);
 
	if ((scratchpad[1]&128) == 0){ }
    else{
      tmp = ((unsigned int)scratchpad[1]<<8)|scratchpad[0];
      tmp = ~tmp + 1;
      scratchpad[0] = tmp;
      scratchpad[1] = tmp>>8;  
    }
 
temperature = (scratchpad[0]<< 4)& 0x70|((scratchpad[1])>> 4); // тут пытался разделить по сегментам
tempint1 = temperature % 1000 / 100;
tempint2 = temperature % 100 / 10; 
tempint3 = temperature % 10; 
 
set_char_at(tempint1, 0);
set_char_at(tempint2, 1);
set_char_at(tempint3, 2);
set_char_at('t', 3);
  }
  }
}
 
}

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 30 сен 2012, 19:24
ASDFG123
//#define SET_DIGIT cbi
//#define CLEAR_DIGIT sbi
//#define SET_SEGMENT sbi
//#define CLEAR_SEGMENT cbi
как переделать под ключи на pnp транзах ? индикатор ОА

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 01 окт 2012, 15:15
boogyman
Где, в какой библиотеке править? Не вижу?

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 01 окт 2012, 18:29
ASDFG123

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>
#include "display.h"

// Выбираем тип подключения дисплея OA или OK
// common anode
#define SET_DIGIT sbi
#define CLEAR_DIGIT cbi
#define SET_SEGMENT cbi
#define CLEAR_SEGMENT sbi

// common cathode
//#define SET_DIGIT cbi
//#define CLEAR_DIGIT sbi
//#define SET_SEGMENT sbi
//#define CLEAR_SEGMENT cbi

#define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))

char data[4]; // Digit data
char segment_data[4]; // Segment data

// dots [bit 0~3]
uint8_t dots = 0;

uint16_t brightness = 80;	// Read from EEPROM on startup

void display(uint8_t pos, uint8_t digit);
void clearDisplay(void);

void display_init(void)
{
	// set digits as output
	sbi(DIGIT1_DDR, DIGIT1_BIT);
	sbi(DIGIT2_DDR, DIGIT2_BIT);
	sbi(DIGIT3_DDR, DIGIT3_BIT);
	sbi(DIGIT4_DDR, DIGIT4_BIT);
	
	// set segments as output
	sbi(A_DDR,  A_BIT);
	sbi(B_DDR,  B_BIT);
	sbi(C_DDR,  C_BIT);
	sbi(D_DDR,  D_BIT);
	sbi(E_DDR,  E_BIT);
	sbi(F_DDR,  F_BIT);
	sbi(G_DDR,  G_BIT);
	sbi(DP_DDR, DP_BIT);

	// clear screen
	clear_screen();

	sei();	// Enable interrupts

	// Inititalize timer for multiplexing
	TCCR0 = (1<<CS01); // Set Prescaler to clk/8 : 1 click = 1us. CS01=1 
	TIMSK |= (1<<TOIE0); // Enable Overflow Interrupt Enable
	TCNT0 = 0; // Initialize counter
}

uint8_t set_brightness(uint8_t b)
{
	if (b > 100) b = 100;
	b = 100 - b;

	brightness = b + 5;
	return b;
}

void shift_in(char c)
{
	data[0] = data[1];
	data[1] = data[2];
	data[2] = data[3];
	data[3] = c;

	segment_data[0] = segment_data[1];
	segment_data[1] = segment_data[2];
	segment_data[2] = segment_data[3];
	segment_data[3] = 0;
}

void set_char_at(char c, uint8_t offset)
{
	data[offset] = c;
}

void set_segments_at(uint8_t segments, uint8_t offset)
{
	segment_data[offset] = segments;
	data[offset] = 0b10000000; // set upper bit to indicate that segment data should be used for display
}

void shift_in_segments(uint8_t segments)
{
	data[0] = data[1];
	data[1] = data[2];
	data[2] = data[3];
	data[3] = 0b10000000; // set upper bit to indicate that segment data should be used for display

	segment_data[0] = segment_data[1];
	segment_data[1] = segment_data[2];
	segment_data[2] = segment_data[3];
	segment_data[3] = segments;
}

// show number on screen
void set_number(uint16_t num)
{
	data[3] = num % 10;
	num /= 10;
	data[2] = num % 10;
	num /= 10;
	data[1] = num % 10;
	num /= 10;
	data[0] = num % 10;
	dots = 0;
}

void clear_screen(void)
{
	data[0] = ' '; data[1] = ' '; data[2] = ' '; data[3] = ' ';
	cbi(dots, 2);
}

void set_time(uint8_t hour, uint8_t min, uint8_t sec)
{
	set_number(hour * 100 + min);
	if (sec % 2) sbi(dots, 2); // set dot 1 on
	else cbi(dots, 2); // set dot 1 off
}

void set_dots(void)
{
	sbi(dots, 3); // set dot 1 on
}

uint8_t multiplex_counter = 0;

// display multiplexing routine: run once every 5us
void display_multiplex(void)
{
	if (multiplex_counter == 0)
		display(0, 1);
	else if (multiplex_counter == 1)
		display(1, 2);
	else if (multiplex_counter == 2)
		display(2, 3);
	else if (multiplex_counter == 3)
		display(3, 4);
	else if (multiplex_counter == 4)
		clearDisplay();

	multiplex_counter++;

	// brightness setting: 5~100
	if (multiplex_counter == brightness) multiplex_counter = 0;
}

// run once every 1 us
ISR(TIMER0_OVF_vect)
{
	display_multiplex();	
	TCNT0 = 0xFF - 12; // Overflow again after 10 ticks = 10 us
}

uint8_t calculate_segments(uint8_t character)
{
	uint8_t segments = 0;

	switch (character)
	{
		case 0:
		case '0':
		case 'O':
			segments = (1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<E)|(1<<F);
			break;
		case 1:
		case '1':
		case 'l':
			segments = (1<<B)|(1<<C);
			break;
		case 2:
		case '2':
			segments = (1<<A)|(1<<B)|(1<<D)|(1<<E)|(1<<G);
			break;
		case 3:
		case '3':
			segments = (1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<G);
			break;
		case 4:
		case '4':
			segments = (1<<B)|(1<<C)|(1<<F)|(1<<G);
			break;
		case 5:
		case '5':
		case 'S':
		case 's':
			segments = (1<<A)|(1<<C)|(1<<D)|(1<<F)|(1<<G);
			break;
		case 6:
		case '6':
			segments = (1<<A)|(1<<C)|(1<<D)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 7:
		case '7':
			segments = (1<<A)|(1<<B)|(1<<C);
			break;
		case 8:
		case '8':
			segments = (1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 9:
		case '9':
		case 'g':
			segments = (1<<A)|(1<<B)|(1<<C)|(1<<D)|(1<<F)|(1<<G);
			break;
		case 10:
		case 'A':
		case 'a':
			segments = (1<<A)|(1<<B)|(1<<C)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 11:
		case 'B':
		case 'b':
			segments = (1<<C)|(1<<D)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 12:
		case 'C':
			segments = (1<<A)|(1<<D)|(1<<E)|(1<<F);
			break;
		case 'c':
			segments = (1<<D)|(1<<E)|(1<<G);
			break;
		case 13:
		case 'D':
		case 'd':
			segments = (1<<B)|(1<<C)|(1<<D)|(1<<E)|(1<<G);
			break;
		case 14:
		case 'E':
			segments = (1<<A)|(1<<D)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 'e':
			segments = (1<<A)|(1<<B)|(1<<D)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 15:
		case 'F':
		case 'f':
			segments = (1<<A)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 'G':
			segments = (1<<A)|(1<<C)|(1<<D)|(1<<E)|(1<<F);
			break;
		case 'H':
			segments = (1<<B)|(1<<C)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 'h':
			segments = (1<<C)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 'I':
		case 'i':
			segments = (1<<B)|(1<<C);
			break;
		case 'J':
		case 'j':
			segments = (1<<B)|(1<<C)|(1<<D)|(1<<E);
			break;
		case 'L':
			segments = (1<<D)|(1<<E)|(1<<F);
			break;
		case 'M':
		case 'm':
			segments = (1<<A)|(1<<C)|(1<<E)|(1<<G);
			break;
		case 'N':
		case 'n':
			segments = (1<<C)|(1<<E)|(1<<G);
			break;
		case 'o':
			segments = (1<<C)|(1<<D)|(1<<E)|(1<<G);
			break;
		case 'P':
		case 'p':
			segments = (1<<A)|(1<<B)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 'Q':
		case 'q':
			segments = (1<<A)|(1<<B)|(1<<C)|(1<<F)|(1<<G);
			break;
		case 'R':
		case 'r':
			segments = (1<<E)|(1<<G);
			break;
		case 'T':
		case 't':
			segments = (1<<D)|(1<<E)|(1<<F)|(1<<G);
			break;
		case 'U':
			segments = (1<<B)|(1<<C)|(1<<D)|(1<<E)|(1<<F);
			break;
		case 'u':
			segments = (1<<C)|(1<<D)|(1<<E);
			break;
		case 'V':
		case 'v':
			segments = (1<<C)|(1<<D)|(1<<E);
			break;
		case 'W':
		case 'w':
			segments = (1<<A)|(1<<C)|(1<<D)|(1<<E);
			break;
		case 'Y':
		case 'y':
			segments = (1<<B)|(1<<C)|(1<<D)|(1<<F)|(1<<G);
			break;
		case '-':
			segments = (1<<G);
			break;
		case '"':
			segments = (1<<B)|(1<<F);
			break;
		case 0x27:	// "'"
			segments = (1<<B);
			break;
		case '_':
			segments = (1<<D);
			break;
		case ' ':
		default:
			segments = 0;
			break;
	}

	return segments;
}

// Output number to digit 0, 1, 2 or 3
void display(uint8_t pos, uint8_t digit)
{	
	clearDisplay();

	//  Turn on selected digit
	switch (digit)
	{
		case 1:
			SET_DIGIT(DIGIT1_PORT, DIGIT1_BIT);
			break;
		case 2:
			SET_DIGIT(DIGIT2_PORT, DIGIT2_BIT);
			break;
		case 3:
			SET_DIGIT(DIGIT3_PORT, DIGIT3_BIT);
			break;	
		case 4:
			SET_DIGIT(DIGIT4_PORT, DIGIT4_BIT);
			break;
	}

	uint8_t segments = 0;

	if (data[pos] & 0b10000000)
		segments = segment_data[pos];
	else
		segments = calculate_segments(data[pos]);
	
	// set dot
	if (dots & (1<<digit))
		segments |= (1<<DP);

	// This allows segments do be on different ports
	if (segments & _BV(7)) SET_SEGMENT(DP_PORT, DP_BIT);
	else CLEAR_SEGMENT(DP_PORT, DP_BIT);

	if (segments & _BV(6)) SET_SEGMENT(G_PORT, G_BIT);
	else CLEAR_SEGMENT(G_PORT, G_BIT);

	if (segments & _BV(5)) SET_SEGMENT(F_PORT, F_BIT);
	else CLEAR_SEGMENT(F_PORT, F_BIT);

	if (segments & _BV(4)) SET_SEGMENT(E_PORT, E_BIT);
	else CLEAR_SEGMENT(E_PORT, E_BIT);

	if (segments & _BV(3)) SET_SEGMENT(D_PORT, D_BIT);
	else CLEAR_SEGMENT(D_PORT, D_BIT);

	if (segments & _BV(2)) SET_SEGMENT(C_PORT, C_BIT);
	else CLEAR_SEGMENT(C_PORT, C_BIT);
			
	if (segments & _BV(1)) SET_SEGMENT(B_PORT, B_BIT);
	else CLEAR_SEGMENT(B_PORT, B_BIT);

	if (segments & _BV(0)) SET_SEGMENT(A_PORT, A_BIT);
	else CLEAR_SEGMENT(A_PORT, A_BIT);
}

void clearDisplay(void)
{
	// all digits low
	CLEAR_DIGIT(DIGIT1_PORT, DIGIT1_BIT);
	CLEAR_DIGIT(DIGIT2_PORT, DIGIT2_BIT);
	CLEAR_DIGIT(DIGIT3_PORT, DIGIT3_BIT);
	CLEAR_DIGIT(DIGIT4_PORT, DIGIT4_BIT);
	
	// all segments high
	CLEAR_SEGMENT(A_PORT,  A_BIT);
	CLEAR_SEGMENT(B_PORT,  B_BIT);
	CLEAR_SEGMENT(C_PORT,  C_BIT);
	CLEAR_SEGMENT(D_PORT,  D_BIT);
	CLEAR_SEGMENT(E_PORT,  E_BIT);
	CLEAR_SEGMENT(F_PORT,  F_BIT);
	CLEAR_SEGMENT(G_PORT,  G_BIT);
	CLEAR_SEGMENT(DP_PORT, DP_BIT);
}
В этой библиотеке

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 01 окт 2012, 19:38
boogyman
Какой тип подключения нужен, надо раскомментировать его дефайны, другой тип комментируем и наоборот. Сейчас выбрано с общим анодом

Re: Часы AVR ATMega 8, 7 сегментный индикатор

Добавлено: 01 окт 2012, 20:12
ASDFG123
так мне тоже нужен ОА, но с ключами на ПНП транзах. У них наскоко я знаю лог 1 выставляется при 0 на базах (без ключей горят при 1), а 8 катодов (7 сег и точка) не меняются
п.с протеус как мне кажется оч сильно гонит, пытаюсь просимулировать с ключами и показывает абракадабру на всех сегментах, скоро разведу норм плату под дисплей.