Всем добрый день!
Помогите плиз перевести код программы с Ассемблера на С.
Огромный поклон.
.include "m16def.inc"
.device ATMEGA16
;--задаем имена регистрам------------------
.def temp = r16 ;рабочая переменная
; ---------------Проинициализировали указатель стека------
ldi r16,high(RAMEND) ; Начало
out SPH,r16 ; основной программы
ldi r16,low(RAMEND)
out SPL,r16
;--прерывания------------------------------
rjmp RESET ;Reset Handle
break
reti; jmp EXT_INT0 ; IRQ0 Handler
break
reti; jmp EXT_INT1 ; IRQ1 Handler
break
reti; jmp TIM2_COMP ; Timer2 Compare Handler
break
;reti; jmp TIM2_OVF ; Timer2 Overflow Handler
;break
;reti; jmp TIM1_CAPT ; Timer1 Capture Handler
;break
rjmp TIM1_COMPA
break
break; Timer1 CompareA Handler
break
break
ret; jmp TIM1_COMPB ; Timer1 CompareB Handler
break
break
reti; jmp TIM1_OVF ; Timer1 Overflow Handler
break
reti; jmp TIM0_OVF ; Timer0 Overflow Handler
break
reti; jmp SPI_STC ; SPI Transfer Complete Handler
break
reti; jmp USART_RXC ; USART RX Complete Handler
break
reti; jmp USART_UDRE ; UDR Empty Handler
break
reti; jmp USART_TXC ; USART TX Complete Handler
break
reti; jmp ADC ; ADC Conversion Complete Handler
break
reti; jmp EE_RDY ; EEPROM Ready Handler
break
reti; jmp ANA_COMP ; Analog Comparator Handler
break
reti; jmp TWSI ; Two-wire Serial Interface Handler
break
reti; jmp EXT_INT2 ; IRQ2 Handler
break
reti; jmp TIM0_COMP ; Timer0 Compare Handler
break
reti; jmp SPM_RDY ; Store Program Memory Ready Handler
break
RESET:
;------ Инициализация портов --------
ldi r17, 0x00
out PINA, r17 ; деактивируем Pull-up резисторы
ldi r17, 0x00
out DDRA, r17 ; порт на вывод
sei ;разрешаем прерывания
;------ Инициализация таймера --------
ldi r16, 0x10
out TIMSK, r16 ; разрешение прерывания по совпадению TCNT с OCR
ldi r22, 0x00
out OCR1AH, r22 ;
ldi r22, 0xАА
out OCR1AL, r22 ; устанавливаем предел счета 255
;------------- Тело ----------------------------
ldi r20, 0xAA ; загрузка 10101010 на вывод в PORTA
ldi r21, 0xFF ; слагаемое для Суммы по модулю 2
ldi r16, 0x00
out TCCR1A, r16 ; очистка TCCR1A
ldi r16, 0x0A ; запуск Таймера
out TCCR1B, r16 ; ставим предделитель в CLK/1024
Cycle: ; основной пустой цикл
out PORTA, r20
jmp Cycle
;------- Прерывание --------------
TIM1_COMPA:
nop
push R16 ;
in R16,SREG ; процедура прерывания
push R16 ;
eor r20, r21 ; Изменение 10101010 на 01010101
out PORTA, r20
jmp ttt ; выйти из прерывания
pop R16 ;Востанавливаем регистры
out SREG,R16
pop R16
nop
reti
Перевод с Ассемблера на С
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Перевод с Ассемблера на С
в вашей программе есть несуразности и явные ошибки. но код, похоже, сводится примерно к следующему (WinAVR):
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect){
PORTA ^= 0xFF;
}
int main(void){
DDRA = 0xFF;
PORTA = 0b01010101;
OCR1A = 0x00AA;
TCCR1B = 0x0A; // ох, и не люблю я такие присваивания...
TIMSK = _BV(OCIE1A);
sei();
while(1);
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Перевод с Ассемблера на С
Это и всё?????????
Вот так вот коротко?
И без описаний всех этих векторов прерываний?
Вот так вот коротко?
И без описаний всех этих векторов прерываний?
Re: Перевод с Ассемблера на С
Да, так коротко.
Всю заботу о прерываниях, стеке и т.д. компилятор берет на себя.
Равно как и еще кучу других вещей. Беда только в том, что делает он это не всегда эффективно. Хотя, справедливости ради стоит сказать, что нынешние компиляторы действительно хороши.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Перевод с Ассемблера на С
Всем доброго времени суток.
Помогите пожалуйста перевести код с Ассемблера на С. Программа работы с клавиатурой, написана для 8051.
Заранее огромное спасибо)
---------------------------------------------------
; Подпрограммы для работы с клавиатурой
; ---------------------------------------------------
INKEY_MASK EQU 70h; маска, в которой входы = 1
; подпрограмма ожидания нажатия какой-нибудь кнопки
WaitForKeyPress:
push ACC;
mov P1, #INKEY_MASK; направления портов согласно маске
WaitForKeyPress1:
mov ACC, P1;
anl ACC, #INKEY_MASK; реализация маски
xrl ACC, #INKEY_MASK; "перевернуть" значения в маске
jz WaitForKeyPress1; не нажато ничего?
acall Wait; пауза. от дребезга
mov ACC, P1;
anl ACC, #INKEY_MASK; аналогичные действия
xrl ACC, #INKEY_MASK;
jz WaitForKeyPress1; а сейчас нажато?
pop ACC;
ret; теперь точно что-то нажато
; подпрограмма ожидания отпускания клавиши
; аналогична предыдущей за исключением
; типа перехода
;
; объединение усложняет код
WaitForKeyRelease:
push ACC;
mov P1, #INKEY_MASK;
WaitForKeyRelease1:
mov ACC, P1;
anl ACC, #INKEY_MASK;
xrl ACC, #INKEY_MASK;
jnz WaitForKeyRelease1;
acall Wait;
mov ACC, P1;
anl ACC, #INKEY_MASK;
xrl ACC, #INKEY_MASK;
jnz WaitForKeyRelease1;
pop ACC;
ret; все кнопы отпущены
; подпрограмма определения кода нажатой клавиши "бегущий ноль"
; возвращает (1..12) - код, или 0 - если не нажато ничего
; в аккумулятор
;
RunningZero:
push 02h; итерационная переменная
push 03h; буфер кода
push 04h; бегущий ноль
mov r2, #0Ch;
!clr 03h; буфер пуст пока
mov r4, #0EFh; 0b1110.1111 - (optional)
RunningZeroLoop:
mov ACC, r4;
rr A; в какую сторону бежать (optional)
mov r4, ACC;
mov P1, r4; пуск "ноля" в клавиатуру
nop;
jb P1.6, NextOne1; поочередная проверка по столбцам
mov 03h, 02h; сохранение кода
NextOne1:
dec r2; итерационная переменная - 1
jb P1.5, NextOne2; далее аналогичные действия
mov 03h, 02h;
NextOne2:
dec r2;
jb P1.4, NextOne3;
mov 03h, 02h;
NextOne3:
djnz r2, RunningZeroLoop; хватит?
mov ACC, r3; да, сохр. в аккумулятор
pop 04h;
pop 03h;
pop 02h;
ret;
; подпрограмма проверки АСС[в 1..9, 11] ?
IsDigit:
jz IsDigitNO; NULL - железно неправильный код
cjne A, #0Bh, IsDigitX;
sjmp IsDigitOK; нолик
IsDigitX:; не нолик
cjne A, #9, IsDigitX1;
sjmp IsDigitOK; девять
IsDigitX1:
jc IsDigitOK; девять > кода - это хорошо
IsDigitNO:
mov ACC, #00h; вернуть - нет
sjmp IsDigitRet;
IsDigitOK:
mov ACC, #0FFh; вернуть - да
sjmp IsDigitRet;
IsDigitRet:
ret;
; подпрограмма печати десятичной цифры на дисплейчике
; в @ACC число для преобразования и печати
; ++ нормализует код нуля!
echo:
cjne A, #0Bh, echo1; код нуля
clr C;
subb A, #0Bh; да, "нормализовать"
echo1:
push ACC;
add A, #30h; подготовка в соотв. с ASCII
acall DataWR;
pop ACC; вернуть преобразованный код
ret;
; подпрограмма ввода числа: @ACC - кол-во цифр считать
; результат вернет в @ACC
;
; wait for keypress\ scan keyboard \ print it\ wait for lift
; конечные автоматы внутри
ScanF:
push 02h; состояние автомата
push 03h; временный результат
push 04h; количество ост. цифр для ввода
mov 02h, #00h;
mov 03h, #00h;
mov r4, ACC; теперь аккумулятор свободен
; для общего назначения
jnz ScanFRoute;
mov r2, #02h; ничего вв не надо, лишь * нажать
ScanFRoute:
mov ACC, 02h;
jz ScanFStateS; #00h
dec ACC;
jz ScanFStateA; #01h
dec ACC;
jz ScanFStateB; #02h
jmp ScanFStateF; above #02h;
; --- только цифру можно нажать ---
ScanFStateS:
acall WaitForKeyPress; void
acall RunningZero; ->ACC
push ACC;
acall IsDigit; <-ACC
jz ScanFStateS2; не цифра
sjmp ScanFStateS1;
ScanFStateS1:
pop ACC; цифра
acall echo; отобразить
mov r3, ACC; сохр. результат
mov 02h, #01h; следующее состояние
dec r4; осталось на одну меньше цифр
sjmp ScanFStateS3;
ScanFStateS2:
pop ACC; неправильный ввод
sjmp ScanFStateS3; проигнорировать
ScanFStateS3:
acall WaitForKeyRelease;
ajmp ScanFRoute;
; --- надо цифру или подтверждение ввода (*) ---
ScanFStateA:
mov ACC, r4;
jnz ScanFStateA1; а цифры то еще нужны?
mov 02h, #02h; нет, хватит
sjmp ScanFStateA4;
ScanFStateA1:
acall WaitForKeyPress; void
acall RunningZero; ->ACC
push ACC;
acall IsDigit; <-ACC
jz ScanFStateA3; неправильный для состояния код
sjmp ScanFStateA2;
ajmp ScanFRoute;
ScanFStateA2:; цифра нажата
pop ACC; вот ее код
acall echo;
; "зарядка" новой цифры в результат
push ACC; пусть тут полежит код нажатой клавиши
mov ACC, r3; временный результат
mov B, #0Ah;
mul AB; умножим на 10d
mov r3, ACC; сохраним обратно
pop ACC;
add A, r3; и добавим 1 "свежую" цифру
mov r3, A; теперь результат переформировани
dec r4; на 1 цифру осталось ввести меньше
sjmp ScanFStateA4;
ScanFStateA3:; * или # нажато
pop ACC;
clr C;
subb A, #0Ah;
jnz ScanFStateA4; не *, надо переввести
mov r2, #03h; ура, подтверждение ввода
ScanFStateA4:; завершение ввода
acall WaitForKeyRelease;
ajmp ScanFRoute;
; --- ожидание только * ---
ScanFStateB:
acall WaitForKeyPress; void
acall RunningZero; ->ACC
clr C;
subb A, #0Ah; проверить, * ли?
jnz ScanFStateB1; не, повторить
mov r2, #03h; двигаем к выходу
ScanFStateB1:
acall WaitForKeyRelease;
ajmp ScanFRoute;
; --- вернуть значение числа ---
ScanFStateF:
mov ACC, r3;
pop 04h;
pop 03h;
pop 02h;
ret;
Помогите пожалуйста перевести код с Ассемблера на С. Программа работы с клавиатурой, написана для 8051.
Заранее огромное спасибо)
---------------------------------------------------
; Подпрограммы для работы с клавиатурой
; ---------------------------------------------------
INKEY_MASK EQU 70h; маска, в которой входы = 1
; подпрограмма ожидания нажатия какой-нибудь кнопки
WaitForKeyPress:
push ACC;
mov P1, #INKEY_MASK; направления портов согласно маске
WaitForKeyPress1:
mov ACC, P1;
anl ACC, #INKEY_MASK; реализация маски
xrl ACC, #INKEY_MASK; "перевернуть" значения в маске
jz WaitForKeyPress1; не нажато ничего?
acall Wait; пауза. от дребезга
mov ACC, P1;
anl ACC, #INKEY_MASK; аналогичные действия
xrl ACC, #INKEY_MASK;
jz WaitForKeyPress1; а сейчас нажато?
pop ACC;
ret; теперь точно что-то нажато
; подпрограмма ожидания отпускания клавиши
; аналогична предыдущей за исключением
; типа перехода
;
; объединение усложняет код
WaitForKeyRelease:
push ACC;
mov P1, #INKEY_MASK;
WaitForKeyRelease1:
mov ACC, P1;
anl ACC, #INKEY_MASK;
xrl ACC, #INKEY_MASK;
jnz WaitForKeyRelease1;
acall Wait;
mov ACC, P1;
anl ACC, #INKEY_MASK;
xrl ACC, #INKEY_MASK;
jnz WaitForKeyRelease1;
pop ACC;
ret; все кнопы отпущены
; подпрограмма определения кода нажатой клавиши "бегущий ноль"
; возвращает (1..12) - код, или 0 - если не нажато ничего
; в аккумулятор
;
RunningZero:
push 02h; итерационная переменная
push 03h; буфер кода
push 04h; бегущий ноль
mov r2, #0Ch;
!clr 03h; буфер пуст пока
mov r4, #0EFh; 0b1110.1111 - (optional)
RunningZeroLoop:
mov ACC, r4;
rr A; в какую сторону бежать (optional)
mov r4, ACC;
mov P1, r4; пуск "ноля" в клавиатуру
nop;
jb P1.6, NextOne1; поочередная проверка по столбцам
mov 03h, 02h; сохранение кода
NextOne1:
dec r2; итерационная переменная - 1
jb P1.5, NextOne2; далее аналогичные действия
mov 03h, 02h;
NextOne2:
dec r2;
jb P1.4, NextOne3;
mov 03h, 02h;
NextOne3:
djnz r2, RunningZeroLoop; хватит?
mov ACC, r3; да, сохр. в аккумулятор
pop 04h;
pop 03h;
pop 02h;
ret;
; подпрограмма проверки АСС[в 1..9, 11] ?
IsDigit:
jz IsDigitNO; NULL - железно неправильный код
cjne A, #0Bh, IsDigitX;
sjmp IsDigitOK; нолик
IsDigitX:; не нолик
cjne A, #9, IsDigitX1;
sjmp IsDigitOK; девять
IsDigitX1:
jc IsDigitOK; девять > кода - это хорошо
IsDigitNO:
mov ACC, #00h; вернуть - нет
sjmp IsDigitRet;
IsDigitOK:
mov ACC, #0FFh; вернуть - да
sjmp IsDigitRet;
IsDigitRet:
ret;
; подпрограмма печати десятичной цифры на дисплейчике
; в @ACC число для преобразования и печати
; ++ нормализует код нуля!
echo:
cjne A, #0Bh, echo1; код нуля
clr C;
subb A, #0Bh; да, "нормализовать"
echo1:
push ACC;
add A, #30h; подготовка в соотв. с ASCII
acall DataWR;
pop ACC; вернуть преобразованный код
ret;
; подпрограмма ввода числа: @ACC - кол-во цифр считать
; результат вернет в @ACC
;
; wait for keypress\ scan keyboard \ print it\ wait for lift
; конечные автоматы внутри
ScanF:
push 02h; состояние автомата
push 03h; временный результат
push 04h; количество ост. цифр для ввода
mov 02h, #00h;
mov 03h, #00h;
mov r4, ACC; теперь аккумулятор свободен
; для общего назначения
jnz ScanFRoute;
mov r2, #02h; ничего вв не надо, лишь * нажать
ScanFRoute:
mov ACC, 02h;
jz ScanFStateS; #00h
dec ACC;
jz ScanFStateA; #01h
dec ACC;
jz ScanFStateB; #02h
jmp ScanFStateF; above #02h;
; --- только цифру можно нажать ---
ScanFStateS:
acall WaitForKeyPress; void
acall RunningZero; ->ACC
push ACC;
acall IsDigit; <-ACC
jz ScanFStateS2; не цифра
sjmp ScanFStateS1;
ScanFStateS1:
pop ACC; цифра
acall echo; отобразить
mov r3, ACC; сохр. результат
mov 02h, #01h; следующее состояние
dec r4; осталось на одну меньше цифр
sjmp ScanFStateS3;
ScanFStateS2:
pop ACC; неправильный ввод
sjmp ScanFStateS3; проигнорировать
ScanFStateS3:
acall WaitForKeyRelease;
ajmp ScanFRoute;
; --- надо цифру или подтверждение ввода (*) ---
ScanFStateA:
mov ACC, r4;
jnz ScanFStateA1; а цифры то еще нужны?
mov 02h, #02h; нет, хватит
sjmp ScanFStateA4;
ScanFStateA1:
acall WaitForKeyPress; void
acall RunningZero; ->ACC
push ACC;
acall IsDigit; <-ACC
jz ScanFStateA3; неправильный для состояния код
sjmp ScanFStateA2;
ajmp ScanFRoute;
ScanFStateA2:; цифра нажата
pop ACC; вот ее код
acall echo;
; "зарядка" новой цифры в результат
push ACC; пусть тут полежит код нажатой клавиши
mov ACC, r3; временный результат
mov B, #0Ah;
mul AB; умножим на 10d
mov r3, ACC; сохраним обратно
pop ACC;
add A, r3; и добавим 1 "свежую" цифру
mov r3, A; теперь результат переформировани
dec r4; на 1 цифру осталось ввести меньше
sjmp ScanFStateA4;
ScanFStateA3:; * или # нажато
pop ACC;
clr C;
subb A, #0Ah;
jnz ScanFStateA4; не *, надо переввести
mov r2, #03h; ура, подтверждение ввода
ScanFStateA4:; завершение ввода
acall WaitForKeyRelease;
ajmp ScanFRoute;
; --- ожидание только * ---
ScanFStateB:
acall WaitForKeyPress; void
acall RunningZero; ->ACC
clr C;
subb A, #0Ah; проверить, * ли?
jnz ScanFStateB1; не, повторить
mov r2, #03h; двигаем к выходу
ScanFStateB1:
acall WaitForKeyRelease;
ajmp ScanFRoute;
; --- вернуть значение числа ---
ScanFStateF:
mov ACC, r3;
pop 04h;
pop 03h;
pop 02h;
ret;
- Реклама

