Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Туплю с программным UART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
pitman
Есть следующий проблем, который не борется второй день. smile3046.gif

Решил сделать программный UART, электрическая схема собрана, с компа данные идут, на него посылаются. Беру скорость 9600 8N1, считаю, получаю, что передача единичного состояния занимает 104мкс. Делаю тестовый вариант, где в цикле передается 0xAA. Стартовый бит 104мкс, и дальше 1 104мкс, 0 104 мкс и т.д. После передачи символа выдерживаю паузу и передаю снова. Трабла в том, что судя по логическому анализатору (включеному до MAX232) времянка соблюдается, в комп ничего не приходит. Меняю задержку, времянка не совпадает с расчетной, на комп приходят какие-то левые символы. Подскажите где я не прав??? У меня что-то все идеи кончились. Проц ATtiny26.
Alexandr
А что видно после max232? Если сигналы проходят через него нормально, то тогда советую посмотреть состояние регистров компа - адреса 3F8-3FF (для COM1). Кстати - а чем настраиваете COM - порт? Проверьте настройки. А соединяетесь с платой по нуль-модемному кабелю?
pitman
С компом содиняюсь по нуль-модемному кабелю прямому. Приходящие данные смотрю в программе minicom под Линух. Скорость, и пр. параметры порта настраиваются в ней. Какой-то мусор в нее же приходит....

cranky.gif

Сегодня попробую проверить, что видно после второго MAX232 на стороне компа. Может из-за кондеров не получаются нужные уровни RS-232.
arttab
на атини26 нет аппаратного уарта, а есть и2с. Вы в режиме халт дуплекс (как в апликейшен) делаете реализацию?
Я программно делал связь на 9600. у меня проблема была с калибровкой оссилятора на 4 Мгц. Так как я могу считать калибровочный байт только для 1 Мгц. Вот частоту подбирал. И запрещал другие прерывания на время передачи. Уточните, что Вы делаете.
pitman
Цитата(arttab @ Apr 8 2005, 11:23)
на атини26 нет аппаратного уарта, а есть и2с. Вы в режиме халт дуплекс (как в апликейшен) делаете реализацию?
Я программно делал связь на 9600. у меня проблема была с калибровкой оссилятора на 4 Мгц. Так как я могу считать калибровочный байт только для 1 Мгц. Вот частоту подбирал. И запрещал другие прерывания на время передачи. Уточните, что Вы делаете.
*


Дык ить пишу. Делаю чисто программный UART никак не используя USI. Для проверки работы сделана простая программа, которая в цикле отдает 0xAA дергая ножку с нужными задержками. Какая должна быть длительность символа на 9600??
arttab
1/9600 длительность.
вот моя подпрограмма вывода:


RSBEG:

push temp2 ;в стек temp2
in temp2,SREG ;сохран статуса
push temp2 ;в стек SREG
mov temp2,RSDT


;----привязка опроса кнопки к 10000 Гц
RSPAUSE:

sbrs TM10000,$0 ;перескочить если бит установлен
rjmp RSZ
sbrc KEY,RSTEMP ;перескочить если бит сброшен
rjmp RSPAUSE ;TM=1, RSTEMP=1
sbr KEY,(1<<RSTEMP) ;
rjmp RSSTART ;TM=1, RSTEMP=0
RSZ:
sbrs KEY,RSTEMP ;перескочить если бит установлен
rjmp RSPAUSE ;TM=0, RSTEMP=0
cbr KEY,(1<<RSTEMP) ;
rjmp RSSTART ;TM=0, RSTEMP=1

;переход на передачу происходит только если TM10000,$0 и RSTEMP не равны,
;т.е. по фронту TM10000,$0. для исключения преждевременной передачи, RSTEMP:= TM10000,$0
; и следующий проход после изменения таймера TM10000.

;-------------------------RS-232



RSSTART:

cpi K,$0 ;start bit
brne RS0 ;перейти если не равно
cbi PORTB,PB1 ;иначе выдать 0
rjmp RSINC ;
RS0:
cpi K,$9 ; bit stop1
brne RS9 ;перейти если не равно
sbi PORTB,PB1 ;
rjmp RSINC ;
RS9:
cpi K,$A ; bit stop2
brne RSB ;перейти если не равно

sbi PORTB,PB1 ;
rjmp RSINC ;
RSB:
cpi K,$B ;
brne RS1 ;перейти если не равно
clr K
cbr KEY,(1<<RSENB) ;
rjmp RSSTOP ;выход

RS1:

sbrs temp2,$0 ;перескочить если бит 0 установлен
rjmp RS11 ;иначе
sbi PORTB,PB1 ;
lsr temp2 ;логически сдвинуть в право. выстав. след. бит
rjmp RSINC ;

RS11:
cbi PORTB,PB1 ;
lsr temp2 ;логически сдвинуть в право. выстав. след. бит
rjmp RSINC ;


RSINC:
inc K ;
rjmp RSPAUSE



RSSTOP:

;в K считаются биты и он указывает после inc на нужный бит. K=$B - окончание передачи байта.
;байт даных сдвигается в лево. передаеться младший бит.
;по окончанию передачи RSENB & KEYSTAT :=0. пока не передан байт подпрога крутиться

pop temp2 ;SREG
out SREG,temp2 ;востанов из стека SREG
pop temp2 ;востанов из стека temp2

ret

;
вот обработчик прерываний:
;---------------TCM1A обработка прерываний от совпадения
TCM1A: ;Match A


push temp2 ;в стек temp2
in temp2,SREG ;сохран статуса
push temp2 ;в стек SREG


inc TM10000 ;увеличение значения счетчика по прерыванию
cpi TM10000,$64 ;сравнить со 100 $64
brne noe100 ;перейти если не равно
inc TM100 ;иначе нарастить 100 Гц счетчик
clr TM10000 ;сброс по совпадению

noe100:
cpi TM100,$32 ;сравнить со 50 $32
brne noe10 ;перейти если не равно
inc TM2 ;иначе нарастить 2 Гц счетчик
clr TM100 ;сброс по совпадению

noe10:

rjmp SOEND1

sbrs FLAG,KEYS ;
rjmp SOEND1 ;


sbrs TM2,$0
rjmp SOEND1

SO00:
sbrs TM10000,$2
rjmp SO10

sbi PORTB,PB1
rjmp SOEND1

SO10:
cbi PORTB,PB1
rjmp SOEND1

SOEND1:

pop temp2 ;востан
out SREG,temp2 ;востанов стека
pop temp2 ;востан temp2

reti
вот настройка таймера:
;----------------настройка таймера
;-TCCR1A
;-b7, b6 = 00 - режим OC1A не задействован
;-b5, b4 = 00 - режим OC1B переключения
;-b3 = 0 FOC1A: Force Output Compare Match 1A не использую
;-b2 = 0
;-b1, b0 = 00 - PWM не использую

ldi temp1,0b00000000 ;
out TCCR1A,temp1 ;

;----TCCR1B
;-Bit 7 = 1 - CTC1 очистить таймер после совпадения
;-Bit 6 = 0 - PSR1
;-Bit 5..4 = 00 reserve
;-Bit 3..0 = 0010 k=2 4*10^6 / 2 / 256 = 7812.5 Гц

ldi temp1,0b10000010 ;
out TCCR1B,temp1 ;

;----OCR1A

ldi temp1,T1COMP;значение для прерывания по совпадению
out OCR1A,temp1 ;

;----OCR1C

ldi temp1,T1RES ;значение для очиски счетчика
out OCR1C,temp1 ;



;------TIMSK
;b7 - - Res
;b6 = 1 OCIE1A: Timer/Counter1 Output Compare Interrupt Enable
;b5 = 0 OCF1B: Output Compare Flag 1B
;b 4..3 - Res
;b2 = 0 TOIE1: Timer/Counter1 Overflow Interrupt Enable
;b1 = 0 TOIE0: Timer/Counter0 Overflow Interrupt Enable
;b0 - - Res

ldi temp1,0b01000000 ;
out TIMSK,temp1 ;
естественно, это я выдернул из своей программы - надо разбираться в ней. настройку делал меняя значения в настройке счетчика и посылал FF, 00, AA, 55 для побстройки
pitman
Цитата(arttab @ Apr 8 2005, 11:36)
1/9600 длительность.
вот моя подпрограмма вывода:


Ок, погляжу. Дык вот 104мкс символ и получается. Буду пробовать FF, 00.
-Tумблер-
Цитата(pitman @ Apr 7 2005, 16:32)
Решил сделать программный UART, электрическая схема собрана, с компа данные идут, на него посылаются. Беру скорость 9600 8N1, считаю, получаю, что передача единичного состояния занимает 104мкс. Делаю тестовый вариант, где в цикле передается 0xAA. Стартовый бит 104мкс, и дальше 1 104мкс, 0 104 мкс и т.д.


Насколько я помню, байты передаются "ногами вперед".
те для передачи 0xAA надо:

0 start 104 мкс
0 бит0 104 мкс
1 бит1 104 мкс
итд
smile.gif
Maxim
Вот кусок програмного УАРТА из рабочей программы (только надо подобрать свои задержки). Передаваемый символ находится в R16
Программа взята из апликейшн на АВР

/************************************************************
* Запись символа в програмный UART
************************************************************/
su_putch: ;
LDI R17, 1+8+1 ; start + data + stop
COM R16 ; Inverte everything
SEC ; Start bit
ppc_m1: ;
BRCC ppc_m2 ; If carry set
CBI SOFT_UARTO,SU_TX; send a '0'
RJMP ppc_m3 ; else
ppc_m2: ;
SBI SOFT_UARTO,SU_TX; send a '1'
NOP ;
ppc_m3: ;
RCALL UART_delay ; One bit delay
RCALL UART_delay ;
NOP ;
LSR R16 ; Get next bit
DEC R17 ; If not all bit sent
BRNE ppc_m1 ; send next
RET ;
pitman
Всем спасибо за участие. Заменил по кругу все кондеры вокруг MAX232, символы перестали биться при передаче. Проблема заборена! cheers.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.