Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 18:01:57

Alex_641, запущенный процесс преобразования работает в АЦП аппаратно независимо от того, что делает в данный момент АЛУ, и по окончании его выставляется флаг ПРЕОБРАЗОВАНИЕ ОКОНЧЕНО.

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 18:04:40

Alex_641, из pdf:
All interrupts have a separate Interrupt Vector in the Interrupt Vector table. The interrupts have priority in accordance with their Interrupt Vector position. The lower the Interrupt Vector address, the higher the priority.
---
ru: Все прерывания имеют отдельный вектор прерывания в таблице векторов прерываний. Прерывания имеют приоритет в соответствии с их положением в векторе прерывания. Чем меньше адрес вектора прерывания, тем выше приоритет.

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 18:06:44

А пачему если есть прерывания , то приходиться корректировать показания АЦП каноническими формулами ? А если прерываний нет , то не надо ? КАК ?

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 18:24:02

Alex_641, видимо, что-то ты не правильно делаешь.
два аппаратных устройства работают независимо друг от друга и не мешают друг другу. но ты отказываешься эту независимость понимать.
лично мне никогда не приходилось корректировать результат АЦП - всегда АЦП работает правильно и совершенно линейно.

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 19:13:03

Незнаю почему ! Но вот первый мой вольтметр на пик16ф684 , лет 6 назад . Первые фотки это без компенсации , вторые с ней .
Изображение
Вложения
555.jpg
(225.87 KiB) Скачиваний: 39

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 19:53:05

ADIF отслеживаете завершено ли преобразование, до получения результата?

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 20:05:02

Адиф - это кто ?

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 20:06:48

PIC16F684:
Код:
REGISTER 2-5: PIR1: PERIPHERAL INTERRUPT REQUEST REGISTER 1
...
bit 6 ADIF: A/D Interrupt Flag bit
1 = A/D conversion complete
0 = A/D conversion has not completed or has not been started
...

или без прерывания:
Код:
REGISTER 9-1: ADCON0: A/D CONTROL REGISTER 0
../
bit 1 GO/DONE: A/D Conversion Status bit
1 = A/D conversion cycle in progress. Setting this bit starts an A/D conversion cycle.  This bit is automatically cleared by hardware when the A/D conversion has completed.
0 = A/D conversion completed/not in progress
...

Вероятно, используете данные прежде чем закончилось преобразования.
---
Какова компенсация выше? В коде? В некотором смысле, алгоритм?
Последний раз редактировалось veso74 Сб мар 25, 2023 20:21:53, всего редактировалось 1 раз.

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 20:21:46

Alex_641, а как ты сделал свой измеритель, если даже совсем не знаешь периферию твоего МК?

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб мар 25, 2023 20:54:11

Работает программа , происходит считывание АЦП, и тут .... прерывание то таймеру ... АЦП идёт накуй , само собой , прерывание же ! Да таймеры времени правильно считают время. НО а что с прерванным АЦП происходит ? Он ( АЦП ) получает неизвестно что !?
У меня такое ощущение, что Вы говорите о программном АЦП. А скажу по секрету (только чтобы об этом больше никто не знал!!!), в контроллерах бывают ещё и аппаратные АЦП. Они работают не только независимо от процессора, но даже от другого источника тактовой частоты. То есть проц работает на своей частоте, выполняет свою работу (или просто спит), а АЦП в это же самое время потихоньку на своей (скорее всего более низкой) частоте делает своё дело. Никто никому не мешает, никто ни от кого не зависит. По окончании преобразования аппаратный АЦП выставляет флаг готовности, который может быть заведён также и в систему прерываний (в зависимости от конкретного МК). Поэтому никаких коррекций при чтении данных с аппаратных АЦП не требуется.

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб дек 09, 2023 08:00:48

Все бросились обсуждать, то что не в тему. Читаем название темы: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер. Ничего умного, кроме предложения опроса каждые 100 мс не написано. Я очень долго бьюсь над задачей опроса именно ТМ1638, но конкретного факта нажатия ещё не выловил. Для флага нажатия хоть-какой-нибудь кнопки поставил светодиод. Для вывода кода нажатой кнопки - стоит побитный индикатор на целый порт (использую жирную PIC). Николай Савельев близко подошёл к программной реализации опроса кнопок, но слился с форума. Конкретно есть готовые примеры у кого-нибудь? Не ассемлер не предлагать и АЦП не упоминать - давайте не отходить от темы.

По программе. Пример реализации чтения с ТМ1683. Передаём команду чтения с ТМ1683, затем принимаем четыре байта.
; реализация чтения данных с клавиатуры
movlw 0x42 ; чтение данных с клавиатуры
call Byte_Out ; пересылка данных в ККД
bsf dio_in ; RC5 на ввод
call Byte_In ; принятие данных из ККД
... сохраняем первый принятый байт
call Byte_In ; принятие данных из ККД
... сохраняем второй принятый байт
call Byte_In ; принятие данных из ККД
... сохраняем третий принятый байт
call Byte_In ; принятие данных из ККД
... сохраняем четвёртый принятый байт
bcf dio_in ; RC5 на вывод


И всё. Все четыре принятых байта всегда нулевые. Кнопки естественно бешено и в беспорядке нажимаются.

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Вс янв 07, 2024 18:58:24

Ассемблер 8051.
Спойлер
Код:
;Запись в видео-память возможна в режиме:
;1) фиксированного адреса (команда 0x44): каждый раз сначала передается адрес ячейки памяти, потом байт данных
;2) автоувеличения адреса (команда 0x40): каждый раз сначала передается адрес ячейки памяти, потом несколько байт данных (до 16-ти). Каждый следующий байт пишется в следующую ячейку

;Управление включением-выключеним и яркостью задается командой: 0x80 с параметрами — битами:
;1) Влючение выключание задается установкой/сбросом 3-го бита.
;2) Яркость задается от 0 до 7 — 3-мя младшими битами.

;Запись в видео-память состоит из минимум 2-х байт:
;1) Задает адрес записи (или начала записи, если задан режим автоувеличения адреса): 0xC0 + адрес 0-15.
;2) Собственно байт данных

;Чтение клавиатуры состоит из 3-х этапов:
;1) Отправки команды чтения клавиатуры: 0x42
;2) Не забыть отпустить DIO (setb DIO)
;3) Чтения 32 бит данных

STB      equ     P2.0
CLK             equ     P2.1
DIO             equ     P2.2

Byte      equ     R7              ; отсылаемый в ТМ1638 байт
Bit_counter   equ     R6              ; счетчик отправленых или принятых бит
Bit_counter_   equ     6h              ; он же, в форме для сохранения в стек
Symbol          equ     R5              ; порядковый номер выводимого на индикатор числа
Symbol_counter   equ     R4              ; счетчик выводимых на индикатор чисел, до 8
KeyByte_counter   equ     R3              ; счетчик примаемых байт состояния клавиатуры, до 4
KeyByte_pointer   equ     R1              ; указатель на 1 из 4 примаемых байт состояния клавиатуры (подходит только R0 или R1)
KeyByte      equ     9h              ; байт состояния клавиаутры, установленый байт отвечает нажатой кнопке, после него должны быть свободны еще 3 байта, в которые временно записывается состояние клавиатуры при считывании
Counter         equ     8h              ; счетчик, показывающий порядковый номер нажатой кнопки (установленого бита в байте KeyByte)
Temp_Counter   equ     R2              ; временная версия предыдущего счетчика, из которой делается вычетание при сравнении, и содержимое которой соответсвенно портиться при каждом сравнении
Led_State   equ     0h      ; здесь хранится состояние светодиодов ТМ1638

dseg   at      10h
Stack:

cseg   at      0
   jmp   Ini

org   0Bh                             ; Прерывание по переполнению Timer0
   jmp     TM1638

TM1638:
   push    ACC
   push    Bit_counter_
   mov     Byte,   #01000010b   ; Установка режима работы - Чтение клавиатуры
   ;           |||
   ;           ||+-------- Запись в индикатор (0) / Чтение клавиатуры (1)
   ;           |+--------- Автоинкремент адреса (0) / фиксированный адрес (1)
   ;           +---------- Normal Mode (0) / Test Mode (1)
   call    Send_Byte
   setb    DIO                     ; Установим ногу на вход !!!
   mov     KeyByte_counter,#4      ; Будем читать 4 байта клавиатуры
   mov     KeyByte_pointer,#KeyByte; Установим указатель на место записи 1 считаного байта
Loop_Receive_All_Keys:
   mov     Bit_counter,#8      ; Принимаем 8 бит
Loop_Receive_Byte:
   clr     CLK                     ; Дергаем клок
   rr      A                       ; Прием идет младшим битом вперед, поэтому двигаем вправо
   setb    CLK                     ; По фронту клока на DIO получаем бит
   jb      DIO,   Set_Log_1       ; Формируем запихиваемый бит
   clr     ACC.7
   jmp     Skip_Set_Log_1
Set_Log_1:
   setb    ACC.7
Skip_Set_Log_1:
   djnz    Bit_counter,Loop_Receive_Byte ; Пока не примем 8 бит
   mov     @KeyByte_pointer,A   ; И сохраняем
   inc     KeyByte_pointer      ; Делаем адрес для следующего байта
   djnz    KeyByte_counter,Loop_Receive_All_Keys ; Принимаем 4 байта
   setb    STB                     ; И поднимаем строб - прием закончен
   mov     A,      KeyByte+1   ; А теперь склеим все 4 байта в 1 и получим байт с состоянием всех 8 кнопок
   rl      A
   orl     KeyByte,A
   mov     A,      KeyByte+2
   rl      A
   rl      A
   orl     KeyByte,A
   mov     A,      KeyByte+3
   rl      A
   rl      A
   rl      A
   orl     KeyByte,A      ; Склейка байтов в 1 закончена, теперь у нас в KeyByte состояние всех 8 кнопок (но оно инверсное, то есть установленый бит отвечает нажатой кнопке!)
   mov     Byte,   #01000100b   ; Вернем прежний режим работы - Запись в индикатор, но уже с фиксированным адресом, чтобы можно было что-то оперативно локально менять, не задевая другое
   ;           |||
   ;           ||+-------- Запись в индикатор (0) / Чтение клавиатуры (1)
   ;           |+--------- Автоинкремент адреса (0) / фиксированный адрес (1)
   ;           +---------- Normal Mode (0) / Test Mode (1)
   call    Send_Byte
   setb    STB
   pop     Bit_counter_
   pop     ACC
   reti

Ini:
   mov     SP,   #Stack
;============== Настройка таймеров и маски прерываний ==========================
   mov   TMOD,   #00000001b   ; Режим работы таймеров Т0 и Т1
   ;       ||||||||
   ;       ||||||++-------Режим работы Т0 (01 - 16-бит, 10 - 8-бит с автоперезагрузкой, 11 - 2 независимых 8-бит)
   ;       |||||+---------С/Т0: 0-таймер, 1-счетчик
   ;       ||||+----------: 0-управление по TR0, 1-Управление по TR0 и INT0
   ;       ||++---------- работы Т1 (01 - 16-бит, 10 - 8-бит с автоперезагрузкой, 11 - невозможно)
   ;       |+----------/Т1: 0-таймер, 1-счетчик
   ;       +----------: 0-управление по TR1, 1-управление по TR1 и INT1

   mov   TCON,   #00010000b      ; Управление таймерами Т0 и Т1
   ;       ||||||||
   ;       |||||||+-------IT0 - Тип INT0: 0-по уровню, 1-динамический по спаду
   ;       ||||||+--------IE0 - Запрос прерывания INT0 (при IT0=1 автоматически сбрасывается в обработчике)
   ;       |||||+---------IT1 - Тип INT1: 0-по уровню, 1-динамический по спаду
   ;       ||||+---------- - Запрос прерывания INT1 (при IT1=1 автоматически сбрасывается в обработчике)
   ;       |||+---------- - Запуск Т0
   ;       ||+---------- - Флаг переполнения Timer0
   ;       |+---------- - Запуск Т1
   ;       +---------- - Флаг переполнения Timer1

   mov   IE,   #10000010b      ; Прерывания
   ;       ||||||||
   ;       |||||||+-------EX0 - разрешение обработки прерываний от внешнего входа INT0
   ;       ||||||+--------ЕТ0 - разрешение обработки прерываний от Timer0
   ;       |||||+---------EX1 - разрешение обработки прерываний от внешнего входа INT1
   ;       ||||+---------- - разрешение обработки прерываний от Timer1
   ;       |||+---------- - разрешение обработки прерываний от посл.порта
   ;       ||+---------- - разрешение обработки прерываний от Timer2
   ;       |+----------, не используеться
   ;       +---------- - разрешение обработки всех прерываний
;============== Настройка TM1638 ============
   mov     Byte,   #01000000b   ; Установка режима работы
   ;           |||
   ;           ||+-------- Запись в индикатор (0) / Чтение клавиатуры (1)
   ;           |+--------- Автоинкремент адреса (0) / фиксированный адрес (1)
   ;           +---------- Normal Mode (0) / Test Mode (1)
   call    Send_Byte
   setb    STB
   mov     Byte,   #10001000b   ; Управление яркостью индикатора
   ;           ||||
   ;           |||+------- Младший бит яркости
   ;           ||+-------- Средний бит яркости
   ;           |+--------- Старший бит яркости
   ;           +---------- Бит включения индикатора
   call    Send_Byte
   setb    STB
;============================
; Заполнение индикаторов и светодиодов TM1638 начальными значениями, необходимо, чтобы не выводился мусор, если все должно быть погашено, заполняем нулями
;============================
   mov     Byte,   #11000000b   ; Установка начального адреса -  (0b - 1 знакоместо дисплея, 1b - LED1, 10b - 1 знакоместо дисплея, 11b - LED2 и т.д.)
   ;           ||||
   ;           |||+------- 1 бит адреса
   ;           ||+-------- 2 бит адреса
   ;           |+--------- 3 бит адреса
   ;           +---------- 4 бит адреса
   call    Send_Byte      ; Адрес шлем без строба
   mov     Symbol,   #1
   mov   Symbol_counter,#8
Loop_Symbol:
   mov     DPTR,   #Symbol_Table   ; Адрес таблицы в DPTR
   mov     A,   Symbol          ; Номер символа в АСС
   movc   A,   @A+DPTR         ; Достаем символ из таблицы
   mov     Byte,   A               ; Запихиваем
   call    Send_Byte               ; и отправляем
   inc   Symbol                  ; Следующий символ из таблицы символов
   mov     Byte,   #0      ; Каждый второй байт (последний бит байта) это отдельный светодиод, поэтому просто гасим их
   call    Send_Byte
   djnz    Symbol_counter,Loop_Symbol; Шлем 8 бит
   setb    STB         ; А после данных - строб
;============== Главный цикл ==================
   mov   KeyByte,#0
   mov     Led_State,#0            ; Установим начальное состояние светодиодов - все выключены
Main:
;============== Процедура преобразования порядкового номера бита в байте в число, соответствующее его порядковому номеру ================
   mov     A,      KeyByte
   jz      Main                    ; Если нет нажатыж клавиш, нечего сюда и лезть
   mov     Counter,#0              ; Обнулим счетчик порядкового номера бита
Loop:
   mov     Temp_Counter,Counter    ; Перенесем счетчик порядкового номера бита во временную переменную
   cjne    Temp_Counter,#8,Skip    ; И проверяем, все ли 8 бит были проверены
   jmp     Main                    ; Да, валим в начало (в реальности попадание сюда теоретически невозможно, потому что пустой байт jz Main не пропустит, а выставлений бит кнопки выкинет из цикла до попадания сюда)
Skip:
   inc     Counter                 ; Нет, проверяем следующий бит
   rr   A                       ; Заталкиваем его в ACC.7
   jnb     ACC.7,  Loop
;============== Здесь мы получаем в Counter число, соответствующее порядковому номеру выставленного в KeyByte бита ====
   mov     DPTR,   #Led_Addr_Table ; Загружаем таблицу адресов светодиодов
   mov     A,      Counter         ; Порядковый номер установленого бита - это номер светодиода, состояние котрого мы будем менять
   movc   A,   @A+DPTR         ; Берем адрес светодиода
   clr     EA                      ; Запрещаем прерывания, чтобы сканирование клавиатуры не мешало отправлять данные
   mov     Byte,   A               ; Загружаем адрес свтодиода
   call    Send_Byte      ; И отсылаем (адрес шлем без строба)
;============== Этот кусок определяет, включать, или выключать светодиод в зависимости от его предыдущего состояния ====================
   mov     A,      Led_State       ; Загрузим состояние светодиодов
Loop_2:
   rr   A                       ; Провернем вправо
   djnz   Counter,Loop_2          ; Столько раз, сколько насчитали в счетчик порядкого номера установленого бита
   jb      ACC.7,Led_Off      ; Проверим, включен ли текущий светодиод (по логике, нам надо было бы проверять 0 бит, но 1 раз сдвиг мы делаем в любом случае, так что 0 бит переместится в 7, поэтому его и проверяем)
   mov     Byte,#1                ; Выключен, будем зажигать
   jmp     Skip_Led_Off
Led_Off:
   mov     Byte,#0                ; Включен, будем гасить
Skip_Led_Off:
;===========================
   call    Send_Byte
   setb    STB         ; А после данных - строб
   mov     A,      KeyByte
   xrl     Led_State,A      ; Переключим состояние светодиодов
   setb    EA
   jmp     Main
;============== Отправка 1 байта =============
Send_Byte:
        mov     A,   Byte
   mov     Bit_counter,#8
   clr     STB
Loop_Send_Byte:
   jb      ACC.0,   Log_1           ; Передача идет младшим битом вперед, поэтому проверяем нулевой бит
   clr     DIO
   jmp     Skip_Log_1
Log_1:
   setb    DIO
Skip_Log_1:
   clr     CLK
   rr   A                       ; Передача идет младшим битом вперед, поэтому двигаем вправо
   setb    CLK
   djnz    Bit_counter,Loop_Send_Byte
   ret
;============== Таблица символов ==============
Symbol_Table:
   db   00111111b      ; 0
   db   00000110b      ; 1
   db   01011011b      ; 2
   db   01001111b      ; 3
   db   01100110b      ; 4
   db   01101101b      ; 5
   db   01111101b      ; 6
   db   00000111b      ; 7
   db   01111111b      ; 8
   db   01101111b      ; 9
   
Led_Addr_Table:
   db      0
   db      0C1h                  ; Адрес 1 светодиода
        db      0C3h         ; Адрес 2 светодиода
        db      0C5h         ; Адрес 3 светодиода
        db      0C7h         ; Адрес 4 светодиода
        db      0C9h         ; Адрес 5 светодиода
        db      0CBh         ; Адрес 6 светодиода
        db      0CDh         ; Адрес 7 светодиода
        db      0CFh         ; Адрес 8 светодиода
end

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Сб янв 13, 2024 11:34:29

Спасибо, посмотрю. Но вроде топикстартер не эту программу приводил?

Re: Плата LED&KEY (TM1638). Чтение кнопок, ассемблер.

Чт янв 18, 2024 04:11:23

Спасибо, посмотрю. Но вроде топикстартер не эту программу приводил?

Я не смотрел код топикстартера. В последнем сообщении темы просили код на ассемблере, я привел свой рабочий код, с комментариями. Правда писал я его лет 5 назад, когда ещё совсем зелёным был, поэтому скорее всего можно написать и лучше. Но комментарии по особенностям работы с ТМ1638 есть, так что можно разобраться.
Ответить