Перейти к содержанию

Программа asm gередача по UART attiny25

Доброго времени суток.
Нужно передать 1 байт на скорости 19200 бод (8 бит 1 стоп) от мк attiny25 на устройство.
МК программируется программатором громова через uniprof.при подключении питания на мк устройство принимает 1 байт 0FFh вместо 05fh.
МК работает от внутренного тактвого генератора на заводских установках, частоте- 1мгц.
сперва сделал код на таймере.Ничего не получилось, решил считать такты.Исходил из того, что, при частоте 1мгц длительность 1 такта занимает 0,000001 секунды.длительность 1 бита(бода) при скорости 19200 будет 0,000052083 секунды, тоесть задержка между перепадами уровней должна быть 52 такта.Вроде написал код, вроде правильно.Но не работает, подскажите, что может быть не так.


CODE
rjmp RESET ; Reset Handler

RESET:
cli
ldi r17, 0xd0
out 0x3D, r17 ;инициализация стэка

ldi R16, 0b00000011 ;порты как выход
out 0x17, r16
LDI R30, low(fing_cmp*2) ;
lpm r18, Z ;загрузим байт

trx_idle: ;2 такта
ldi R16, 0b00000001 ;логический 1 (idle)
out 0x18, r16

;Задержка 52-2 = 50
ldi r20, 16
delay1:
dec r20
brne delay1
nop
nop

trx_start: ;2 такта
ldi R16, 0b00000000 ;логический 0 (start bit)
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay2:
dec r20
brne delay2
nop
nop
trx_bit0: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay3:
dec r20
brne delay3
nop
nop
trx_bit1: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay4:
dec r20
brne delay4
nop
nop
trx_bit2: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay5:
dec r20
brne delay5
nop
nop
trx_bit3: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay6:
dec r20
brne delay6
nop
nop
trx_bit4: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16


;Задержка 52-5 = 47
ldi r20, 15
delay7:
dec r20
brne delay7
nop
nop
trx_bit5: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay8:
dec r20
brne delay8
nop
nop
trx_bit6: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16


;Задержка 52-5 = 47
ldi r20, 15
delay9:
dec r20
brne delay9
nop
nop
trx_bit7: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16


;Задержка 52-2 = 50
ldi r20, 16
delay13:
dec r20
brne delay13
nop
nop
trx_idle2: ;2 такта
ldi R16, 0b00000001 ;логический 1 (idle)
out 0x18, r16


stop:
nop
nop
rjmp stop

fing_cmp: .db 0xf5
Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(zombi @ Apr 14 2018, 08:35) <{POST_SNAPBACK}>
R31 ненужно грузить?



нет, r31 cодержит 0, когда под отладчиком в avr studio прогоняешь то в r18 грузится нужное число -05fh.B биты в портах, когда сдвигаешь r18 щелкают правильно.

Цитата(zombi @ Apr 14 2018, 08:35) <{POST_SNAPBACK}>
R31 ненужно грузить?


загрузил регистр r18 напрямую значением.вроде заработало, но иногда приходит df.

Спасибо)получается когда мк включается состояние регистров не определено ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(addict @ Apr 14 2018, 12:09) <{POST_SNAPBACK}>
Спасибо)получается когда мк включается состояние регистров не определено ?

конечно не определено biggrin.gif
И изучите макросы что ли, если циклы лень использовать.
глаза сломать можно глядя на вашу писанину.

Цитата(addict @ Apr 14 2018, 12:09) <{POST_SNAPBACK}>
в r18 грузится нужное число -05fh

Просто интересно, компилятор выдаёт какие либо варнинги?
Если да, то читаете ли Вы их?

Задавались ли Вы вопросом какую точность имеет Internal RC Oscillator? и может ли это влиять на качество передачи?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(zombi @ Apr 14 2018, 17:56) <{POST_SNAPBACK}>
Просто интересно, компилятор выдаёт какие либо варнинги?
Если да, то читаете ли Вы их?

Задавались ли Вы вопросом какую точность имеет Internal RC Oscillator? и может ли это влиять на качество передачи?


нет, варнингов нет. Насчет точности..в книге прочитал что встроенный rc генератор может давать существенные погрешности, и вроде нужно подстраивать частоту.Вообщем переписал малость код, также с подсчетом тактов, на этой частоте на этом мк на реальном железе пока ошибок нет, все работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(addict @ Apr 14 2018, 20:25) <{POST_SNAPBACK}>
нет, варнингов нет.

Странно. И на это не ругается?
Цитата
fing_cmp: .db 0xf5

второй байт слова не определён.
и никакого беспокойства у компилятора это не вызывает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(zombi @ Apr 14 2018, 19:06) <{POST_SNAPBACK}>
Странно. И на это не ругается?

второй байт слова не определён.
и никакого беспокойства у компилятора это не вызывает?


нет, никаких ошибок, Assembly complete, 0 errors. 0 warnings
.avr studio 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(addict @ Apr 14 2018, 23:05) <{POST_SNAPBACK}>
нет, никаких ошибок, Assembly complete, 0 errors. 0 warnings
.avr studio 4

А какой последний байт в файле прошивки?
Скорее всего конечно 0хFF, но просто интересно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(zombi @ Apr 15 2018, 06:51) <{POST_SNAPBACK}>
А какой последний байт в файле прошивки?
Скорее всего конечно 0хFF, но просто интересно.


Код
020000020000FC
:1000000002C09DC07FC0F89410ED1DBF03E007BB88
:10001000F1E0EEE35527259101E008BB40E14A9568
:10002000F1F70000000000E008BB4FE04A95F1F74F
:1000300000000000889400272795001F08BB4FE0B0
:100040004A95F1F700000000889400272795001FCB
:1000500008BB4FE04A95F1F70000000088940027A4
:100060002795001F08BB4FE04A95F1F700000000FC
:10007000889400272795001F08BB4FE04A95F1F7A9
:1000800000000000889400272795001F08BB4FE060
:100090004A95F1F700000000889400272795001F7B
:1000A00008BB4FE04A95F1F7000000008894002754
:1000B0002795001F08BB4FE04A95F1F700000000AC
:1000C000889400272795001F08BB40E14A95F1F767
:1000D0000000000001E008BB5395583009F09BCFA9
:1000E00003E007BB01E008BB00E00ABF00E20BBF72
:1000F00004E005BBBB27CC27F1E0E6E4259178942A
:100100000000FECFB03071F0B93071F000272795B4
:10011000001F16B316951695011771F4B39500E0FC
:100120000ABF1895B3951895BB27C395C83011F031
:100130002591189502E008BBF8940000FDCFF50C5E
:0E014000000000000CF5F50C000101000CF5AC
:00000001FF
Прошивка уже немного другая.Но все также- константы в коде на конце.
не знаю почему на конце AC00000001FF, сигнатура чтоли какая или выравнивание, ну 1-2 байта выровнять, зачем то хвост такой вставляет.Или там страницы, блоки, банки, что там еще.Да и вообще дурацкая какая то студия -когда входишь в обработчик и у тебя флаг прерывания сбрасывается, как и должно.следующий раз он не сбрасывается.Или после команды обращения к памяти вдруг флаги прерываний устанавливаются.Порты PINB не меняют своего статуса после установки в DDRB бита 1, или не сразу.
У меня теперь другая засада biggrin.gif теперь прочитать не могу 8 байт.Запарился уже.Что может быть не так.8 байт уходит в устройство, прикладываю к нему палец, должен прийти ответ и мк зажечь светодиод.

CODE
rjmp RESET ; Reset Handler
rjmp EXT_INT0 ; IRQ0 Handler
rjmp PCINT0 ; PCINT0 Handler
;rjmp TIM1_COMPA ; Timer1 CompareA Handler
;rjmp TIM1_OVF ; Timer1 Overflow Handler
;rjmp TIM0_OVF ; Timer0 Overflow Handler
;rjmp EE_RDY ; EEPROM Ready Handler
;rjmp ANA_COMP ; Analog Comparator Handler
;rjmp ADC ; ADC Conversion Handler
;rjmp TIM1_COMPB ; Timer1 CompareB Handler
;rjmp TIM0_COMPA ;
;rjmp TIM0_COMPB ;
;rjmp WDT ;
;rjmp USI_START ;
;rjmp USI_OVF ;

;f50c000000000cf5 ;запрос на скан
;F5 0C 01 01 01 00 0D F5 ;средний палец
;F5 0C 00 01 01 00 0C F5 ;указательный палец





RESET:

cli
ldi r17, 0xd0
out 0x3D, r17 ;инициализация стэка

ldi R16, 0b00000011 ;порты как выход
out 0x17, r16

LDI R31, high(fing_cmp*2) ;настройка строки
LDI R30, low(fing_cmp*2) ;настройка строки

clr r21 ;счетчик байтов

trx_symbol:
lpm r18, Z+ ;загрузим байт

trx_idle: ;2 такта
ldi R16, 0b00000001 ;логический 1 (idle)
out 0x18, r16

;Задержка 52-2 = 50
ldi r20, 16
delay1:
dec r20
brne delay1
nop
nop

trx_start: ;2 такта
ldi R16, 0b00000000 ;логический 0 (start bit)
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay2:
dec r20
brne delay2
nop
nop
trx_bit0: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay3:
dec r20
brne delay3
nop
nop
trx_bit1: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay4:
dec r20
brne delay4
nop
nop
trx_bit2: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay5:
dec r20
brne delay5
nop
nop
trx_bit3: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay6:
dec r20
brne delay6
nop
nop
trx_bit4: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16


;Задержка 52-5 = 47
ldi r20, 15
delay7:
dec r20
brne delay7
nop
nop
trx_bit5: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16

;Задержка 52-5 = 47
ldi r20, 15
delay8:
dec r20
brne delay8
nop
nop
trx_bit6: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16


;Задержка 52-5 = 47
ldi r20, 15
delay9:
dec r20
brne delay9
nop
nop
trx_bit7: ;5 тактов
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16


;Задержка 52-2 = 50
ldi r20, 16
delay13:
dec r20
brne delay13
nop
nop
trx_idle2: ;2 такта
ldi R16, 0b00000001 ;логический 1 (idle)
out 0x18, r16

inc r21 ;обработали очередной байт
cpi r21, 8
breq receive
rjmp trx_symbol


receive:
ldi R16, 0b00000011 ;порт 2 как вход, 0 и 1 как выходы
out 0x17, r16
ldi R16, 0b00000001 ;вход 2 сделаем HI-z а нулевой оставим установленным - пассивным
out 0x18, r16
ldi R16, 0b00000000 ;очистим все флаги прерываний
out 0x3a, r16
ldi R16, 0b00100000 ;разрешим прерывание по изменению на пине
out 0x3b, r16
ldi R16, 0b00000100 ;разрешим прерывание только от 2-ого пина (0 1 2)
out 0x15, r16

clr r27 ;счетчик бодов
clr r28 ;счетчик байтов
LDI R31, high(middle_fing*2) ;настройка строки
LDI R30, low(middle_fing*2) ;настройка строки
lpm r18, Z+ ;загрузим байт
sei

stop:
nop
rjmp stop

PCINT0:
cpi r27, 0
breq start_bit
cpi r27, 9
breq stop_bit
clr r16
ror r18 ;младший байт уходит в C
adc r16, r16
in r17, 0x16 ;прочитаем порт PINB
lsr r17
lsr r17
cp r16, r17
brne error
inc r27
ldi R16, 0b00000000 ;очистим все флаги прерываний
out 0x3a, r16
reti

start_bit:
inc r27
reti

stop_bit:
clr r27 ;все боды прошли
inc r28 ;обработали очередной байт
cpi r28, 8
breq succes
lpm r18, Z+ ;загрузим байт
reti

succes:
ldi r16, 0b00000010
out 0x18, r16

error:
cli
nop
rjmp error

EXT_INT0:


fing_cmp: .db 0xf5, 0x0c,0x00,0x00, 0x00, 0x00, 0x0c, 0xf5
middle_fing: .db 0xf5, 0x0c,0x00,0x01, 0x01, 0x00, 0x0c, 0xf5
Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
сперва решите Вашу задачу с использованием кварцевого тактирования от встроенного (если есть возможность) или внешнего генератора.
Когда все будет работать как надо и без сбоев - переводите на RC и отлаживаете (считаете такты, подстраиваете генератор итп).
ps Снизьте скорость UART пока отлаживаете софт. Или надо будет такты пересчитывать ? sm.gif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
bb-offtopic.gif
Цитата
Прошивка уже немного другая.Но все также- константы в коде на конце.

Так теперь константы кратны 2 и выравнивать ничего не нужно biggrin.gif
Цитата
У меня теперь другая засада biggrin.gif теперь прочитать не могу 8 байт.Запарился уже.Что может быть не так.

не, нет времени.
Могу только посоветовать увеличить паузу между байтами раз по одному все норм.
И internal RC проверить.
Если есть осциллограф то просто зациклить ногодрыг и смотреть какая частота на ноге получилась.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(addict @ Apr 14 2018, 13:09) <{POST_SNAPBACK}>
нет, r31 cодержит 0,

шутить изволите?
не сравнивайте компилятор с реальным авр!!! при включении там может быть мусор!

вы используете софтовую реализацию компорта и передаёте байт описывая каждый бит..
это занимает очень много памяти..
вот попробуйте это...
подогнать под свою скорость и частоту кварца сможете?
CODE
;**********************************************************************
*********
*******************

; передача одного байта в формате РС-232 16МГЦ 115200
TX_232:

push r16
push r17
push r18
; заносим в...
cbi PORTB,1 ; формирум СТАРТ бит 1=>0
ldi r17,0x08 ; заносим в CNT_BIT - 9. количество сдвигов
;---------------------
ldi r18,43 ; корекция скорости передачи
sta_bit:
dec r18
brne sta_bit
;---------------------
Loop_TX:
sbrs r16,0
cbi PORTB,1
sbrc r16,0
sbi PORTB,1

;------------------
ldi r18,43 ; корекция скорости передачи
tx_bit:
dec r18
brne tx_bit
nop
nop
;------------------

lsr r16 ; здвигаем
dec r17
brne Loop_TX


sbi PORTB,1 ; формирум СТОП бит
;------------------
ldi r18,80 ; 15 корекция скорости передачи
st_bit:
dec r18
brne st_bit;
;------------------

pop r18
pop r17
pop r16

ret



;*******************************************************************************
*******************



LDI R30, low(fing_cmp*2)
LDI R31, high(fing_cmp*2)
lpm r18, Z ;загрузим байт

и R31 обязателен!!!

вот и вся прога... отправки 8ми байт в ком из таблицы
CODE
;**********************************************************************
****************************
;
_reset:

clr r1
out SREG,r1

ldi r16, LOW(RAMEND) ;setup stack pointer
out SPL, r16
; ldi r16, HIGH(RAMEND)
; out SPH, r16


ldi ZL,low(Table_1*2) ; считываем адрес таблицы
ldi ZH,high(Table_1*2)

ldi r19,8

lp:
lpm r24,Z+

call TX_232

dec r19
brne lp


sss:
jmp sss


Table_1:
.db 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08

;*******************************************************************************
*******************
Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
[quote name='KGB' date='Apr 17 2018, 23:33' post='1557047']
шутить изволите?
не сравнивайте компилятор с реальным авр!!! при включении там может быть мусор!

вы используете софтовую реализацию компорта и передаёте байт описывая каждый бит..
это занимает очень много памяти..
вот попробуйте это...
подогнать под свою скорость и частоту кварца сможете?

и R31 обязателен!!!



Уже понял) спасибо.Мне память не критична в данном случае.На отправку у меня давно получилось, а вот прием.С приемом тоже разобрался, там уже циклы.Жаль по прерываниям от переполнения счетчика таймера не получится реализовать на данном мк.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(addict @ Apr 20 2018, 13:02) <{POST_SNAPBACK}>
Жаль по прерываниям от переполнения счетчика таймера не получится реализовать на данном мк.

не понял что не можете реализовать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(KGB @ Apr 20 2018, 20:46) <{POST_SNAPBACK}>
не понял что не можете реализовать


вот к примеру почему не работает этот код на отправку, мк тотже, частота теже

CODE

rjmp RESET ; Reset Handler
rjmp EXT_INT0 ; IRQ0 Handler
rjmp PCINT0 ; PCINT0 Handler
rjmp TIM1_COMPA ; Timer1 CompareA Handler
rjmp TIM1_OVF ; Timer1 Overflow Handler

RESET:
cli
ldi r17, 0xd0
out 0x3D, r17 ;инициализация стэка


ldi R16, 0b00000011 ;порты как выход
out 0x17, r16

LDI R30, low(fing_cmp*2)
clr r31

lpm r18, Z+
clr r28 ;счетчик бодов
clr r29 ;счетчик байтов

ldi R16, 0b00000100 ;разрешим прерывание по переполнению таймера 1
out 0x39, r16
ldi R16, 0xf3 ;дозаполним счетчик
out 0x2f, r16
ldi R16, 0b00000010 ;сброс предделителя
out 0x2c, r16
ldi R16, 0b00000011 ;установка предделителя- CK\4 итоговая частота
out 0x30, r16 ;после установки частоты счетчик тутже начинает считать
sei

wt:
nop
rjmp wt ;заглушка до прерывания



TIM1_OVF:
ldi R16, 0xf3 ;дозаполним счетчик
out 0x2f, r16
ldi R16, 0b00000010 ;сброс предделителя
out 0x2c, r16

transmit:
cpi r28, 1
brlo trx_idle ;если меньше 1, тоесть 0 то выставляем лог.единицу
breq trx_start ;лог единица уже стоит и значит пишем стартовый бит
cpi r28, 10
brlo trx_bit
clr r28 ;все, все боды прошли
inc r29 ;обработали очередной байт
cpi r29, 8 ;сколько байт обработали
breq stop ;если 8 то все.
lpm r18, Z+
reti

trx_idle:
ldi R16, 0b00000001 ;логический 1 (idle онже потом stop бит)
out 0x18, r16
inc r28
reti


trx_start:
ldi R16, 0b00000000 ;логический 0 (start bit)
out 0x18, r16
inc r28
reti

trx_bit:
clc
clr r16
ror r18 ;младший бит уходит в C
adc r16, r16
out 0x18, r16
inc r28
reti

stop:
nop
nop
rjmp stop

EXT_INT0: ; IRQ0 Handler
PCINT0: ; PCINT0 Handler
TIM1_COMPA: ; Timer1 CompareA Handler

fing_cmp: .db 0xf5, 0x0c,0x00,0x00, 0x00, 0x00, 0x0c, 0xf5

Изменено пользователем addict

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация