|
|
  |
Туплю с программным UART |
|
|
|
Apr 7 2005, 13:32
|
Участник

Группа: Свой
Сообщений: 70
Регистрация: 3-03-05
Пользователь №: 3 029

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

Группа: Свой
Сообщений: 70
Регистрация: 3-03-05
Пользователь №: 3 029

|
С компом содиняюсь по нуль-модемному кабелю прямому. Приходящие данные смотрю в программе minicom под Линух. Скорость, и пр. параметры порта настраиваются в ней. Какой-то мусор в нее же приходит....  Сегодня попробую проверить, что видно после второго MAX232 на стороне компа. Может из-за кондеров не получаются нужные уровни RS-232.
|
|
|
|
|
Apr 8 2005, 01:29
|
Участник

Группа: Свой
Сообщений: 70
Регистрация: 3-03-05
Пользователь №: 3 029

|
Цитата(arttab @ Apr 8 2005, 11:23) на атини26 нет аппаратного уарта, а есть и2с. Вы в режиме халт дуплекс (как в апликейшен) делаете реализацию? Я программно делал связь на 9600. у меня проблема была с калибровкой оссилятора на 4 Мгц. Так как я могу считать калибровочный байт только для 1 Мгц. Вот частоту подбирал. И запрещал другие прерывания на время передачи. Уточните, что Вы делаете. Дык ить пишу. Делаю чисто программный UART никак не используя USI. Для проверки работы сделана простая программа, которая в цикле отдает 0xAA дергая ножку с нужными задержками. Какая должна быть длительность символа на 9600??
|
|
|
|
|
Apr 8 2005, 01:36
|

Профессионал
    
Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371

|
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 для побстройки
--------------------
OrCAD, Altium,IAR, AVR....
|
|
|
|
|
Apr 8 2005, 01:50
|
Участник

Группа: Свой
Сообщений: 70
Регистрация: 3-03-05
Пользователь №: 3 029

|
Цитата(arttab @ Apr 8 2005, 11:36) 1/9600 длительность. вот моя подпрограмма вывода: Ок, погляжу. Дык вот 104мкс символ и получается. Буду пробовать FF, 00.
|
|
|
|
|
Apr 8 2005, 10:16
|

Частый гость
 
Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040

|
Цитата(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 мкс итд
--------------------
- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
|
|
|
|
|
Apr 8 2005, 12:43
|
Участник

Группа: Свой
Сообщений: 36
Регистрация: 24-06-04
Пользователь №: 165

|
Вот кусок програмного УАРТА из рабочей программы (только надо подобрать свои задержки). Передаваемый символ находится в 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 ;
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|