USI как UART реаализация на асемблере

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
dinets
Потрогал лапой паяльник
Сообщения: 360
Зарегистрирован: Чт авг 12, 2010 10:16:32

USI как UART реаализация на асемблере

Сообщение dinets »

attiny24 1Mhz
тужусь родить это на ассемблере за основу взял сишный код

Код: Выделить всё

char reverse_bit_order (char byte) 
{ 
    char temp = 0; 
    uint8_t count = 8; 
    
    do 
    { 
  
    } 
    while (--count > 0); 
    
    return byte; 
} 
 void init_usi_uart (void) 
{ 
    PORTA |= (1 << 5); 
    DDRA |= (1 << 5); 
    
    // Init Timer0 
    // Must Be Done Only Once Because Switching Off Timer0 Has No 
    // Effect On The Content Of The Timer0 Registers 
    // Select 8-Bit CTC Mode (Clear Timer On Compare Match) 
    TCCR0A = (1 << WGM00); 
    // Set Timer Top Value To Generate The RS232 Baudrate 
    // A Prescaler Value Of 8 Will Be Used 
    OCR0A = 1000000 / 8 * USI_UART_BAUDRATE; 
    // Stop Timer0 
    TCCR0B = 0; 
    
    // Init USI 
    // Clear All Flags In USI Status Register 
    // Clear USI Counter 
    USISR = 0xE0; 
    // Ensure That USI Output Is High (Default State Of UART Line) 
    USIDR = 0xFF; 
    // Select Three Wire Mode (SPI), 
    // Select Timer0 Compare Match As Clock Source 
    USICR = (1 << USIWM0) | (1 << USICS0) | (1 << USICLK); 
} 



void usi_uart_putch (char send_char) 
{ 
    uint8_t uart_half_frame; 
    uint8_t ch = (uint8_t) send_char; 
    
    // The USI Output Order Is MSB First, But RS232 Standard Is LSB First 
    // Thus The Bit Order Of The Data Byte ch Must Be Reversed 
    ch = reverse_bit_order (ch); 
    
    // Calculate And Send 1st Half Of UART Frame 
    // 1st Half:  STOP START D0   D1   D2   D3   D4   D5 
    // Bit No.:    7    6    5    4    3    2    1    0 
    uart_half_frame = 0x80 | (uint8_t) (ch >> 2); 
    
    // Loop Until USI Is Ready 
    while ((USISR & 0x0F) > 0); 
    
    USISR = 6; 
    USIDR = uart_half_frame; 
    
    // Start Timer0 Which Is The Clock Source Of The USI 
    TCNT0 = 0; 
    TCCR0B = (1 << CS01); 
    
    // Calculate 2nd Half Of UART Frame 
    // 2nd Half:   D3   D4   D5   D6   D7  STOP STOP STOP 
    // Bit No.:    7    6    5    4    3    2    1    0 
    uart_half_frame = 0x07 | (uint8_t) (ch << 3); 
    
    // Wait Until First Half Frame (Startbit, D0...D2 Is Send 
    while ((USISR & 0x0F) < 11); 
    
    // Send 2nd Half Of UART Frame 
    USIDR = uart_half_frame; 
    
    // Loop Until USI Is Ready 
    while ((USISR & 0x0F) > 0); 
    
    // Stop Timer0 
    TCCR0B = 0; 
} 
который тож правда не шипко работает
инвертирование порядка бит в посылки убрано

пишу на асм у меня загвоздка
таймер при достижении отметки А не тактирует УСИ а должен был
что я не так накосячил с флагами
код
#include <tn24def.inc>
;*********************
;* Interrupt Vectors *
;*********************
.def temp = r16
.def temp2 = r17
#define USI_UART_BAUDRATE 9600
.CSEG
rjmp RESET ; TO START sting 25
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti// reti//timer 0 over
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti// rjmp TIM0//tim0
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
USI_INIT:
//ldi temp, (1<<5)
//out DDRA, temp
//out PORTA, temp
//
ldi temp,(1<<WGM00);
out TCCR0A,temp
//
ldi temp,152 // из апноута
out OCR0A,temp
//
ldi temp,0xE0
out USISR,temp
//
ldi temp,0xFF
out USIDR,temp
//
ldi temp,(1 << USIWM0) | (1 << USICS0) | (1 << USICLK)
out USICR,temp
ret

SEND:

ldi temp,0b10101010
ldi temp2,6
out USISR,temp2
out USIDR,temp
//
ldi temp,0
out TCNT0,temp

ldi temp,(1<<CS01)
out TCCR0B,temp
////
s2:
in temp2,USISR
ldi temp,0b00001111

and temp2,temp ////
cpi temp2,11
brlo s2
///
ldi temp,0b01010111
out USIDR,temp
////
s3:
in temp2,USISR
ldi temp,0b00001111

and temp2,temp ////
cpi temp2,0
brlo s3
////
ldi temp,0
out TCCR0B,temp
ret




RESET:


rcall USI_INIT
re2: rcall SEND
rjmp re2
таймер счёлкает до отметки 152 и продолжает счолкать дальше
с уси ничего не происходит
хотя он по достижению должен был сбрасыватся?
Реклама
Аватара пользователя
Финский
Открыл глаза
Сообщения: 59
Зарегистрирован: Сб авг 28, 2010 13:29:43
Откуда: Докучаевск, Донецк
Контактная информация:

Re: USI как UART реаализация на асемблере

Сообщение Финский »

Первое, что бросается в глаза - нет прерывания по совпадению таймера OCR0A. А во-вторых - прокомментируйте, пожалуйста код.
[color=#800000]Техноманьяк и IT-шаман. Танцы с бубном на дому.[/color]
Реклама
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение Engineer_Keen »

Финский писал(а):Первое, что бросается в глаза - нет прерывания по совпадению таймера OCR0A.
И при том, что у тини24 всего 17 векторов прерываний, а в коде зачем-то 30+ затычек reti... Хотя это не важно.
Важно что на стек как-всегда забили...
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение ibiza11 »

точняк) стек не инициализирован. :lol:
Ставим плюсы: )
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение Engineer_Keen »

В симуляторе вроде работает, но выдает не то. Надо AVR307 почитать...
Реклама
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: USI как UART реаализация на асемблере

Сообщение ChipKiller »

dinets писал(а):...тужусь родить это на ассемблере за основу взял сишный код который тож правда не шипко работает ..
так зачем добавлять проблем - отредактируйте С-код, а уж потом переписывайте ... ИМХО если алгоритм работы верен, то не важно на чем написано.....
Реклама
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение Engineer_Keen »

Почитал тут AVR307. Принципиальная разница с кодом топикстартера в том что у него проверка готовности передачи происходит путем тупления в циклах проверки USISR, что не есть хорошо, хоть и допустимо. В аппноуте все происходит по прерываниям. Но есть и косяк. В аппноуте USI CLK переключается по переполнению таймера, а в тини24 USI умеет тактироваться только от сравнения с OCR. В общем получается примерно так (проверено в глюкопротеусе):

Код: Выделить всё

	.include <tn24def.inc>
	.def	ZERO=R0
	.equ	TRANSMIT_HALF_BYTE=0	;Tx 1/2 or 2/2 flag
	.equ	TRANSMITTING=1		;set at Tx start, clear after 2/2 byte Tx start
	.equ	TX_BUSY=2		;set at Tx start, clear after 2/2 byte Tx complete
	.macro	OUTI
	LDI	R16,@1
	OUT	@0,R16
	.endm
	.macro	PREPARE_BYTE
	CLR	R17		;reverse bit order
	ROR	R16		;add start/stop bits
	ROL	R17		;and save to Tx buffer
	ROR	R16
	ROL	R17
	BST	R16,0
	BLD	R17,7
	SWAP	R17
	ORI	R17,0x80
	STS	UDATA,R17
	CLR	R17
	ROR	R16
	ROR	R16
	ROL	R17
	ROR	R16
	ROL	R17
	ROR	R16
	ROL	R17
	ROR	R16
	ROL	R17
	SWAP	R17
	BST	R16,0
	BLD	R17,3
	ORI	R17,0x07
	STS	UDATA+1,R17
	.endm

.dseg
UDATA:	.byte	2			;Tx Buffer (1/2 and 2/2)
.cseg
	RJMP RESET			;RESET
	RETI				;EXT_INT0
	RETI				;PCINT0
	RETI				;PCINT1
	RETI				;WDG
	RETI				;T1_CAP
	RETI				;T1=A
	RETI				;T1=B
	RETI				;T1_OVF
	RJMP	T0_A			;T0=A
	RETI				;T0=B
	RETI				;T0_OVF
	RETI				;ANA_COMP
	RETI				;ADC
	RETI				;EE_RDY
	RETI				;USI_STR
	RJMP	USI_OVF			;USI_OVF

RESET:	OUTI	SPL,low(RAMEND)			;stack...
	CLR	ZERO
	OUTI	DDRA,0x20			;ports...
	OUT	PORTA,R16
	OUTI	OCR0A,95			;Fc=1MHz, BAUD_RATE=9600
	OUTI	TIFR0,(1<<OCF0A)		;timer...
	OUTI	TIMSK0,(1<<OCIE0A)
	OUTI	USICR,(1<<USIOIE)|(1<<USIWM0)|(1<<USICS0);USI...
	CBI	GPIOR0,TRANSMITTING
	SEI					;enable INTs
	LDI	R16,0x48			;send "HELLO!"
	RCALL	UART_WRITE
	LDI	R16,0x45
	RCALL	UART_WRITE
	LDI	R16,0x4C
	RCALL	UART_WRITE
	LDI	R16,0x4C
	RCALL	UART_WRITE
	LDI	R16,0x4F
	RCALL	UART_WRITE
	LDI	R16,0x21
	RCALL	UART_WRITE
LOOP:	RJMP	LOOP				;main loop

T0_A:	OUT	TCNT0,ZERO		;reset timer
	RETI
UART_WRITE:
	SBIC	GPIOR0,TX_BUSY		;Check Tx BUSY flag
	RJMP	UART_WRITE		;Waiting for previous Tx complete...
	PREPARE_BYTE			;convert data byte to "start bits-data bits-stop bits" word
	OUT	TCNT0,ZERO		;reset timer
	OUTI	TCCR0B,(1<<CS00)	;start timer
	OUTI	USIDR,0xFF		;prepare USI data & status
	OUT 	USISR,R16
	SBI	GPIOR0,TRANSMITTING	;set Tx transmitting flag
	SBI	GPIOR0,TX_BUSY		;set Tx BUSY flag
	RET
USI_OVF:
	PUSH	R16
	SBIS	GPIOR0,TRANSMITTING
	RJMP	TX_DISABLE
	SBIC	GPIOR0,TRANSMIT_HALF_BYTE
	RJMP	SEND2
SEND1:	SBI	GPIOR0,TRANSMIT_HALF_BYTE	;transmit 1/2
	OUTI	USISR,0xFB			;USI counter set to 11 (16-5, 2 start bits+3 data bits)
	LDS	R16,UDATA
	OUT	USIDR,R16
	RJMP	US_RET
SEND2:	CBI	GPIOR0,TRANSMIT_HALF_BYTE	;transmit 2/2
	OUTI	USISR,0xFA			;USI counter set to 10 (16-6, 5 data bits+stop bit)
	LDS	R16,UDATA+1
	OUT	USIDR,R16
	CBI	GPIOR0,TRANSMITTING
	RJMP	US_RET
TX_DISABLE:
	OUTI	USISR,0xF0			;disable Tx (Timer0)
	CBI	GPIOR0,TX_BUSY
	OUT	TCCR0B,ZERO
	OUT	TCNT0,ZERO
US_RET:	POP	R16
	RETI
Сори за каменты, лень раскладку переключать.
Кстати в аппноуте суммарный код только передатчика (таблица 3) получился 252 байта. Мой весь - 226, а это и передатчик и общая инициализация и передача строки :)
Да, вместо подпрограммы прерывания таймера по сравнению можно бы использовать режим CTC, но он почему-то не эмулируется :kill:
dinets
Потрогал лапой паяльник
Сообщения: 360
Зарегистрирован: Чт авг 12, 2010 10:16:32

Re: USI как UART реаализация на асемблере

Сообщение dinets »

да я уже нашол пару косяков в коде
удалось получить хоть какойто поток бит напоминающий то что надо
(даже в протосе)
что интерестно период таймера в анпноте 152 а расчотом выходит 104

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

второе порядок бит зачем они дублируют уже посланые в буфер биты??
// 1st Half: STOP START D0 D1 D2 D3 D4 D5
// Bit No.: 7 6 5 4 3 2 1 0

// 2nd Half: D3 D4 D5 D6 D7 STOP STOP STOP
// Bit No.: 7 6 5 4 3 2 1 0

D3 D4 D5 по что слать дважды одно и тоже или они не успевают быть высланными??
этого момента непонял
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение Engineer_Keen »

dinets писал(а):что интерестно период таймера в анпноте 152 а расчотом выходит 104
Видимо какое-то несовпадение по частотам тактирования. Я в своем коде вообще на глаз подбирал :)))
dinets писал(а):а можно ли родить асинхронный приём
ну дабы приём начался по прерыванию а не принудительным запуском функции ожидания?
Вроде как можно использовать INT0/INT1/PCINT
dinets писал(а): второе порядок бит зачем они дублируют уже посланые в буфер биты??
Биты не дублируются. В первом байте передаются только 3 первых бита данных, там специально счетчик в USISR подкручивают.
dinets
Потрогал лапой паяльник
Сообщения: 360
Зарегистрирован: Чт авг 12, 2010 10:16:32

Re: USI как UART реаализация на асемблере

Сообщение dinets »

странно у мня в протосе вроде работает СТС
дощёлколо и сбросило
какая формула расчота?

а средствами УСИ можно ли асинхронно ловить начало передачи?


те лишниие биты попадали просто так?
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение Engineer_Keen »

dinets писал(а):странно у мня в протосе вроде работает СТС дощёлколо и сбросило
может протеус старый, у меня 7.6...
dinets писал(а):какая формула расчота?
По логике должно быть Fc/BAUD_RATE, при прескалере 1, но что-то не соответствует...
dinets писал(а):а средствами УСИ можно ли асинхронно ловить начало передачи?
Сомневаюсь. Чем можно ловить? Нога MOSI - у нас Tx, нога MISO в USI источником прерывания не является. Если только включать в режим слейва, грузить счетчик "переполнение-1" и ловить перепад с ноги CLK? Но тогда ничего передавать нельзя, да и нога лишняя тратится. Лучше по прерыванию PCINT (не помню какая там нога MISO).
dinets писал(а):те лишниие биты попадали просто так?
Какие? Которые в первом байте с 3 младших? Они никуда не пропадали, они просто никуда не выводились :))) , а то, что они дублировали 3 бита второго байта - издержки алгоритма перестановки.
dinets
Потрогал лапой паяльник
Сообщения: 360
Зарегистрирован: Чт авг 12, 2010 10:16:32

Re: USI как UART реаализация на асемблере

Сообщение dinets »

Engineer_Keenогромное спасибо!
Успех! приём прост как 2 копейки ловим старт бит PCINTом поймали стартуем таймер заряжаем счотчик УСИ на 8 и ждём усиоверфлоу, разворачиваем принятый байт и всё
(как добью положу код)
осталось только увязать два процеса ибо уси оверфлоу и там и там

Один только вопрос мучает что есть GPIOR0
я так думаю регистр ощего статуса ввода вывода для красоты и удобства програмиста?
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: USI как UART реаализация на асемблере

Сообщение Engineer_Keen »

dinets писал(а):Один только вопрос мучает что есть GPIOR0
я так думаю регистр ощего статуса ввода вывода для красоты и удобства програмиста?
Верно. У некоторых контроллеров есть регистры GPIOR, которые удобно использовать в качестве флагов, по тому как к ним можно применить SBI\CBI и SBIC\SBIS. Так можно освободить регистры R0-R31 или место в ОЗУ.
dinets
Потрогал лапой паяльник
Сообщения: 360
Зарегистрирован: Чт авг 12, 2010 10:16:32

Re: USI как UART реаализация на асемблере

Сообщение dinets »

2 Engineer_Keen

Я победил старого демона!!!!!
терь отправляю и получаю!

гоню температуру с внутреннего сенсора
а в начале подстраиваю скрость ввожу 'U' и как только контролёр её считает так знать и скоррость верная в моём случае 9600кбпс == 106 (задержка таймера) при частоте в 8Мгц (пред делитьель таймера тоже 8)

Проверил в металле!!!!!

Код: Выделить всё




 .include <tn24def.inc>
   .def   ZERO=R0
   .equ   TRANSMIT_HALF_BYTE=0   ;Tx 1/2 or 2/2 flag
   .equ   TRANSMITTING=1      ;set at Tx start, clear after 2/2 byte Tx start
   .equ   TX_BUSY=2      ;set at Tx start, clear after 2/2 byte Tx complete
.equ   RX_BUSY=3      ;set at RX
.equ   RECEIVING=4      ;set at RX
   .macro   OUTI
   LDI   R16,@1
   OUT   @0,R16
   .endm
   .macro   PREPARE_BYTE
   CLR   R17      ;reverse bit order
   ROR   R16      ;add start/stop bits
   ROL   R17      ;and save to Tx buffer
   ROR   R16
   ROL   R17
   BST   R16,0
   BLD   R17,7
   SWAP   R17
   ORI   R17,0x80
   STS   UDATA,R17
   CLR   R17
   ROR   R16
   ROR   R16
   ROL   R17
   ROR   R16
   ROL   R17
   ROR   R16
   ROL   R17
   ROR   R16
   ROL   R17
   SWAP   R17
   BST   R16,0
   BLD   R17,3
   ORI   R17,0x07
   STS   UDATA+1,R17
   .endm

.macro   PREPARE_BYTE_R
clr r17
 ROR   R16      ;add start/stop bits
   ROL   R17      ;and save to Tx buffer

   ROR   R16
   ROL   R17

   
   ROR   R16
   ROL   R17

   
   ROR   R16
   ROL   R17

   
   ROR   R16
   ROL   R17

   
   ROR   R16
   ROL   R17

   
   ROR   R16
   ROL   R17

   
   ROR   R16
   ROL   R17
.endm
.dseg
UDATA:   .byte   2         ;Tx Buffer (1/2 and 2/2)
.cseg
   RJMP RESET         ;RESET
   RETI            ;EXT_INT0
   rjmp PCI            ;PCINT0
   RETI            ;PCINT1
   RETI            ;WDG
   RETI            ;T1_CAP
   RETI            ;T1=A
   RETI            ;T1=B
   RETI            ;T1_OVF
   RJMP   T0_A         ;T0=A
   RETI            ;T0=B
   RETI            ;T0_OVF
   RETI            ;ANA_COMP
   RETI            ;ADC
   RETI            ;EE_RDY
   RETI            ;USI_STR
   RJMP   USI_OVF         ;USI_OVF

RESET:   OUTI   SPL,low(RAMEND)         ;stack...
   CLR   ZERO
   OUTI   DDRA,0x20         ;ports...
   OUT   PORTA,R16
   OUTI   OCR0A,105       ;Fc=8MHz, BAUD_RATE=9600
   OUTI   TIFR0,(1<<OCF0A)      ;timer...
   OUTI   TIMSK0,(1<<OCIE0A)
   OUTI   USICR,(1<<USIOIE)|(1<<USIWM0)|(1<<USICS0);USI...
   CBI   GPIOR0,TRANSMITTING
   CBI   GPIOR0,TX_BUSY
ldi r16,0b11100111
	out ADCSRA,r16                                 
//	ldi r16,0		; Select ADC0 as input, VCC as VREF
ldi r16,0b10100010
	out ADMUX,r16
ldi r16,0
   SEI               ;enable INTs
 /*  LDI   R16,0x48         ;send "HELLO!"
 //  RCALL   UART_WRITE
   LDI   R16,0x45
 //  RCALL   UART_WRITE
   LDI   R16,0x4C
  // RCALL   UART_WRITE
   LDI   R16,0x4C
 //  RCALL   UART_WRITE
   LDI   R16,0x4F
 //  RCALL   UART_WRITE
   LDI   R16,0x21
 //  RCALL   UART_WRITE
 
*/





//
	
  ldi r31,100
loop1:
rcall UART_READ
out OCR0A,r31
inc r31
 l1: SBIC GPIOR0,TX_BUSY
rjmp l1
CPI r17, 0x55
brne loop1
mov r16,r31
RCALL   UART_WRITE

/////////////////////////////
LOOP: rcall UART_READ

loop2: SBIC GPIOR0,TX_BUSY
rjmp loop2
mov r16,r17
RCALL   UART_WRITE


//rjmp LOOP

  //
SBIS ADCSRA, ADIF
rjmp LOOP

in r1,ADCL
in r2,ADCH
SBI ADCSRA, ADIF
SBI ADCSRA, ADSC
   LDI   R16,0x21
   RCALL   UART_WRITE
   mov   R16,r2
   RCALL   UART_WRITE
      mov   R16,r1
   RCALL   UART_WRITE




RJMP   LOOP            ;main loop

T0_A:   OUT   TCNT0,ZERO      ;reset timer
   RETI

   PCI:
   push r16
 OUT   TCNT0,ZERO      ;reset timer
OUTI   USISR,0xF8 ///not read start bit
   OUTI   TCCR0B,(2<<CS00)   ;start timer


//ldi r16,1<<6 //listing PA6 DI
out PCMSK0,ZERO
out GIFR, ZERO
pop r16
   reti

UART_READ:
SBIC GPIOR0,RECEIVING
RJMP UART_READ
SBIC GPIOR0,TX_BUSY
RJMP UART_READ

SBI GPIOR0,RECEIVING //lock
SBI GPIOR0,TX_BUSY //lock
ldi r16,1<<PCIE0 //pcie int on
out GIMSK,r16

ldi r16,1<<6 //listing PA6 DI
out PCMSK0,r16
sei




ret
UART_WRITE:
   SBIC   GPIOR0,TX_BUSY      ;Check Tx BUSY flag
   RJMP   UART_WRITE      ;Waiting for previous Tx complete...
   PREPARE_BYTE         ;convert data byte to "start bits-data bits-stop bits" word
   OUT   TCNT0,ZERO      ;reset timer
   OUTI   TCCR0B,(2<<CS00)   ;start timer
   OUTI   USIDR,0xFF      ;prepare USI data & status
   OUT    USISR,R16
   SBI   GPIOR0,TRANSMITTING   ;set Tx transmitting flag
   SBI   GPIOR0,TX_BUSY      ;set Tx BUSY flag
   RET
USI_OVF:

   PUSH   R16
   SBIC GPIOR0,RECEIVING
RJMP RECV
   SBIS   GPIOR0,TRANSMITTING
   RJMP   TX_DISABLE
   SBIC   GPIOR0,TRANSMIT_HALF_BYTE
   RJMP   SEND2
SEND1:   SBI   GPIOR0,TRANSMIT_HALF_BYTE   ;transmit 1/2
   OUTI   USISR,0xFB         ;USI counter set to 11 (16-5, 2 start bits+3 data bits)
   LDS   R16,UDATA
   OUT   USIDR,R16
   RJMP   US_RET
SEND2:   CBI   GPIOR0,TRANSMIT_HALF_BYTE   ;transmit 2/2
   OUTI   USISR,0xFA         ;USI counter set to 10 (16-6, 5 data bits+stop bit)
   LDS   R16,UDATA+1
   OUT   USIDR,R16
   CBI   GPIOR0,TRANSMITTING
   RJMP   US_RET

   RECV:

in r16,USIDR
PREPARE_BYTE_R
CBI GPIOR0,RECEIVING
//RJMP   US_RET
//OUTI   USIDR,0xFF
// OUTI   USISR,0xF4
//RJMP   US_RET
TX_DISABLE:
  
        ;disable Tx (Timer0)
   CBI   GPIOR0,TX_BUSY
   OUT   TCCR0B,ZERO
   OUT   TCNT0,ZERO
   OUTI   USISR,0xF0
US_RET:   POP   R16
   RETI


ещё раз спасибо!
dinets
Потрогал лапой паяльник
Сообщения: 360
Зарегистрирован: Чт авг 12, 2010 10:16:32

Re: USI как UART реаализация на асемблере

Сообщение dinets »

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

Код: Выделить всё

l1: SBIC GPIOR0,TX_BUSY
rjmp l1
и тут я понимаю мосгом что такие "паралельные" функции безполезны по одиночке и их нужно переписать для работы с масивом, с целым буфером который надо отправить или принять
Сразу вспоминаются алгоритмы "писателя и читателя" или ещё там какие...

так вот я хотел бы уточнить как по научному наз. функция такая как в нашем случае реализованна на прерывании и работает паралельно?

И второе есть ли контролёры у которых УАПП сделан не как микросхема
8250 http://ru.wikipedia.org/wiki/8250_UART а с аппаратным буфером как микросхема 16550 http://ru.wikipedia.org/wiki/16550_UART
Или ПДП (DMA) рулит? (праздное любопытство)
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»