Страница 1 из 3
7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 09:03:08
alex38779
Мяу всем) Ребята ткните мордой в молоко, т.е в ошибку..
Хочу сделать динамическую индикацию через сдвиговый регистр... Второй день моск пилю, не получается. Все выводится да криво....
Схемка такая
настройка SPI
Код: Выделить всё
SPCR = 0<<SPIE | 1<<SPE | 1<<DORD | 1<<MSTR | 0<<CPOL | 0<<CPHA | 1<<SPR1 | 1 <<SPR0;
запись в регистр:
Код: Выделить всё
//это число в разряд индикатора
void send_7segm_digit(int number, int position_digit)
{
SPDR=numb[number];
while(!(SPSR & (1<<SPIF)))
//_delay_us(100);
SPDR=digit[position_digit];
while(!(SPSR & (1<<SPIF)))
// _delay_us(100);
PORTB |= 1<<PB0;
_delay_us(100);
PORTB = 0<<PB0;
}
//а это просто число в индикатор
void send_7segm_data(int data)
{
int number1, number2, number3, number4;
number4 = data % 10;
number3 = (data % 100 - number4) / 10;
number2 = (data % 1000 - number3) / 100;
number1 = (data % 10000 - number2) / 1000;
send_7segm_digit(number1, 3);
_delay_us(100);
send_7segm_digit(number2, 2);
_delay_us(100);
send_7segm_digit(number3, 1);
_delay_us(100);
send_7segm_digit(number4, 0);
_delay_us(100);
}
код пишу в саблайме под линуксом....
весь код
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 11:44:39
oleg110592
PORTB = 0<<PB0; это непонятно
если сбросить бит, наверное так: PORTB &= ~(1<<PB0);
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 16:36:33
alex38779
Не выходит...
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 16:41:20
oleg110592
протеуса проект выложите
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 16:51:24
alex38779
oleg110592 писал(а):
если сбросить бит, наверное так: PORTB &= ~(1<<PB0);
Блинн. От я балбес... Не внимательный.. Заработало..
Благодарю!
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 17:03:35
WiseLord
alex38779 писал(а):Код: Выделить всё
number4 = data % 10;
number3 = (data % 100 - number4) / 10;
number2 = (data % 1000 - number3) / 100;
number1 = (data % 10000 - number2) / 1000;
А вычитать-то зачем? Если потом всё равно делить?
Кстати, вычисления довольно громоздкие для 8-битного AVR, так что 4 разряд будет дольше светиться, чем остальные.
Да и вообще, в индикации на задержках смысла нет. Пустая трата ресурса МК и блокирование основного цикла программы.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 17:33:48
alex38779
WiseLord писал(а):alex38779 писал(а):
Да и вообще, в индикации на задержках смысла нет. Пустая трата ресурса МК и блокирование основного цикла программы.
Я сделаю в таймере индикацию, это для проверки на задержках сделал.
Насчет вычитаний не подумал, уберу, все равно в итоге получу целое число..
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 18:02:50
WiseLord
Мне думается, быстрее будет работать такой вариант:
Код: Выделить всё
_data = data;
number4 = _data % 10;
_data /= 10;
number3 = _data % 10;
_data /= 10;
number2 = _data % 10;
_data /= 10;
number1 = _data % 10;
Тем более, взяв вместо четырех переменных один массив, такой вариант легко зациклить и получить более компактный код.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 19:36:24
oleg110592
ну да - типа так (не мое):
Код: Выделить всё
uint8_t number[4];
void Bin2Bcd(uint16_t value) // HHIMERA(c)
{
uint8_t *p = number;
while (value > 0)
{
*p++ = numb[value % 10];
value /= 10;
}
}
хорошо правда для STM8, STM32 - у них есть аппаратное деление.
#include "display.c" в display.h - не есть хорошо.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 20:08:29
alex38779
oleg110592 писал(а):
#include "display.c" в display.h - не есть хорошо.
А как хорошо?

Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 20:25:46
oleg110592
в makefile можно указать несколько си файлов для сборки проекта
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 20:27:35
alex38779
oleg110592 писал(а):в makefile можно указать несколько си файлов
я не через make компилирую. а командами в терминале. попробую сделать через мейк файл.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Вс июн 28, 2015 20:37:01
oleg110592
мой makefile под вин8.1:
Спойлер
Код: Выделить всё
# Задаем имя проекта, в результате получатся файлы test.hex test.bin
TARG=test
CC = avr-gcc
OBJCOPY = avr-objcopy
SIZE = avr-size
OD = avr-objdump.exe
# Задаем из каких файлов собирать проект, можно указать несколько файлов
SRCS= main.c display.c
OBJS = $(SRCS:.c=.o)
# Задаем для какого микроконтроллера будем компилировать (atmega8)
MCU=atmega8
# Флаги компилятора, при помощи F_CPU определяем частоту на которой будет работать контроллер,
CFLAGS = -mmcu=$(MCU) -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections
LDFLAGS = -mmcu=$(MCU) -Wl,-Map=Test.map -gc-sections
all: $(TARG)
$(TARG): $(OBJS)
$(CC) $(LDFLAGS) -o $@.elf $(OBJS) -lm
$(OBJCOPY) -O binary -R .eeprom -R .nwram $@.elf $@.bin
$(OBJCOPY) -O ihex -R .eeprom -R .nwram $@.elf $@.hex
$(OD) -St $@.elf >$@.lst
$(SIZE) $@.elf
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.elf *.bin *.hex $(OBJS) *.map
все собирается, #include "display.c" убрал:

в принципе индикацию можно несколько упростить:

Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пн июн 29, 2015 07:02:05
alex38779
oleg110592 писал(а):
Код: Выделить всё
uint8_t number[4];
void Bin2Bcd(uint16_t value) // HHIMERA(c)
{
uint8_t *p = number;
while (value > 0)
{
*p++ = numb[value % 10];
value /= 10;
}
}
А в чем разница в использовании uint8 от uint16 в AVR? И стоит ли так делать?
Насчет индикации думаю поставить на каждый разряд свой сдвиг. регистр, просто хочу сэкономить выводы мк под другие цели.
Индикатор у меня будет общий катод или анод(какой найду), катоды, аноды потом посажу на минус-плюс.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пн июн 29, 2015 08:58:16
oleg110592
А в number будут числа больше 255? Зачем uint16 - лишний расход для восьмибитного микроконтроллера.
unsigned int numb и unsigned int digit лучше сделать uint8_t.
Если "на катоды, аноды потом посажу на минус-плюс" то ток через каждый индикатор будет приблизительно такой:
Пусть ток через каждый сегмент будет 10мА.
Если будут "гореть" все сегменты, то ток будет 8*10 = 80 мА.
Если знакомест в индикаторе 4, то общий ток возможен 4*80=320мА.
Имхо динамическая индикация получше будет.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пн июн 29, 2015 09:45:51
alex38779
oleg110592 писал(а):
Если знакомест в индикаторе 4, то общий ток возможен 4*80=320мА.
Имхо динамическая индикация получше будет.
Можно поставить транзисторы.. либо uln после 595 микрухи.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пн июн 29, 2015 10:08:53
oleg110592
если uln или транзисторы, ток общий меньше не станет. При разводке нужны "толстые" шины питания, мощный (импульсный) стабилизатор. Посмотрите статейку, может посегментная динамическая индикация приглянется:
http://we.easyelectronics.ru/Shematech/ ... iya_2.html
uln или транзисторы тоже нужны скорее всего будут, но общий ток будет значительно меньше.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пн июн 29, 2015 10:26:37
alex38779
oleg110592 писал(а):если uln или транзисторы, ток общий меньше не станет. При разводке нужны "толстые" шины питания, мощный (импульсный) стабилизатор.
.
7805 не прокатит? 1,5 А по даташиту держит.. на радиатор прилепить. плюс не все сегменты всегда будут гореть.
uln2003 жирно будет думаю, 500 мА на один выход. хотя в целях удобства разводки платы проще его поставить, чем городить транзисторы и резисторы.
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пн июн 29, 2015 12:01:25
oleg110592
на 7805 при входном напряжении 9В упадет 4В. При токе пусть 200 мА на 7805 будет выделятся мощность 4*0.2=0.8Вт, радиатор скорее всего будет нужен. В uln2003 7 транзисторов, если точка не нужна, то хватит, или один транзистор добавить или uln2803
Re: 7 сегментный индикатор + 74hc595 + atmega 8
Добавлено: Пт июл 03, 2015 11:00:35
alex38779
Опять проблемка. Как лучше сделать вывод на индикатор числа, а иногда нужно вывести букву или число в отдельный разряд индикатора.
Вывод организован в прерывании так:
могу ли я взять директиву #if и сделать так? добавить булеву переменную например word и от нее уже отталкиваться.
Код: Выделить всё
ISR(TIMER0_OVF_vect){
#if !word
//выводим число
set_led_data(i);
#else
//выводим в разряд
set_led_data_position(number, position_digit);
#end_if
}
посоветуйте как лучше сделать?