Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2545
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2047
∙ повысить рейтинг »
vladisslav
Статус: 8-й класс
Рейтинг: 1327
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1389
Дата выхода:01.12.2010, 08:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:221 / 67
Вопросов / ответов:2 / 2

Вопрос № 180942: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следуюшей задачи: - написать программу в среде MPLab для микроконтроллера PIC16F84. Требуется последовательно выводить числа от 0 до максимально возможного числа с использованием таймер...


Вопрос № 180947: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Здравствуйте еще раз, помоги те пожалуйста с решением задачи, связанную с сопроцессорами "Рассчитать и вывести значение выражения, при заданных пользователем значени...

Вопрос № 180942:

Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следуюшей задачи:
- написать программу в среде MPLab для микроконтроллера PIC16F84. Требуется последовательно выводить числа от 0 до максимально возможного числа с использованием таймера прерываний на индикатор.
Прилагаю блок - схему, по которой пишется программа с точностью до обозначений (но в ней чего-то не хватает). Из этой блок - схемы удалять элементы нельзя и переобозначать переменные тоже. Однако, насколько я понимаю, необходимо добавить блок - схемы некоторых подпрограмм. Вот ссылка:

blok_shema.pdf (103.6 кб)

К ответу прошу также приложить и блок - схему с ДОПОЛНЕНИЯМИ!
Под индикатором, на который последовательно выводятся числа, понимается следующий приборчик:



Система команд микроконтроллера PIC16F84 такова :




Спасибо за Ваш труд!


Отправлен: 26.11.2010, 00:09
Вопрос задал: Dmitry (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Dmitry!
Вот, накидал программу.
Хотелось бы узнать, рабочая ли она...
Потом добавлю, чего не хватает.
Код:

LIST p=16F84
#include <p16f84.inc>

; Биты регистра PORTB
DAT EQU 04h ; бит данных
SYN EQU 05h ; бит синхронизации

CBLOCK 0CH ; блок рабочих регистров
X
WAIT
W1
W2
W3
CNT1
CNT2
W_TEMP
STATUS_TEMP
ENDC

org 00h ; начало исполняемого кода
GOTO START

org 04h ; программа обработки прерываний
MOVWF W_TEMP
MOVF STATUS,W
MOVWF STATUS_T EMP

CLRF TMR0 ;очистка таймера
BCF INTCON,T0IF ;сброс флага прерывания

COMF WAIT,F

MOVF STATUS_TEMP,W
SWAPF W_TEMP,F
SWAPF W_TEMP,W
retfie

; Основная программа
START
; Инициализация PORTB
MOVLW B'11001111' ; настройка порта В

BSF STATUS,RP0 ; выбор банка 1
MOVWF TRISB ; установка RB4, RB5 на вывод

MOVLW B'01110010'
MOVWF OPTION_REG

BCF STATUS,RP0 ; выбор банка 0
;
BSF PORTB,DAT ; установка битов DAT, SYN
BSF PORTB,SYN ; в регистр PORTB

CLRF X ;X = 0
CLRF WAIT ;WAIT = 0

CLRF TMR0
MOVLW B'10100000'
MOVWF INTCON

MAIN ;основной цикл
BTFSS WAIT,0
GOTO MAIN

CALL VYVOD ;рисуем X

COMF WAIT,F

INCF X,F
GOTO MAIN

VYVOD
MOVF X,W
MOVWF W1

MOVLW 4
MOVWF CNT1
DIGITS
MOVLW 10
CALL DIVIDE
CALL CODING
CALL OUT

DECFSZ CNT1,F ; по всем 4 цифрам
GOTO DIGITS

RETURN

;=============================================
; Преобразование BCD -> 7 сегментный код
; получаем в W сегменты индикатора
; 0 - горит
;=============================================
CODING
addwf PCL,F ; W + PC -> PC
retlw b'11000000' ; ..FEDCBA = '0'
retlw b'11111001' ; .....CB. = '1'
retlw b'10100100' ; .G.ED.BA = '2'
retlw b'10110000' ; .G..DCBA = '3'
retlw b'10011001' ; .GF..CB. = '4'
retlw b'10010010' ; .GF.DC.A = '5'
retlw b'10000010' ; .GFEDC.A = '6'
retlw b'11111000' ; .....CBA = '7'
retlw b'10000000' ; .GFEDCBA = '8'
retlw b'10010000' ; .GF.DCBA = '9'

; Подпрограмма вывода
OUT
MOVWF W2 ; сохраним в W2
MOVLW D'8' ; 8 бит
MOVWF CNT2 ; в счетчик CNT2
SEGMENTS
BCF P ORTB,DAT ; установка в 0 RB4 (чтобы горело)
BTFSC W2,0 ; если 0 бит в регистре W2 = 0, то пропускаем
BSF PORTB,DAT ; команду, если нет, то установка RB4 в 1 (чтобы потухло)

; синхронизация PORTB
BCF PORTB,SYN
BSF PORTB,SYN

RRF W2,F ; сдвиг вправо, через перенос
DECFSZ CNT2,F ; по всем 8 битам
GOTO SEGMENTS ; переход на метку SEGMENTS

RETURN ; возврат из подпрограммы

DIVIDE
MOVWF W2 ; сохраним в W2
MOVF W1,W
MOVWF W3 ; сохраним в W3
MOVF W2,W
CLRF W1
SUBLOOP
SUBWF W3,F
BTFSS STATUS,C
GOTO DIVRET
INCF W1,F
GOTO SUBLOOP
DIVRET
ADDWF W3,W

RETURN

END

-----
Люби своего ближнего, как самого себя

Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 26.11.2010, 17:54
Номер ответа: 264350
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 264350 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 180947:

    Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
    Здравствуйте еще раз, помоги те пожалуйста с решением задачи, связанную с сопроцессорами
    "Рассчитать и вывести значение выражения, при заданных пользователем значениях x и a." и пример:

    Отправлен: 26.11.2010, 03:13
    Вопрос задал: Алексей Патрин (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, Алексей Патрин!
    Вот Вам программа...
    Считается все, как в формуле (без упрощений) ...
    Код:

    .model tiny, C
    .data
    sX db 'Enter x: $' ;приглашения для ввода
    sA db 0ah,'Enter a: $'
    sY db 0ah,'Y = $' ;результат
    sAny db 0dh,0ah,'Press any key$'

    x dq 0 ;переменные
    a dq 0

    num db 32 ;буфер для ввода строки
    len db 0
    String db 32 dup (0)

    .code
    .386
    .startup
    lea dx, sX
    mov ah, 9
    int 21h ;ждем Х

    lea dx, num
    mov ah, 0ah
    int 21h

    call str2float ;преобразуем строку в double
    fstp x
    lea dx, sA
    mov ah, 9
    int 21h ;ждем А

    lea dx, num
    mov ah, 0ah
    int 21h

    call str2float ;преобразуем строку в double
    fstp a

    call calcY, offset a, offset x ;считаем по формуле

    call float2str ;преобразуем в строку
    lea dx, sY
    mov ah, 9
    int 21h
    lea dx, String ;выведем
    mov ah, 9
    int 21h

    lea dx, sAny
    mov ah, 9
    int 21h ;ждем "any key"

    mov ah, 8
    int 21h

    mov ax, 4c00h
    int 21h

    ;експонента st=e^st
    exp proc
    fldl2e ;log(осн 2)e->st
    fmulp ;st(1)*log(осн 2)e->st
    fld st ;x*log[2]e->st(1)
    frndint ;округляем st до целого
    fsub st(1),st ;st(1)-=st
    fxch ;st(1)<->st
    f2xm1 ;st=(2 в степени st) - 1
    fld1 ;1->st
    fadd ;st+=1
    fscale ;exp = st * (2 в степени st(1))
    fstp st(1) ;чтобы убрать значение из st(1)
    ret
    exp endp

    ;считаем по формуле
    y=(3*4 +5*6-ae^x)/(7/2+4/3+12/3)*(16/2)*3*6*cos(a/x)
    calcY proc pa:word, px:word
    local c2:word, c3:word, c4:word, c5:word, c6:word, c7:word, c12:word, c16:word
    uses di, si
    mov di, pa ;адрес А
    mov si, px ;адрес Х
    mov c2, 2 ;константы
    mov c3, 3
    mov c4, 4
    mov c5, 5
    mov c6, 6
    mov c7, 7
    mov c12, 12
    mov c16, 16

    fild c3 ;3
    fimul c4 ;3*4
    fild c5 ;5
    fimul c6 ;5*6
    faddp ;3*4+5*6
    fld qword ptr [si] ;x
    call exp ;e^x
    fmul qword ptr [di] ;a*e^x
    fsubp st(1), st ;3*4+5*6-a*e^x

    fild c7 ;7
    fidiv c2 ;7/2
    fild c4 ;4
    fidiv c3 ;4/3
    faddp ;7/2+4/3
    fild c12 ;12
    fidiv c3 ;12/3
    faddp ;7/2+4/3+12/3

    fdivp ;y=(3*4+5*6-a*e^x)/(7/2+4/3+12/3)

    fimul c16 ;y*16
    fidiv c2 ;y*16/2
    fimul c3 ;y*16/2*3
    fimul c6 ;y*16/2*3*6

    fld qword ptr [di] ;a
    fdiv qword ptr [si] ;a/x
    fcos ;cos(a/x)
    fmulp ;y*16/2*3*6*cos(a/x)
    ret
    c alcY endp

    ;Преобразование строки в вещественное число в st сопроцессора
    str2float proc ;преобразование строки в вещественное число
    local ww:word ;для загрузки в сопроцессор
    local dcount:word ;число знаков после точки
    local wSign:word ;знак числа
    local c10:word ;10

    fldz ;подготовим st=0
    lea si, String ;числовая строка
    xor ax, ax ;0
    mov dcount, ax ;число знаков после точки = 0
    mov wSign, ax ;положительное
    mov c10, 10 ;10
    s2fStart: ;цикл обхода незначащих стартовых пробелов
    lodsb
    cmp al, 0dh
    je s2fRet ;по концу строки - выход
    cmp al, ' '
    je s2fStart ;на повтор
    cmp al, 9
    je s2fStart
    cmp al, '-'
    jne s2fCompare ;все остальное - на анализ
    inc wSign ;по минусу - взводим признак минуса
    s2fNext:
    lodsb ;очередной символ
    s2fCompare:
    cmp al, '.' ;точка
    je s2fInc
    cmp al, '0'
    jb s2fSign ;все, что не цифры - конец числа
    cmp al, '9'
    ja s2fSign

    and ax, 0fh ;иначе готовим разряд
    mov ww, ax ; для загрузки в сопроцессор
    cmp dcount , 0 ;если целая часть, то
    je s2fMul10 ; на умножение на 10
    mov cx, dcount ;иначе делим dcount раз на 10
    fild ww ; очередной разряд
    s2fdiv:
    fidiv c10 ;делим dcount раз
    loop s2fdiv
    faddp ;складываем разряд за точкой с формируемым числом
    s2fInc:
    inc dcount ;для точки только увеличиваем dcount
    jmp s2fNext ;пока не дойдем до конца

    s2fMul10: ;целое число
    fimul c10 ;умножаем старое на 10
    fiadd ww ;и прибавляем очередной разряд
    jmp s2fNext
    s2fSign:
    cmp wSign, 0 ;если bSign == 1
    je s2fRet
    fchs ;то меняем знак
    s2fRet:
    ret
    str2float endp

    ;преобразование вещественного числа из st в строку по адресу String
    float2str proc
    local c10:word ;10
    local wSign:word ;знак
    local dig:word ;буфер для извлечения целого из сопроцессора
    local sTemp:byte:64 ;временный буфер для строки

    mov c10, 10 ;10
    mov wSign, 0 ;пока считаем, что положительное
    lea di, sTemp ;здесь буде м формировать строку
    ftst ;Проверяем число
    fstsw ax ;флаги в ax
    sahf ;флаги в регистре флагов
    jnz f2s_notZero ;не 0
    mov ax, '$0' ;если 0, то выводим 0
    stosw
    jmp f2s_Ret ;на выход

    f2s_notZero: ;не 0
    jnc f2s_1 ;если отрицательное,
    inc wSign ; то помечаем минус
    fchs ; и оставляем модуль числа.
    ; Пояснение далее пойдёт на примере. ; ST(0) ST(1) ST(2) ST(3) ...
    ; Отделим целую часть от дробной. ; 73.25 ...
    f2s_1: fld1 ; 1 73.25 ...
    fld st(1) ; 73.25 1 73.25 ...
    ; Остаток от деления на единицу даст дробную часть.
    fprem ; 0.25 1 73.25 ...
    ; Если вычесть её из исходного числа, получится целая часть.
    fsub st(2), st ; 0.25 1 73 ...
    fxch st(2) ; 73 1 0.25 ...
    ; Сначала поработаем с целой частью. Считать количество цифр будем в CX.
    xor cx, cx
    ; Поделим целую часть на десять,
    f2s_2: fidiv c10 ; 7.3 1 0.25 ...
    fxch st(1) ; 1 7.3 0.25 ...
    fld st(1) ; 7.3 1 7.3 0.25 ...
    ; отделим дробную часть - очередную справа цифру целой части исходного числа,-
    fprem ; 0.3 1 7.3 0.25 ...
    ; от чатсного оставим только целую часть
    fsub st(2), st ; 0.3 1 7 0.25 ...
    ; и сохраним цифру
    fimul c10 ; 3 1 7 0.25 ...
    fistp dig ; 1 7 0.25 ...
    inc cx
    ; в стеке.
    push dig
    fxch st(1) ; 7 1 0.25 ...
    ; Так будем повторять, пока от целой части не останется ноль.
    ftst
    fstsw ax
    sahf
    jnz f2s_2
    ; Теперь выведем её.
    f2s_3: pop ax
    ; Вытаскиваем очередную цифру, переводим её в символ и выводим.
    add al, 30h
    stosb
    ; И так, пока не выведем все цифры.
    loop f2s_3 ; 0 1 0.25 ...
    ; Итак, теперь возьмёмся за дробную часть, для начала проверив её существование.
    fstp st(0) ; 1 0.25 ...
    fxch st(1) ; 0.25 1 ...
    ftst
    fstsw ax
    sahf
    jz f2s_5
    ; Если она всё- таки ненулевая, выведем точку
    lea ax, sTemp
    mov cx, di
    sub cx, ax
    sub cx, 63
    neg cx
    mov al, '.'
    stosb
    ; Помножим дробную часть на десять
    f2s_4: fimul c10 ; 2.5 1 ...
    fxch st(1) ; 1 2.5 ...
    fld st(1) ; 2.5 1 2.5 ...
    ; отделим целую часть - очередную слева цифру дробной части исходного числа,-
    fprem ; 0.5 1 2.5 ...
    ; оставим от произведения лишь дробную часть
    fsub st(2), st ; 0.5 1 2 ...
    fxch st(2) ; 2 1 0.5 ...
    ; сохраним полученную цифру во временной ячейке
    fistp dig ; 1 0.5 ...
    ; и сразу выведем.
    mov ax, dig
    add al, 30h
    stosb
    ; Теперь, если остаток дробной части ненулевой
    fxch st(1) ; 0.5 1 ...
    ftst
    fstsw ax
    sahf
    ; и мы вывели менее cx цифр, продолжим
    loopnz f2s_4 ; 0 1 ...
    ; Итак, число выведено. Осталось убрать мусор из стека.
    f2s_5: fstp st(0) ; 1 ...
    fstp st(0) ; ... mov byte ptr [di], '$'

    ; и скопировать в буфер String
    lea si, sTemp
    lea di, String
    xor cx, cx ;длина
    c mp wSign, 0 ;проверим на знак
    je f2s_6
    mov al, '-' ;отрицательное
    stosb
    f2s_6:
    lodsb
    stosb ;копируем 1 байт
    inc cx ;считаем
    cmp cx, 14 ;копируем только 14 байт !!! (если получится число
    ; с большим чем 14 байт знаков, то последние усекутся)
    je f2s_7 ;насильно закрываем $!
    cmp al, '$'
    jne f2s_6 ;копирование завершаем по $
    dec cx ;отнимем 1 (посчитался $)
    f2s_7:
    mov byte ptr [di], '$' ;закроем $ (для случая обрезания)
    f2s_Ret:
    ret
    float2str endp

    end

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 28.11.2010, 01:28
    Номер ответа: 264366
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Оценка ответа: 5

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 264366 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFPRO.RU, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.24 от 30.11.2010

    В избранное