Программирование МК AVR

 

 

 

Помечено: 

Просмотр 5 сообщений - с 46 по 50 (из 50 всего)
  • Автор
    Сообщения
  • #22271
    cedric69
    Участник

    Здравствуйте! Нужна помощь. Пробую задействовать два входа АЦП на тини13 и чтоб замеры на каждом в пине соответствовали действиям на двух соответствующих выходах. Столкнулся с проблемой – не могу сохранить значения . Значения АЦП вмешиваются во все функции дрыгая не своими ногами. Как сохранить значение предназначенное для отдельной функции и соответственно переписать именно когда дойдет очередь. Очередь я считаю по if (ADCSRA&(1<<ADSC)) и скажем если X четное то “направо” нечетное “налево” За ранее спасибо.

    #22291
    Zhenya
    Участник

    Здравствуйте! Нужна помощь по индикации, но в 3 разряда. Комментарские варинты не работают, а код ниже хорошо показывает 2 разряда.

    #22392
    oleg5672
    Участник

    Здравствуйте друзья нужна помощь подправить код ИК-приёмник на Attiny13. При долговременном нажатии на кнопку пульта светодиод на выходе работает в тригерном режиме , надо поправить код чтоб светодиод при долговременном(удержание кнопки пульта) нажатии на кнопку пульта горел постоянно . Ниже прилагаю код написанный на assembler
    ;– http://radiohlam.ru – собери сам, помоги собрать другу
    ;——————————————————————
    .device ATtiny13
    .include “tn13def.inc”
    .list

    ;– определ¤ем свои переменные
    .def w=r16 ; это будет наш аккумул¤тор
    .def MBC=r17 ; старший байт посылки
    .def LBC=r18 ; младший байт посылки
    .def Sch=r19 ; счЄтчик прин¤тых бит
    .def C_time=r20; текущее значение таймера
    .def H_time=r21; 3/4 бита
    ;– определ¤ем константы
    .equ Sys=29 ; номер системы
    .equ CMD_1=1 ; 000001 код команды=1
    .equ CMD_2=2 ; 000010 код команды=2
    .equ CMD_3=3 ; 000011 код команды=3
    .equ CMD_4=4 ; 000100 код команды=4
    .equ Delay = 100
    ;– »спользуемые регистры
    ; SPL – указатель вершины стека
    ; ACSR – управление компаратором
    ; DDRB – направление работы ног
    ; PORTB – выходы порта
    ; PCMSK – разрешение прерываний на отдельных входах
    ; GIMSK – общее разрешение прерываний по входам
    ; GTCCR – сброс предделител¤
    ; TCCR0B – управление таймером
    ; TIMSK0 – прерывани¤ от таймера
    ; PB0 – выход D3, PB1- выход D2, PB2- выход D1, PB3 – вход, PB4 – выход D4
    ;– начало программного кода
    .cseg
    .org 0
    rjmp Init ; переход на начало программы
    ;– вектора прерываний
    reti ; INT0
    rjmp Pch ; Pin Change
    rjmp Timer ; Timer
    reti ; EEPROM
    reti ; comparator
    reti ; timer compare match A
    reti ; timer compare match B
    reti ; watchdog
    reti ; ADC
    ;– начало программы
    Init: ldi w,RAMEND ; устанавливаем указатель вершины
    out SPL,w ; стека на старший байт RAM
    sbi ACSR,7 ; выключаем компаратор
    ldi w,0b00010111 ; определ¤ем входы и выходы порта
    out DDRB,w
    ldi w,0b11101000 ; включаем подт¤гивающие резисторы
    out PORTB,w ; и определ¤ем начальное состо¤ние выходов
    ;– разрешить прерывани¤ от таймера (пока он не запущен – прерывани¤ всЄ равно не будет)
    ldi w,0b00000010
    out TIMSK0,w ; разрешить прерывани¤ от таймера
    ;– ќбнул¤ем счЄтчик и регистр флагов
    Reset: in w,PORTB ; читаем порт
    clr Sch
    clt ; сбрасываем флаг “
    ;– разрешить прерывание от входов
    ldi w,0b00100000
    out GIMSK,w ; разрешаем прерывание от входов
    ;– разрешить прерывани¤ на входе PB3
    Start: ldi w,0b00100000
    out GIFR,w ; сбросить флаг прерываний от входов
    ldi w,0b00001000
    out PCMSK,w ; разрешаем прерывани¤ на входе PB3
    sei ; разрешить глобальные прерывани¤
    Scan: nop
    rjmp Scan
    ;– ќЅ–јЅќ“„»  ѕ–?–џ¬јЌ»я ѕќ ¬’ќ?”
    ;– инициализируем счЄтчик, адр.бита, пров.рег., адр.рег.записи
    Pch: tst Sch ; счЄтчик =0?
    brne Next
    Nachalo: sbic PINB,3 ; если на входе низкий уровень – пропускаем команду
    reti ; это не приЄм – выходим
    ldi w,0b00000001
    out GTCCR,w ; сбросить предделитель
    ldi w,0b00000100
    out TCCR0B,w ; запустить таймер с делителем на 256
    sec ; подн¤ть carry flag
    rol LBC
    rol MBC
    inc Sch
    reti
    Next: in C_time,TCNT0 ; читаем значение таймера
    clr w
    out TCNT0,w ; перезапускаем таймер
    cpi Sch,1 ; Sch=1?
    brne Next2
    Next1: mov H_time,C_time
    lsr C_time ; находим четверть бита
    add H_time,C_time ; находим 3/4 бита
    set ; ставим флаг пропуска (T в регистре SREG)
    sec
    rol LBC
    rol MBC
    inc Sch ; увеличиваем счЄтчик
    reti
    Next2: brts Not_Signed_FRont
    Signed_Front:
    cp C_time,H_time
    brsh Long_time
    Short_time: set ; установить признак пропуска
    clc
    sbrc LBC,0 ; пропустить, если прошлоне значение = 0
    sec
    rjmp Zapis_bita
    Long_time: clc ; принимаемый бит инвертирован, по отношению к последнему
    sbrs LBC,0 ; пропустить, если прошлое значение = 1
    sec
    Zapis_bita: rol LBC
    rol MBC
    inc Sch
    cpi Sch,14
    breq rab_chast
    reti
    Not_Signed_Front:
    clt
    reti
    ;– ќЅ–јЅќ“„»  ѕ–?–џ¬јЌ»я ќ“ “ј…ћ?–ј
    Timer: clr w
    out TCCR0B,w ; выключить таймер
    pop w ; очищаем стек
    pop w
    rjmp Reset ; ресетимс¤

    ;– –јЅќ„јя „ј—“№
    ;– ѕроверка номера системы и команды
    rab_chast: clr w
    out TCCR0B,w ; выключить таймер
    out TCNT0,w ; сбросить таймер
    pop w ; очищаем стек
    pop w
    clc
    rol LBC ; сдвигаем всЄ, кроме номера команды в MBC
    rol MBC
    clc
    rol LBC
    rol MBC
    lsr LBC ; выравниваем номер команды младшим битом к
    lsr LBC ; младшему биту байта
    in w,PORTB ; читаем порт B
    cpi LBC,CMD_1
    breq Button1
    cpi LBC,CMD_2
    breq Button2
    cpi LBC,CMD_3
    breq Button3
    cpi LBC,CMD_4
    breq Button4
    rjmp Reset
    Button1: ldi Sch,0b00000001
    eor w,Sch ; инвертируем нулевой бит
    out PORTB,w
    rjmp Thats_all
    Button2: ldi Sch,0b00000010
    eor w,Sch ; инвертируем первый бит
    out PORTB,w
    rjmp Thats_all
    Button3: ldi Sch,0b00000100
    eor w,Sch ; инвертируем второй бит
    out PORTB,w
    rjmp Thats_all
    Button4: ldi Sch,0b00010000
    eor w,Sch ; инвертируем четвЄртый бит
    out PORTB,w
    Thats_all: rcall Pause
    rjmp Reset
    Pause: ldi R22, Delay ; загрузка константы для задержки в регистр R22
    WLoop0:
    ldi R23, 0x28 ; загружаем число 40 (0x28) в регистр R23
    WLoop1:
    ldi R24, 0xFF ; загружаем число 255 (0xFF) в регистр R24
    WLoop2:
    dec R24 ; уменьшаем значение в регистре R24 на 1
    brne WLoop2 ; возврат к WLoop2 если значение в R24 не равно 0
    dec R23 ; уменьшаем значение в регистре R23 на 1
    brne WLoop1 ; возврат к WLoop1 если значение в R23 не равно 0
    dec R22 ; уменьшаем значение в регистре R22 на 1
    brne WLoop0 ; возврат к WLoop0 если значение в R22 не равно 0
    eor w,Sch ; инвертируем второй бит
    out PORTB,w
    ret ; возврат из подпрограммы Pause

    #22565
    Ilya3145456
    Участник

    Здравствуйте. Помогите считать температуру с датчика LMT01. Датчик подключен к ножке внешнего прерывания. При попытках считать импульсы возникла проблема с таймингами между периодами импульсов и паузой.

    #22577
    Andry_EXOSpace
    Участник

    Здравствуйте! Во-первых, большое спасибо вам за сайт!!!
    Но, Изучая урок 22 часть 2. ни как не могу понять:
    Ни как не могу понять как получили значение с АЦП!
    return (unsigned int) ADC; как это работает?
    где обработка регистров ADCH и ADCL. как в 3 части урока?
    Поясните пожалуйста этот момент.

  • Автор
    Сообщения
  • #22271

    cedric69
    Участник
    • Оффлайн

    Здравствуйте! Нужна помощь. Пробую задействовать два входа АЦП на тини13 и чтоб замеры на каждом в пине соответствовали действиям на двух соответствующих выходах. Столкнулся с проблемой – не могу сохранить значения . Значения АЦП вмешиваются во все функции дрыгая не своими ногами. Как сохранить значение предназначенное для отдельной функции и соответственно переписать именно когда дойдет очередь. Очередь я считаю по if (ADCSRA&(1<<ADSC)) и скажем если X четное то “направо” нечетное “налево” За ранее спасибо.

    #22291

    Zhenya
    Участник
    • Оффлайн

    Здравствуйте! Нужна помощь по индикации, но в 3 разряда. Комментарские варинты не работают, а код ниже хорошо показывает 2 разряда.

    #22392

    oleg5672
    Участник
    • Оффлайн

    Здравствуйте друзья нужна помощь подправить код ИК-приёмник на Attiny13. При долговременном нажатии на кнопку пульта светодиод на выходе работает в тригерном режиме , надо поправить код чтоб светодиод при долговременном(удержание кнопки пульта) нажатии на кнопку пульта горел постоянно . Ниже прилагаю код написанный на assembler
    ;– http://radiohlam.ru – собери сам, помоги собрать другу
    ;——————————————————————
    .device ATtiny13
    .include “tn13def.inc”
    .list

    ;– определ¤ем свои переменные
    .def w=r16 ; это будет наш аккумул¤тор
    .def MBC=r17 ; старший байт посылки
    .def LBC=r18 ; младший байт посылки
    .def Sch=r19 ; счЄтчик прин¤тых бит
    .def C_time=r20; текущее значение таймера
    .def H_time=r21; 3/4 бита
    ;– определ¤ем константы
    .equ Sys=29 ; номер системы
    .equ CMD_1=1 ; 000001 код команды=1
    .equ CMD_2=2 ; 000010 код команды=2
    .equ CMD_3=3 ; 000011 код команды=3
    .equ CMD_4=4 ; 000100 код команды=4
    .equ Delay = 100
    ;– »спользуемые регистры
    ; SPL – указатель вершины стека
    ; ACSR – управление компаратором
    ; DDRB – направление работы ног
    ; PORTB – выходы порта
    ; PCMSK – разрешение прерываний на отдельных входах
    ; GIMSK – общее разрешение прерываний по входам
    ; GTCCR – сброс предделител¤
    ; TCCR0B – управление таймером
    ; TIMSK0 – прерывани¤ от таймера
    ; PB0 – выход D3, PB1- выход D2, PB2- выход D1, PB3 – вход, PB4 – выход D4
    ;– начало программного кода
    .cseg
    .org 0
    rjmp Init ; переход на начало программы
    ;– вектора прерываний
    reti ; INT0
    rjmp Pch ; Pin Change
    rjmp Timer ; Timer
    reti ; EEPROM
    reti ; comparator
    reti ; timer compare match A
    reti ; timer compare match B
    reti ; watchdog
    reti ; ADC
    ;– начало программы
    Init: ldi w,RAMEND ; устанавливаем указатель вершины
    out SPL,w ; стека на старший байт RAM
    sbi ACSR,7 ; выключаем компаратор
    ldi w,0b00010111 ; определ¤ем входы и выходы порта
    out DDRB,w
    ldi w,0b11101000 ; включаем подт¤гивающие резисторы
    out PORTB,w ; и определ¤ем начальное состо¤ние выходов
    ;– разрешить прерывани¤ от таймера (пока он не запущен – прерывани¤ всЄ равно не будет)
    ldi w,0b00000010
    out TIMSK0,w ; разрешить прерывани¤ от таймера
    ;– ќбнул¤ем счЄтчик и регистр флагов
    Reset: in w,PORTB ; читаем порт
    clr Sch
    clt ; сбрасываем флаг “
    ;– разрешить прерывание от входов
    ldi w,0b00100000
    out GIMSK,w ; разрешаем прерывание от входов
    ;– разрешить прерывани¤ на входе PB3
    Start: ldi w,0b00100000
    out GIFR,w ; сбросить флаг прерываний от входов
    ldi w,0b00001000
    out PCMSK,w ; разрешаем прерывани¤ на входе PB3
    sei ; разрешить глобальные прерывани¤
    Scan: nop
    rjmp Scan
    ;– ќЅ–јЅќ“„»  ѕ–?–џ¬јЌ»я ѕќ ¬’ќ?”
    ;– инициализируем счЄтчик, адр.бита, пров.рег., адр.рег.записи
    Pch: tst Sch ; счЄтчик =0?
    brne Next
    Nachalo: sbic PINB,3 ; если на входе низкий уровень – пропускаем команду
    reti ; это не приЄм – выходим
    ldi w,0b00000001
    out GTCCR,w ; сбросить предделитель
    ldi w,0b00000100
    out TCCR0B,w ; запустить таймер с делителем на 256
    sec ; подн¤ть carry flag
    rol LBC
    rol MBC
    inc Sch
    reti
    Next: in C_time,TCNT0 ; читаем значение таймера
    clr w
    out TCNT0,w ; перезапускаем таймер
    cpi Sch,1 ; Sch=1?
    brne Next2
    Next1: mov H_time,C_time
    lsr C_time ; находим четверть бита
    add H_time,C_time ; находим 3/4 бита
    set ; ставим флаг пропуска (T в регистре SREG)
    sec
    rol LBC
    rol MBC
    inc Sch ; увеличиваем счЄтчик
    reti
    Next2: brts Not_Signed_FRont
    Signed_Front:
    cp C_time,H_time
    brsh Long_time
    Short_time: set ; установить признак пропуска
    clc
    sbrc LBC,0 ; пропустить, если прошлоне значение = 0
    sec
    rjmp Zapis_bita
    Long_time: clc ; принимаемый бит инвертирован, по отношению к последнему
    sbrs LBC,0 ; пропустить, если прошлое значение = 1
    sec
    Zapis_bita: rol LBC
    rol MBC
    inc Sch
    cpi Sch,14
    breq rab_chast
    reti
    Not_Signed_Front:
    clt
    reti
    ;– ќЅ–јЅќ“„»  ѕ–?–џ¬јЌ»я ќ“ “ј…ћ?–ј
    Timer: clr w
    out TCCR0B,w ; выключить таймер
    pop w ; очищаем стек
    pop w
    rjmp Reset ; ресетимс¤

    ;– –јЅќ„јя „ј—“№
    ;– ѕроверка номера системы и команды
    rab_chast: clr w
    out TCCR0B,w ; выключить таймер
    out TCNT0,w ; сбросить таймер
    pop w ; очищаем стек
    pop w
    clc
    rol LBC ; сдвигаем всЄ, кроме номера команды в MBC
    rol MBC
    clc
    rol LBC
    rol MBC
    lsr LBC ; выравниваем номер команды младшим битом к
    lsr LBC ; младшему биту байта
    in w,PORTB ; читаем порт B
    cpi LBC,CMD_1
    breq Button1
    cpi LBC,CMD_2
    breq Button2
    cpi LBC,CMD_3
    breq Button3
    cpi LBC,CMD_4
    breq Button4
    rjmp Reset
    Button1: ldi Sch,0b00000001
    eor w,Sch ; инвертируем нулевой бит
    out PORTB,w
    rjmp Thats_all
    Button2: ldi Sch,0b00000010
    eor w,Sch ; инвертируем первый бит
    out PORTB,w
    rjmp Thats_all
    Button3: ldi Sch,0b00000100
    eor w,Sch ; инвертируем второй бит
    out PORTB,w
    rjmp Thats_all
    Button4: ldi Sch,0b00010000
    eor w,Sch ; инвертируем четвЄртый бит
    out PORTB,w
    Thats_all: rcall Pause
    rjmp Reset
    Pause: ldi R22, Delay ; загрузка константы для задержки в регистр R22
    WLoop0:
    ldi R23, 0x28 ; загружаем число 40 (0x28) в регистр R23
    WLoop1:
    ldi R24, 0xFF ; загружаем число 255 (0xFF) в регистр R24
    WLoop2:
    dec R24 ; уменьшаем значение в регистре R24 на 1
    brne WLoop2 ; возврат к WLoop2 если значение в R24 не равно 0
    dec R23 ; уменьшаем значение в регистре R23 на 1
    brne WLoop1 ; возврат к WLoop1 если значение в R23 не равно 0
    dec R22 ; уменьшаем значение в регистре R22 на 1
    brne WLoop0 ; возврат к WLoop0 если значение в R22 не равно 0
    eor w,Sch ; инвертируем второй бит
    out PORTB,w
    ret ; возврат из подпрограммы Pause

    #22565

    Ilya3145456
    Участник
    • Оффлайн

    Здравствуйте. Помогите считать температуру с датчика LMT01. Датчик подключен к ножке внешнего прерывания. При попытках считать импульсы возникла проблема с таймингами между периодами импульсов и паузой.

    #22577

    Andry_EXOSpace
    Участник
    • Оффлайн

    Здравствуйте! Во-первых, большое спасибо вам за сайт!!!
    Но, Изучая урок 22 часть 2. ни как не могу понять:
    Ни как не могу понять как получили значение с АЦП!
    return (unsigned int) ADC; как это работает?
    где обработка регистров ADCH и ADCL. как в 3 части урока?
    Поясните пожалуйста этот момент.

Просмотр 5 сообщений - с 46 по 50 (из 50 всего)
  • Для ответа в этой теме необходимо авторизоваться.