Есть следующий проблем, который не борется второй день.

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

Сегодня попробую проверить, что видно после второго MAX232 на стороне компа. Может из-за кондеров не получаются нужные уровни RS-232.
на атини26 нет аппаратного уарта, а есть и2с. Вы в режиме халт дуплекс (как в апликейшен) делаете реализацию?
Я программно делал связь на 9600. у меня проблема была с калибровкой оссилятора на 4 Мгц. Так как я могу считать калибровочный байт только для 1 Мгц. Вот частоту подбирал. И запрещал другие прерывания на время передачи. Уточните, что Вы делаете.
Цитата(arttab @ Apr 8 2005, 11:23)
на атини26 нет аппаратного уарта, а есть и2с. Вы в режиме халт дуплекс (как в апликейшен) делаете реализацию?
Я программно делал связь на 9600. у меня проблема была с калибровкой оссилятора на 4 Мгц. Так как я могу считать калибровочный байт только для 1 Мгц. Вот частоту подбирал. И запрещал другие прерывания на время передачи. Уточните, что Вы делаете.
Дык ить пишу. Делаю чисто программный UART никак не используя USI. Для проверки работы сделана простая программа, которая в цикле отдает 0xAA дергая ножку с нужными задержками. Какая должна быть длительность символа на 9600??
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 для побстройки
Цитата(arttab @ Apr 8 2005, 11:36)
1/9600 длительность.
вот моя подпрограмма вывода:
Ок, погляжу. Дык вот 104мкс символ и получается. Буду пробовать FF, 00.
-Tумблер-
Apr 8 2005, 10:16
Цитата(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 мкс
итд
Вот кусок програмного УАРТА из рабочей программы (только надо подобрать свои задержки). Передаваемый символ находится в 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 ;
Всем спасибо за участие. Заменил по кругу все кондеры вокруг MAX232, символы перестали биться при передаче. Проблема заборена!