Вопрос № 180942: Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следуюшей задачи: - написать программу в среде MPLab для микроконтроллера PIC16F84. Требуется последовательно выводить числа от 0 до максимально возможного числа с использованием таймер...
Вопрос № 180947: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Здравствуйте еще раз, помоги те пожалуйста с решением задачи, связанную с сопроцессорами "Рассчитать и вывести значение выражения, при заданных пользователем значени...
Вопрос № 180942:
Здравствуйте, уважаемые эксперты! Прошу Вас помочь с решением следуюшей задачи: - написать программу в среде MPLab для микроконтроллера PIC16F84. Требуется последовательно выводить числа от 0 до максимально возможного числа с использованием таймера прерываний на индикатор. Прилагаю блок - схему, по которой пишется программа с точностью до обозначений (но в ней чего-то не хватает). Из этой блок - схемы удалять элементы нельзя и переобозначать переменные тоже. Однако, насколько я понимаю, необходимо
добавить блок - схемы некоторых подпрограмм. Вот ссылка:
К ответу прошу также приложить и блок - схему с ДОПОЛНЕНИЯМИ! Под индикатором, на который последовательно выводятся числа, понимается следующий приборчик:
Система команд микроконтроллера 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 ;сброс флага прерывания
; Подпрограмма вывода 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
Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 26.11.2010, 17:54
Номер ответа: 264350 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 264350
на номер 1151 (Россия) |
Еще номера »
Вопрос № 180947:
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: Здравствуйте еще раз, помоги те пожалуйста с решением задачи, связанную с сопроцессорами "Рассчитать и вывести значение выражения, при заданных пользователем значениях x и a." и пример:
Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Алексей Патрин! Вот Вам программа... Считается все, как в формуле (без упрощений) ...
Код:
.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
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 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.