29.04.2014, 16:17
|
|
Временная регистрация
Регистрация: 28.05.2012
Сообщений: 51
Сказал спасибо: 0
Сказали Спасибо 32 раз(а) в 32 сообщении(ях)
|
Программный UART для PIC12F675
Люди, который раз пытаюсь реализовать эту фиговину. Помогите разобраться, плиз, что не так. Некоторые символы передаются норм, а другие некорректно. Задержки рассчитывал как 1000000(при 4 МГц)/baudrate. Проверяю как в протеусе, так и на железе. Заранее спасибо!
Код:
|
software_UART
bcf STATUS, RP0 ; bank 0 selected
movlw 08h
movwf count_of_bits
movlw 055h
movwf result
bcf GPIO, GP0 ; start bit
transsmit
call delay
btfss result, 0h
goto zero
bsf GPIO, GP0
goto next
zero bcf GPIO, GP0
next bcf STATUS, C
rrf result, 01h
decfsz count_of_bits, 01h
goto transsmit
call delay
bsf GPIO, GP0 ; stop bit
call delay
bsf STATUS, RP0
return
delay
movlw 066h
movwf count_of_cycles
cycle_delay
nop
decfsz count_of_cycles, 01h
goto cycle_delay
return |
|
|
|
|
29.04.2014, 17:02
|
|
Заблокирован
Регистрация: 21.01.2014
Сообщений: 589
Сказал спасибо: 7
Сказали Спасибо 267 раз(а) в 206 сообщении(ях)
|
Re: Программный UART для PIC12F675
Сообщение от Fair88Play
|
Задержки рассчитывал как 1000000(при 4 МГц)/baudrate.
|
Например, для 9600 длительность битов должна быть 104мкс или 104 тика микропроцессора. То есть длина цикла transsmit должна быть 104. Если считать, что все команды по 1 тику, btfss 1-2, а goto, call по 2 тика, то получается всего 12 тиков внутри transsmit. Значит на delay остаётся 104-12=92 тиков.
Внутри delay имеем 5 тиков + длина цикла * count_of_cycles. Длина цикла cycle_delay равна 4 тика. Таким образом получаем (92-5)/4=22. То есть надо пройти цикл cycle_delay 22 раза для получения нужной задержки.
Код:
|
delay
movlw 016h
movwf count_of_cycles |
для скорости 9600 бод
И ещё. Стартовый бит тоже должен быть 104 тика длиной в идеале, то есть между "bcf GPIO, GP0 ; start bit" и "bsf GPIO, GP0" должно быть 12 тиков + delay. А программе только 4 + delay. Поэтому надо бы передвинуть start bit и вставить несколько NOP, типа так
Код:
|
software_UART
bcf STATUS, RP0 ; bank 0 selected
bcf GPIO, GP0 ; start bit
movlw 08h
movwf count_of_bits
movlw 055h
movwf result
nop
nop
nop
nop
transsmit
call delay |
Последний раз редактировалось Yurkin2014; 29.04.2014 в 17:24.
|
|
|
|
29.04.2014, 19:19
|
|
Временная регистрация
Регистрация: 28.05.2012
Сообщений: 51
Сказал спасибо: 0
Сказали Спасибо 32 раз(а) в 32 сообщении(ях)
|
Re: Программный UART для PIC12F675
Спасибо за ответ, но есть определенные непонятные моменты.
1) Не понял как получается 12 тиков в трансмите? Ведь бит устанавливается в "середине" цикла, и тики нужно считать от "середины" до "середины цикла".
2)
Цитата:
|
Внутри delay имеем 5 тиков + длина цикла * count_of_cycles.
|
Внутри delay мы имеем же 2 тика (
Код:
|
movlw 016h
movwf count_of_cycles |
) + длина цикла * (count_of_cycles - 1) + 5 тиков (т.к. в последнем цикле
Код:
|
nop - 1 такт
decfsz count_of_cycles, 01h - 2 такта
goto cycle_delay - 0 тактов
return - 2 такта |
), или я ошибаюсь?
|
|
|
|
29.04.2014, 20:21
|
|
Заблокирован
Регистрация: 21.01.2014
Сообщений: 589
Сказал спасибо: 7
Сказали Спасибо 267 раз(а) в 206 сообщении(ях)
|
Re: Программный UART для PIC12F675
1). От "середины" до "середины цикла" то же самое, что от "начала" до "начала". Считайте как хотите, главное посчитать полный круг цикла.
2).
Код:
|
movlw 016h - 1 такт
movwf count_of_cycles - 1 такт
цикл
nop - 1 такт
decfsz count_of_cycles, 01h - 1 такт если не ноль, и 2 такта если 0 при выходе из цикла
goto cycle_delay - 2 такта
return - 2 такта |
|
|
|
|
30.04.2014, 01:46
|
|
Частый гость
Регистрация: 19.10.2006
Адрес: te.ua
Сообщений: 12
Сказал спасибо: 2
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Программный UART для PIC12F675
рабочий проект с программным UART-ом
|
|
|
|
30.04.2014, 10:20
|
|
Почётный гражданин KAZUS.RU
Регистрация: 02.03.2011
Адрес: Россия, КБР
Сообщений: 629
Сказал спасибо: 108
Сказали Спасибо 596 раз(а) в 334 сообщении(ях)
|
Re: Программный UART для PIC12F675
А для чего программный UART? Тоже делал, когда нужно было два, а был всего один аппаратный. Но программный делал на 1200bps. При 9600 можно не успеть сделать всех необходимых операций (вычислить/проверить бит чётности, например). А если есть ещё параллельные процессы/прерывания, то вообще попа... На приём, тиков должно быть минимум три.
|
|
|
|
30.04.2014, 19:28
|
|
Временная регистрация
Регистрация: 28.05.2012
Сообщений: 51
Сказал спасибо: 0
Сказали Спасибо 32 раз(а) в 32 сообщении(ях)
|
Re: Программный UART для PIC12F675
Спасибо всем за ответы, но вопрос остается в силе. Yurkin2014, в соответствии с вашими замечаниями был скорректирован код, однако работает он все равно некорректно (значение 0х55 передается безошибочно, а вот 0хАА некорректно). Программа написана для скорости 2400 бод. Буду признателен выслушать замечания. Исправленный код приведен ниже:
Код:
|
software_UART
bcf STATUS, RP0 ; bank 0 selected
bcf GPIO, GP0
movlw 08h
movwf count_of_bits
movlw 0AAh
movwf result
nop
nop
nop
transsmit
call delay
btfss result, 0h
goto zero
bsf GPIO, GP0
goto next
zero bcf GPIO, GP0
nop
next bcf STATUS, C
rrf result, 01h
decfsz count_of_bits, 01h
goto transsmit
nop
nop
nop
nop
call delay
bsf GPIO, GP0
call delay
return
delay
nop
nop
movlw 64h
movwf count_of_cycles
cycle_delay
nop
decfsz count_of_cycles, 01h
goto cycle_delay
return |
Считал так: Цикл трансмит выполняется за 12 циклов, на delay остается (1000000/2400)-12 = 405. В подпрограмме delay count_of_cycles рассчитывается так: (405 - 4 (nop, nop, movlw 64h, movwf count_of_cycles) - 5 (nop; decfsz count_of_cycles, 01h; nop; return))/4 = 99. Также добавлены 4 команды nop для корректировки stop bit.
Цитата:
|
А для чего программный UART?
|
vynt, программный UART здесь нужен просто потому, что в PIC12F675 нет аппаратного.
|
|
|
|
30.04.2014, 20:57
|
|
Заблокирован
Регистрация: 23.02.2010
Адрес: GB
Сообщений: 99
Сказал спасибо: 2
Сказали Спасибо 21 раз(а) в 9 сообщении(ях)
|
Re: Программный UART для PIC12F675
для pic16F84 давно пользую - 4мГц кварц, 9600
;-----------------------------------------------------------------------------
; Один бит - 104 мкс.ДЛЯ 1200 бит=833mks Р знос не более -10% от времени перед чи.
TransmittByte
movwf fDATA_OUT
clrf fBIT_CNT
; Выводим стартовый бит.
bcf TX_DATA
; Задержка 1*T (104 мкс).101
movlw d'25' ; 207для 1200 задержка /4 207
movwf fCOUNTER
TBDelay1_Loop
nop
decfsz fCOUNTER,1
goto TBDelay1_Loop
; Выводим 8 бит данных начиная с младшего.
TBBIT_Loop
btfss fDATA_OUT,0
bcf TX_DATA
btfsc fDATA_OUT,0
bsf TX_DATA
rrf fDATA_OUT,1
incf fBIT_CNT,1
; Задержка .
nop
nop
nop
nop
movlw d'18' ; 164для 1200 задержка /4 (-14)150/200
movwf fCOUNTER ;95
TBDelay2_Loop
nop
nop
decfsz fCOUNTER,1
goto TBDelay2_Loop
; Проверка на заполнение всех 8 бит.
btfss fBIT_CNT,3
goto TBBIT_Loop
; Выводим стоповый бит.
bsf TX_DATA
movlw d'26' ;211для 1200 задержк /4
movwf fCOUNTER ;106
TBDelay3_Loop
nop
decfsz fCOUNTER,1
goto TBDelay3_Loop
return
;===============================
Receive_kod ; RS232. 9600 8 N 1 1.035ms =FF 1.038=00
; задержка 1,5Т (156мкс)
btfsc RX_DATA ; RB3
goto Receive_kod
movlw d'38' ; задержка /4 153
movwf fCOUNTER
RKDelay1_Loop
nop
decfsz fCOUNTER,1 ;151mks
goto RKDelay1_Loop
; Читаем 8 бит начиная с младшего.
clrf fBIT_CNT
clrf fDATA_IN
RKBIT_Loop
incf fBIT_CNT,1
; Читаем бит в fDATA_IN.
bcf STATUS,C
rrf fDATA_IN,1
btfsc RX_DATA ; ПОРТ ВВОДА !!!!!
bsf fDATA_IN,7
; Задержка 1*T 208,3мкс ;(104 мкс для 9600).
movlw d'24' ; задержка /4
movwf fCOUNTER
nop
nop
nop
RKDelay2_Loop
nop
decfsz fCOUNTER,1 ;96mks 102
goto RKDelay2_Loop
; Проверка на заполнение всех 8 бит.
btfss fBIT_CNT,3
goto RKBIT_Loop
; Задержка 0.5*T 104 мкс для 9600; (52 мкс для 9600).
movlw d'13' ; задержк /4 53
movwf fCOUNTER
RKDelay3_Loop
nop
decfsz fCOUNTER,1
goto RKDelay3_Loop
movf fDATA_IN,W ;байт данных находтся в fDATA_IN
RETURN
|
|
|
|
30.04.2014, 22:37
|
|
Частый гость
Регистрация: 19.10.2006
Адрес: te.ua
Сообщений: 12
Сказал спасибо: 2
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Программный UART для PIC12F675
Ваш исправленый код у меня отлично работает:
Код:
|
list p=12f675
#include ‹p12f675.inc›
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT
initGPIO equ b'00000001'
trisGPIO equ b'11111110'
;---------------RAM------------------------------------
RAMbase equ 0x20 ; start RAM is 20h
count_of_cycles equ RAMbase + 0x00
count_of_bits equ RAMbase + 0x01 ;
result equ RAMbase + 0x02 ;
;---------------RAM------------------------------------
org 0x000
call init
goto entry
org 0x004
retfie
software_UART:
bcf STATUS, RP0
bcf GPIO, 0
; movlw 0xAA
movwf result
movlw 0x08
movwf count_of_bits
nop
nop
nop
transsmit:
call delay
btfss result, 0
goto zero
bsf GPIO, 0
goto next
zero:
bcf GPIO, 0
nop
next:
bcf STATUS, C
rrf result, f
decfsz count_of_bits, f
goto transsmit
nop
nop
nop
nop
call delay
bsf GPIO, 0
call delay
return
delay:
nop
nop
movlw 0x64
movwf count_of_cycles
cycle_delay:
nop
decfsz count_of_cycles, f
goto cycle_delay
return
;************************************************* **************************************
;* Initialization Routine *
;************************************************* **************************************
init:
call 0x3FF
banksel 0x80
movwf OSCCAL
movlw trisGPIO
movwf TRISIO
movlw b'00000000'
movwf ANSEL
banksel 0x00
movlw b'00000111'
movwf CMCON
movlw b'00000000'
movwf INTCON
movlw initGPIO
movwf GPIO
return
entry:
; задержка
movlw D'64'
movlw count_of_bits
call delay
decfsz count_of_bits, f
goto $-2
; вывод строки
movlw 'k'
call software_UART
movlw 'a'
call software_UART
movlw 'z'
call software_UART
movlw 'u'
call software_UART
movlw 's'
call software_UART
movlw '.'
call software_UART
movlw 'r'
call software_UART
movlw 'u'
call software_UART
movlw 0x0D
call software_UART
movlw 0x0A
call software_UART
goto entry
END |
|
|
|
Сказали "Спасибо" maxx_kazus
|
|
|
04.05.2014, 20:18
|
|
Временная регистрация
Регистрация: 28.05.2012
Сообщений: 51
Сказал спасибо: 0
Сказали Спасибо 32 раз(а) в 32 сообщении(ях)
|
Re: Программный UART для PIC12F675
Цитата:
|
Ваш исправленый код у меня отлично работает
|
Все дело в том, что "kazus.ru" выводит без проблем. Самое смешное то, что символ "к" на русской раскладке (0xAA) не выводится, при том предшествующий символ "й" и последующий символы выводятся норм. Так в чем же загадка?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 00:26.
|
|