Dima_Steep
Ученик
- Регистрация
- 17 Май 2021
- Сообщения
- 1
- Реакции
- 0
- Баллы
- 0
Задача. Бегущая строка на PIC(16f877)
Доброго времени суток, уважаемые форумчане! Есть задача, создать бегущую строку с основными требованиями:
1. Индикация динамическая
2. Число знакомест >10
3. Данные считаются уже зашитыми в память МК. Сообщение должно выводится при нажатии на кнопку. ( аля подключили 3 кнопки и на нажатие каждой выводит определенное сообщение)
4. Сообщение должно состоять из 20+- символов, включая пробелы
5. Код asm, без Си.
И самая загвоздка, что не должны использоваться любые аппаратные решения, аля max7219, сдвиговых регистров и тд.
Т.е. тупая задача. Нужно взять допустим память типо 24с64, при необходимости. Зашить в нее там 5 сообщений. Сделать 5 кнопок, и при нажатии на одну из них выводится определенное сообщение( брать 24с64 не обязательно впринципе просто для примера)
PIC16f877 не обязателен тоже, но как по мне он оптимален. LCD нельзя
Итак. Я не прошу делать всю работу за меня конечно же, я уважаю время каждого, но буду очень рад если мне помогут разрешить проблемы с которыми я столкнулся.
Первое. Хотел делать изначально на матричных индикаторах, но без дешифраторов, сдвиговых регистров, драйверов можно реализовать там 2 матрицы 8х8.. Повторюсь, весь алгоритм индикации должен быть в МК. Если я просто не разобрался, и есть варианты как подключить больше 2-3 матриц без всяких приблуд, буду благодарен!
Суть:
Решил взять семисегментные. PORTB,C,D Позволяют подключить порядка 14, если учитывать еще подключение в ПОРТуБ 24С64.
Индикация выполняется через прерывания ( нашел примерный код ), сам пытался делать через паузы, понял что бегущая через паузы это гиблое дело.
Да, с прерываниями я могу просто вручную задать "по тупому" каждый сдвиг вручную прописывая значения для каждого знакоместа. Но хотелось бы понять как реализовать вывод по человечески в цикле и как реализовать считывание определенного сообщения. Т.е. хочу нажать на кнопку и чтобы начало выводится уже предзаписанное сообщение с помощью какого-либо цикла Простите там за тавтологию.
И еще одно, должны быть кнопки аля "+" и " -" которые должны регулировать скорость строки. Но это уже позже.
PS/Всем выделившим время огромное спасибо.
Код программы, исходник и proteus8 схема для 4 индикаторов прилагаю.
Доброго времени суток, уважаемые форумчане! Есть задача, создать бегущую строку с основными требованиями:
1. Индикация динамическая
2. Число знакомест >10
3. Данные считаются уже зашитыми в память МК. Сообщение должно выводится при нажатии на кнопку. ( аля подключили 3 кнопки и на нажатие каждой выводит определенное сообщение)
4. Сообщение должно состоять из 20+- символов, включая пробелы
5. Код asm, без Си.
И самая загвоздка, что не должны использоваться любые аппаратные решения, аля max7219, сдвиговых регистров и тд.
Т.е. тупая задача. Нужно взять допустим память типо 24с64, при необходимости. Зашить в нее там 5 сообщений. Сделать 5 кнопок, и при нажатии на одну из них выводится определенное сообщение( брать 24с64 не обязательно впринципе просто для примера)
PIC16f877 не обязателен тоже, но как по мне он оптимален. LCD нельзя
Итак. Я не прошу делать всю работу за меня конечно же, я уважаю время каждого, но буду очень рад если мне помогут разрешить проблемы с которыми я столкнулся.
Первое. Хотел делать изначально на матричных индикаторах, но без дешифраторов, сдвиговых регистров, драйверов можно реализовать там 2 матрицы 8х8.. Повторюсь, весь алгоритм индикации должен быть в МК. Если я просто не разобрался, и есть варианты как подключить больше 2-3 матриц без всяких приблуд, буду благодарен!
Суть:
Решил взять семисегментные. PORTB,C,D Позволяют подключить порядка 14, если учитывать еще подключение в ПОРТуБ 24С64.
Индикация выполняется через прерывания ( нашел примерный код ), сам пытался делать через паузы, понял что бегущая через паузы это гиблое дело.
Да, с прерываниями я могу просто вручную задать "по тупому" каждый сдвиг вручную прописывая значения для каждого знакоместа. Но хотелось бы понять как реализовать вывод по человечески в цикле и как реализовать считывание определенного сообщения. Т.е. хочу нажать на кнопку и чтобы начало выводится уже предзаписанное сообщение с помощью какого-либо цикла Простите там за тавтологию.
И еще одно, должны быть кнопки аля "+" и " -" которые должны регулировать скорость строки. Но это уже позже.
PS/Всем выделившим время огромное спасибо.
Код программы, исходник и proteus8 схема для 4 индикаторов прилагаю.
Код:
#include <P16F877A.INC>
LIST p=16F877A ;
;
Sec equ 20h ;
Sec1 equ 21h ;
Sec2 equ 22h ;
datind1 equ 23h ;
datind2 equ 24h ;
datind3 equ 25h
datind4 equ 26h ;
shet equ 27h
W_TEMP equ 7Eh
STATUS_TEMP equ 7Fh ;
test equ 28h
#DEFINE ind1 PORTA,0
#DEFINE ind2 PORTA,1
#DEFINE ind3 PORTA,2
#DEFINE ind4 PORTA,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Реализация динамической индикации для 4-х семисегментных индикаторов
;Частота тактового генератора для примера 4 МГц, машинный цикл 1 мкс
org 0000h ;начать выполнение программы с адреса 0000h
clrf test
movlw .4 ;
movwf test ;
goto Start ;переход на метку Start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Подпрограмма обработки прерываний
org 0004h ;начать выполнение подпрограммы с адреса 0004h
movwf W_TEMP ;сохранение значений ключевых регистров
swapf STATUS,W ;
clrf STATUS ;
movwf STATUS_TEMP ;
;
bcf ind1 ;выключение 1-го индикатора
bcf ind2 ;выключение 2-го индикатора
bcf ind3 ;выключение 3-го индикатора
bcf ind4 ;выключение 4-го индикатора
;
incf shet,F ;инкремент регистра shet
movlw .5 ;проверка содержимого регистра shet
xorwf shet,W ;на равенство числу 5
btfss STATUS,Z ;
goto met1 ;число в регистре shet не равно 5
movlw .1 ;число в регистре shet равно 5: запись числа 1
movwf shet ;в регистр shet
;
met1 movlw .1 ;проверка содержимого регистра shet
xorwf shet,W ;на равенство числу 1
btfss STATUS,Z ;
goto met2 ;число в регистре shet не равно 1: переход на met2
movf datind1,W ;число в регистре shet равно 1: копирование
movwf PORTB ;содержимого регистра datind1 в регистр PORTB
bsf ind1 ;включение 1-го индикатора
goto exxit ;переход на метку exxit
met2 movlw .2 ;проверка содержимого регистра shet
xorwf shet,W ;на равенство числу 2
btfss STATUS,Z ;
goto met3 ;число в регистре shet не равно 2: переход на met3
movf datind2,W ;число в регистре shet равно 2: копирование
movwf PORTB ;содержимого регистра datind2 в регистр PORTB
bsf ind2 ;включение 2-го индикатора
goto exxit ;переход на метку exxit
met3 movlw .3 ;проверка содержимого регистра shet
xorwf shet,W ;на равенство числу 3
btfss STATUS,Z ;
goto met4 ;число в регистре shet не равно 3: переход на met4
movf datind3,W ;число в регистре shet равно 3: копирование
movwf PORTB ;содержимого регистра datind3 в регистр PORTB
bsf ind3 ;включение 3-го индикатора
goto exxit ;переход на метку exxit
met4 movf datind4,W ;копирование содержимого регистра datind3
movwf PORTB ;в регистр PORTB
bsf ind4 ;включение 4-го индикатора
;
exxit bcf INTCON,T0IF ;сброс флага прерывания по переполнению TMR0
movlw .100 ;запись числа 156 в регистр таймера TMR0
movwf TMR0 ;
;
swapf STATUS_TEMP,W ;восстановление содержимого ключевых регистров
movwf STATUS ;
swapf W_TEMP,F ;
swapf W_TEMP,W ;
;
retfie ;выход из подпрограммы прерывания
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Основная программа
Start movlw b'00000000'
movwf PORTB
movlw b'00000000'
movwf PORTA
;movlw b'00000111'
; movwf CMCON
bsf STATUS,RP0
movlw b'00000000'
movwf TRISB
movlw b'11110000'
movwf TRISA
;запись двоичного числа 11010011 в регистр
movlw b'11010011' ;OPTION_REG, тем самым устанавливаем внутренний
movwf OPTION_REG ;источник тактового сигнала для TMR0
bcf STATUS,RP0 ;включаем предделитель перед TMR0
;устанавливаем коэффициент предделителя 1:16
;
clrf shet ;обнуление регистра shet, перед запуском
;прерываний по переполнению TMR0, выполняется
;однократно, после включения питания
;
clrf datind1 ;очистка регистров вывода информации на
clrf datind2 ;индикаторы, равнозначно выключению
clrf datind3 ;индикаторов, так как индикаторы с общим
clrf datind4 ;катодом
;
bcf INTCON,T0IF ;сброс флага прерывания по переполнению TMR0
bsf INTCON,T0IE ;разрешение прерываний по переполнению TMR0
bsf INTCON,GIE ;разрешение глобальных прерываний
;
;//---------------------------------------------------------ВЫВОД----------------------------------------------------
m1 movlw b'10111111' ;Вывод нулей на индикаторы
movwf datind1 ;
movwf datind2 ;
movwf datind3 ;
movwf datind4 ;
call pause
goto m1
;//---------------------------------------------------------ВЫВОД----------------------------------------------------
pause movlw .6 ;запись числа 6 в регистр Sec2
movwf Sec2
p4 movlw .218 ;запись числа 218 в регистр Sec1
movwf Sec1
p3 movlw .255
movwf Sec ;запись числа 255 в регистр Sec
p2 decfsz Sec,F ;декремент с условием регистра Sec
goto p2 ;регистр Sec не равен нулю: переход на метку p2
decfsz Sec1,F ;регистр Sec равен нулю: декремент с условием
;регистра Sec1
goto p3 ;регистр Sec1 не равен нулю: переход на метку p3
decfsz Sec2,F ;регистр Sec1 равен нулю: декремент с условием
;регистра Sec2
goto p4 ;регистр Sec2 не равен нулю: переход на метку p4
return ;регистр Sec2 равен нулю: выход из подпрограммы ;
;
;//-----------------------------------Знакогенератор ( почему то работает не корректно) перескакивает не на тот символ постоянно
tablica ;Таблица выборки для индикатора !!!с общим АНОДОМ!!! Точка нам не нужна, везде гасим
; andlw 0x0F ;Маскируем ненужные биты (чтобы случайно не выскочить за предел таблицы)
addwf PCL,f ;Прибавляем значение аккумулятора к счетчику команд PCL. Тем самым выполняя смешение в таблице
retlw b'11000000';0
retlw b'11111001';1 ;В соответствии со схемой определяем к какой ножке порта В какой сегмент подключен.
retlw b'10100100';2
retlw b'01001111';3
retlw b'10011001';4
retlw b'10010010';5
retlw b'10000010';6
retlw b'11111000';7
retlw b'10000000';8
retlw b'10010000';9
retlw b'11111111';+
retlw b'10111111';-
retlw b'11111111' ;A
retlw b'11111111' ;B
retlw b'11111111' ;C
retlw b'11111111' ;D
retlw b'11111111' ;E
retlw b'11111111' ;F
end ;конец всей программы