ИГП-17 — индикатор цифровой многоразрядный газоразрядный предназначен для отображения информации в виде цифр от 0 до 9 (и десятичного знака) в каждом из 16 цифровых разрядов и дополнительной информации в служебном разряде в средствах отображения информации индивидуального и группового пользования.
Основные технические данные
- Яркость свечения > 100 кд/м²
- Номинальная яркость свечения при максимальном токе 170 кд/м²
- Горизонтальный угол обзора при расстоянии наблюдения 0,6-0,8 м > 120°
- Напряжение источника питания вспомогательных катодов (постоянное) > 190 В
- Напряжение возникновения разряда (амплитуда импульса) < 190 В
- Напряжение поддержания разряда (амплитуда импульса) < 170 В
- Напряжение смещения на сегментах относительно анодов (постоянное) < 120 В
- Ток индикации (среднее значение)
- одного сегмента < 25 мкА
- десятичной точки < 18 мкА
- Интервал времени между импульсами, подаваемыми на электроды двух соседних знакомест > 35 мкс
- Время готовности при освещенности 40 лк < 1 с
- Минимальная наработка 5000 ч
- Параметры, изменяющиеся в течение минимальной наработки импульсное напряжение возникновения разряда < 190 В
- средний ток индикации одного сегмента < 30 мкА
- десятичной точки < 21 мкА
- яркость индикатора > 90 кд/м2
- Срок хранения не менее 8 лет
- Вибрационные нагрузки (1—2000 Гц) < 5g
- Многократные ударные нагрузки (длительность удара 2-15 мс) < 15g
- Одиночные ударные нагрузки (длительность удара 2-6 мс) < 75g
- Температура окружающей среды
- при эксплуатации +1…+50°С
- при транспортировке -60…+50°С
- Относительная влажность воздуха не более 98%
- Пониженное атмосферное давление 400 мм рт. ст.
Предельно допустимый электрический режим
- Наименьшее импульсное напряжение источника питания 190 В
- Наименьшее постоянное напряжение источника питания вспомогательных катодов 190 В
- Наибольшее постоянное напряжение смещения на сегментах относительно анодов 120 В
- Рабочий ток одного сегмента
- средний 25…40 мкА
- импульсный 300…700 мкА
- Рабочий ток десятичной точки
- средний 13…20 мкА
- импульсный 200…400 мкА
- Рабочий ток вспомогательного катода 7…15 мкА
- Наименьшая длительность импульса напряжения источника питания 200 мкс
На индикаторе ИГП-17 можно собрать часы и отображать на них текущее время, дату, месяц и год. В качестве микроконтроллера будет использован Atmega8535, так как обладает большим количеством выходов. Текущее время берется из часов реального времени DS3231.
Обеспечивает работу динамической индикации таймер 2 (1250 Гц), PWM сигнал необходимый для работы импульсного преобразователя напряжения контролируется таймером 1 (15625 Гц). Изменяя скважность PWM сигнала можно регулировать выходное напряжение импульсного преобразователя (+180 В).
Анодами индикатора управляют оптроны TLP627, катодами (сегментами) транзисторные ключи на MPSA44. Часы питаются от постоянного напряжения +12 В, в схеме предусмотрен стабилизатор 7805 для питания микроконтроллера Atmega8535 и часов реального времени DS3231.
В часах реального времени DS3231 имеется термометр, его показания периодически выводятся на индикатор вместо даты, месяца и года.
Так же в часах предусмотрен режим антиотравления катодов, раза в час, ровно в 30 минут происходит перебор всех цифр индикаторов в течении 10 секунд.
Для коррекции времени часов используются три кнопки SET, UP и DOWN. При нажатии на кнопку SET начинают мигать показания часов, кнопками UP и DOWN можно установить необходимое время. При коррекции секунд при нажатии кнопок UP и DOWN происходит сброс секунд в ноль.
// ATMEGA8535 16 MHZ #define ADDR 0x68 #define CPU_F 16000000 // Clock Speed #define SCL_F 400000 // // I2C Speed #define TEMP_KORR 20 // -2гр. Цельсия #include <avr/io.h> #include <util/delay.h> byte a[16],an,segm,i; bool w=1,w1; byte sec,min,hour,datat,mont,year; int temper,sett,times; int set_hour,set_min,set_sec,set_datat,set_mont,set_year; int main(){ DDRA = 0xFF; DDRB = 0xFF; DDRC = 0xFF; DDRD |= (1 << PD6)|(1 << PD7); PORTD |= (1 << PD2)|(1 << PD3)|(1 << PD4); TWBR = (((CPU_F)/(SCL_F)-16 )/2) ; TWSR = 0; DDRD |= (1 << PD5); // PWM +180V TIMER_1 cli(); // TIMER_2 F = 16000000/128/100=1250 Hz (800 uS) OCR2 = 100; TCCR2 |= (1 << WGM21); TCCR2 |= (1 << CS22) | (1 << CS20); TIMSK |= (1 << OCIE2); // TIMER_1 F = 16000000/1024/1/1=15625 Hz TCCR1A |= (1 << COM1A1); TCCR1B |= (1 << WGM12); TCCR1A |= (1 << WGM11) | (1 << WGM10); TCCR1B |= (1 << CS10); ICR1 = 1023; OCR1A = 350; sei(); // set_time(22,2,2,4,22,23,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59 _delay_ms(200); while(1) { datat = ((i2c_read(ADDR,4) & 0x0F) + ((i2c_read(ADDR,4) & 0x70) >> 4) * 10); mont = ((i2c_read(ADDR,5) & 0x0F) + ((i2c_read(ADDR,5) & 0x70) >> 4) * 10); year = ((i2c_read(ADDR,6) & 0x0F) + ((i2c_read(ADDR,6) & 0x70) >> 4) * 10); hour = (i2c_read(ADDR,2) & 0x0F) + (((i2c_read(ADDR,2) & 0x70) >> 4) * 10); min = (i2c_read(ADDR,1) & 0x0F) + (((i2c_read(ADDR,1) & 0x70) >> 4) * 10); if(sec==10||sec==40) temper = (((i2c_read(ADDR,0x11)&0b01111111)*10 + ((i2c_read(ADDR,0x12) & 0b11000000) >> 6)*2.5))-TEMP_KORR ; sec = (i2c_read(ADDR,0) & 0x0F) + (((i2c_read(ADDR,0) & 0x70) >> 4) * 10); set_year = year;set_mont = mont;set_datat = datat;set_hour = hour;set_min = min;set_sec = sec; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// BUTTON ///////////// if(((PIND >> PD2) & 1) == 0){sett++;times=0;if(sett>6){sett=0;}wr();_delay_ms(300);} if(((PIND >> PD3) & 1) == 0 && sett==1){set_hour++;w1=1; if(set_hour>23){set_hour=23;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD4) & 1) == 0 && sett==1){set_hour--;w1=1; if(set_hour<0){set_hour=0;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD3) & 1) == 0 && sett==2){set_min++;w1=1; if(set_mont>59){set_min=59;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD4) & 1) == 0 && sett==2){set_min--;w1=1; if(set_mont<0){set_min=0;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD3) & 1) == 0 && sett==3){set_sec=0;w1=1; set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD4) & 1) == 0 && sett==3){set_sec=0;w1=1; set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD3) & 1) == 0 && sett==4){set_datat++;w1=1; if(set_datat>31){set_datat=31;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD4) & 1) == 0 && sett==4){set_datat--;w1=1; if(set_datat<0){set_datat=0;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD3) & 1) == 0 && sett==5){set_mont++;w1=1; if(set_mont>12){set_mont=12;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD4) & 1) == 0 && sett==5){set_mont--;w1=1; if(set_mont<0){set_mont=0;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD3) & 1) == 0 && sett==6){set_year++;w1=1; if(set_year>50){set_year=50;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(((PIND >> PD4) & 1) == 0 && sett==6){set_year--;w1=1; if(set_year<22){set_year=22;} set_time(set_year,0,set_mont,set_datat,set_hour,set_min,set_sec);wr();_delay_ms(300);} if(sett==0){ if(min==30&&sec<10){a[0]=sec%10+20;a[1]=sec%10+20;a[2]=sec%10+20;a[3]=sec%10+20;a[4]=sec%10+20;a[5]=sec%10+20;a[6]=sec%10+20;a[7]=sec%10+20; a[8]=sec%10+20;a[9]=sec%10+20;a[10]=sec%10+20;a[11]=sec%10+20;a[12]=sec%10+20;a[13]=sec%10+20;a[14]=sec%10+20;a[15]=sec%10+20;} else{ if((sec>=10&&sec<=20)||(sec>=40&&sec<=50)){ a[0]=14; a[1]=13; a[2]=temper%10; a[3]=temper/10%10+20; a[4]=temper/100; a[5]=10; a[6]=12; } else{ a[0]=10; a[1]=year%10; a[2]=year/10; a[3]=mont%10+20; a[4]=mont/10; a[5]=datat%10+20; a[6]=datat/10; } a[7]=10; a[8]=sec%10; a[9]=sec/10; a[10]=11; a[11]=min%10; a[12]=min/10; a[13]=11; a[14]=hour%10; a[15]=hour/10; } }// sett=0 if(sett>0){ a[0]=10; if(sett==6){if(times<=500||w1==1){w1=0;a[1]=year%10+20;a[2]=year/10;}else{a[1]=11;a[2]=11;}} if(sett==5){if(times<=500||w1==1){w1=0;a[3]=mont%10+20;a[4]=mont/10;}else{a[3]=11;a[4]=11;}} if(sett==4){if(times<=500||w1==1){w1=0;a[5]=datat%10+20;a[6]=datat/10;}else{a[5]=11;a[6]=11;}} a[7]=10; if(sett==3){if(times<=500||w1==1){w1=0;a[8]=sec%10;a[9]=sec/10;}else{a[8]=11;a[9]=11;}} a[10]=11; if(sett==2){if(times<=500||w1==1){w1=0;a[11]=min%10;a[12]=min/10;}else{a[11]=11;a[12]=11;}} a[13]=11; if(sett==1){if(times<=500||w1==1){w1=0;a[14]=hour%10;a[15]=hour/10;}else{a[14]=11;a[15]=11;}} if(sett!=3){a[8]=sec%10;a[9]=sec/10;} }// sett>0 if(sett==0){_delay_ms(100);} }} void wr(){a[0]=10;a[1]=year%10; a[2]=year/10;a[3]=mont%10+20;a[4]=mont/10;a[5]=datat%10+20;a[6]=datat/10;a[7]=10;a[8]=sec%10; a[9]=sec/10;a[10]=11;a[11]=min%10;a[12]=min/10;a[13]=11;a[14]=hour%10;a[15]=hour/10;} ISR(TIMER2_COMP_vect){ switch(i){ case 0: segm=a[0]; an=16; anod(); _delay_us(600); segment(); if(a[0]==10)an=16;else an=0; anod(); break; case 1: segm=a[1]; an=16; anod(); _delay_us(600); segment(); if(a[1]==10)an=16;else an=1; anod(); break; case 2: segm=a[2]; an=16; anod(); _delay_us(600); segment(); if(a[2]==10)an=16;else an=2; anod(); break; case 3: segm=a[3]; an=16; anod(); _delay_us(600); segment(); if(a[3]==10)an=16;else an=3; anod(); break; case 4: segm=a[4]; an=16; anod(); _delay_us(600); segment(); if(a[4]==10)an=16;else an=4; anod(); break; case 5: segm=a[5]; an=16; anod(); _delay_us(600); segment(); if(a[5]==10)an=16;else an=5; anod(); break; case 6: segm=a[6]; an=16; anod(); _delay_us(600); segment(); if(a[6]==10)an=16;else an=6; anod(); break; case 7: segm=a[7]; an=16; anod(); _delay_us(600); segment(); if(a[7]==10)an=16;else an=7; anod(); break; case 8: segm=a[8]; an=16; anod(); _delay_us(400); segment(); an=8; anod(); break; case 9: segm=a[9]; an=16; anod(); _delay_us(400); segment(); an=9; anod(); break; case 10: segm=a[10]; an=16; anod(); _delay_us(400); segment(); an=10; anod(); break; case 11: segm=a[11]; an=16; anod(); _delay_us(400); segment(); an=11; anod(); break; case 12: segm=a[12]; an=16; anod(); _delay_us(400); segment(); an=12; anod(); break; case 13: segm=a[13]; an=16; anod(); _delay_us(400); segment(); an=13; anod(); break; case 14: segm=a[14]; an=16; anod(); _delay_us(400); segment(); an=14; anod(); break; case 15: segm=a[15]; an=16; anod(); _delay_us(400); segment(); an=15; anod(); break; }i++;if(i>15){i=0;}times++;if(times>600){times=0;}} void segment(){ switch(segm){ // GECDXBFA case 0: PORTA = 0b01110111;break; case 1: PORTA = 0b00100100;break; case 2: PORTA = 0b11010101;break; case 3: PORTA = 0b10110101;break; case 4: PORTA = 0b10100110;break; case 5: PORTA = 0b10110011;break; case 6: PORTA = 0b11110011;break; case 7: PORTA = 0b00100101;break; case 8: PORTA = 0b11110111;break; case 9: PORTA = 0b10110111;break; // GECDXBFA case 20: PORTA = 0b01111111;break; case 21: PORTA = 0b00101100;break; case 22: PORTA = 0b11011101;break; case 23: PORTA = 0b10111101;break; case 24: PORTA = 0b10101110;break; case 25: PORTA = 0b10111011;break; case 26: PORTA = 0b11111011;break; case 27: PORTA = 0b00101101;break; case 28: PORTA = 0b11111111;break; case 29: PORTA = 0b10111111;break; // GECDXBFA case 10: PORTA = 0b00000000;break; // пусто case 11: PORTA = 0b10000000;break; // - case 12: PORTA = 0b11010010;break; // t case 13: PORTA = 0b10000111;break; // гр case 14: PORTA = 0b01010011;break; // C }} void anod(){ switch(an){ case 0: PORTC &=~(1<<PC7);PORTB |=(1<<PB0);break; case 1: PORTB &=~(1<<PB0);PORTB |=(1<<PB1);break; case 2: PORTB &=~(1<<PB1);PORTB |=(1<<PB2);break; case 3: PORTB &=~(1<<PB2);PORTB |=(1<<PB3);break; case 4: PORTB &=~(1<<PB3);PORTB |=(1<<PB4);break; case 5: PORTB &=~(1<<PB4);PORTB |=(1<<PB5);break; case 6: PORTB &=~(1<<PB5);PORTB |=(1<<PB6);break; case 7: PORTB &=~(1<<PB6);PORTB |=(1<<PB7);break; case 8: PORTB &=~(1<<PB7);PORTD |=(1<<PD6);break; case 9: PORTD &=~(1<<PD6);PORTD |=(1<<PD7);break; case 10: PORTD &=~(1<<PD7);PORTC |=(1<<PC2);break; case 11: PORTC &=~(1<<PC2);PORTC |=(1<<PC3);break; case 12: PORTC &=~(1<<PC3);PORTC |=(1<<PC4);break; case 13: PORTC &=~(1<<PC4);PORTC |=(1<<PC5);break; case 14: PORTC &=~(1<<PC5);PORTC |=(1<<PC6);break; case 15: PORTC &=~(1<<PC6);PORTC |=(1<<PC7);break; case 16: PORTB &=~(1<<PB0);PORTB &=~(1<<PB1);PORTB &=~(1<<PB2);PORTB &=~(1<<PB3);PORTB &=~(1<<PB4);PORTB &=~(1<<PB5);PORTB &=~(1<<PB6);PORTB &=~(1<<PB7); PORTD &=~(1<<PD6);PORTD &=~(1<<PD7);PORTC &=~(1<<PC2);PORTC &=~(1<<PC3);PORTC &=~(1<<PC4);PORTC &=~(1<<PC5);PORTC &=~(1<<PC6);PORTC &=~(1<<PC7);break; }} byte i2c_read(byte i2c_addr, byte i2c_reg){ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START while (!(TWCR & (1<<TWINT))); TWDR = i2c_addr << 1; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWDR = i2c_reg; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START while (!(TWCR & (1<<TWINT))); TWDR = (i2c_addr << 1) | 1; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); byte i2c_data = TWDR; TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП return i2c_data; } void i2c_write(byte i2c_addr, byte i2c_reg, byte i2c_dat){ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START while (!(TWCR & (1<<TWINT))); TWDR = i2c_addr << 1; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWDR = i2c_reg; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWDR = i2c_dat; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП } void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){ if(second < 255){i2c_write(ADDR,0x00,(second/10<<4)+second%10);} if(minute < 255){i2c_write(ADDR,0x01,(minute/10<<4)+minute%10);} if(hours < 255){i2c_write(ADDR,0x02,(hours/10<<4)+hours%10);} if(days < 255){i2c_write(ADDR,0x03,days);} if(datas < 255){i2c_write(ADDR,0x04,(datas/10<<4)+datas%10);} if(monts < 255){i2c_write(ADDR,0x05,(monts/10<<4)+monts%10);} if(years < 255){i2c_write(ADDR,0x06,(years/10<<4)+years%10);} }
Скетч использует 5150 байт (67%) памяти устройства. Всего доступно 7680 байт.
Глобальные переменные используют 44 байт (8%) динамической памяти, оставляя 468 байт для локальных переменных. Максимум: 512 байт.
Для поддержки контроллера Atmega8535 в среде разработке Arduino IDE необходимо выполнить следующие действия:
- Откройте вкладку Файл >> Настройки и в поле «Дополнительные ссылки для менеджера плат» добавьте адрес:
https://mcudude.github.io/MightyCore/package_MCUdude_MightyCore_index.json
- Далее откройте вкладку Инструменты >> Плата >> Менеджер плат
В поле поиска введите число: 8535, установите набор плат: MightyCore by MCUdude
- Установите плату (2.0.0)
- Выберите плату ATmega8535
- Для прошивки скетча или загрузчика Вам понадобится программатор USBasp
Схема подключения
Распиновка USBasp
Перед загрузкой в настройках платы укажите частоту кварцевого резонатора (16 МГц), выбрать программатор USBasp, остальные настройки менять не нужно.
Во вкладке «Инструменты» нажмите «Записать загрузчик«.(делается только один раз)
После записи загрузчика Вы в Arduino IDE увидите примерно следующее:
Для загрузки скетча выберите вкладку — Скетч >> Загрузить через программатор
После загрузки скетча появится следующее сообщение:
При использовании программатора USBasp допускается внутрисхемная прошивка контроллера.
Форум — http://forum.rcl-radio.ru/viewtopic.php?id=450
Доработка — добавлен датчик измерения температуры и влажности HTU21D
Скетч и описание на форуме — http://forum.rcl-radio.ru/viewtopic.php?pid=5382#p5382