реклама на сайте
подробности

 
 
> software UART на tiny 13, может ли он быть надежным?
sbw
сообщение Jan 22 2008, 12:41
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 5-10-07
Из: Харьков, Украина
Пользователь №: 31 107



Стоит такая задача: необходимо в tiny13 при программировании записать первую прошивку, считать данные, которые tiny 13 выдаст, после чего на основе этих данных подставить константы во вторую прошивку, которую уже записать "насовсем" и отправить прибор в путь. Иначе говоря, первая прошивка - калибровочная.
Подзадача: как получить данные из этой Tiny13 "на стенде"? Можно, конечно, писать их в EEPROM, потом считать программатором. Это "вообще". Но в конкретном случае данные - это то, что поступает с АЦП (а нужно откалибровать этот АЦП, то есть высчитать множитель для данных с АЦП, потому что делитель входного напряжения различается от изделия к изделию), напряжение, которое меряет АЦП - это нестабильное сетевое. То есть, нужен именно реал-таймовый поток данных с АЦП, идущий одновременно с потоком данных с калиброванного вольтметра, замеряющего это же сетевое напряжение, чтобы пересчитывать два числа (данные с АЦП калибруемого прибора и данные с вольтметра).
Как получить поток данных с tiny13?
Я предположил, что это можно сделать софтверным uart-ом (к тому же, свободных ног на этой тини - всего одна, на остальных что-то висит: делитель АЦП, реле, светодиоды). Вроде бы предположение "имело право на жизнь": ресурсов процессора для скорости 9600 хватает.
Но столкнулся с тем, что расчетные частоты чуть-чуть не попадают в диапазон требуемых. То есть, данные идут, но только если скорость отличается от расчетной процента на два.
Сначала я предположил, что дело в неточности заводской калибровки: по документации она имеет точность 10%, а требуется 1%. Сделал процедуру автокалибровки по импульсам 100 гц другого процессора. Но в итоге пришел к тому же самому: скорость передачи данных должна быть выше процента на два, чем рассчитывалось. Может быть, я где-то ошибся в алгоритме (ниже)? Или сам заложенный принцип неверен - нельзя полагаться на такую реализацию межпроцессорного обмена, когда нет принципиальной стабильности внутреннего RC-генератора? (и надо делать, скажем, синхронный обмен. Но мне тут уже принципиально интересно стало "в чем же проблема").
Текст фрагмента программы:

Константы и определения:
.equ counter_prescaler=2 ; clk/8
.equ counter_preset=256-125 ; 9 600 000/(8*125) = 9 600
.equ max_bit = 10 ; start + 8bit + stop
.def accum = r16 ; аккумулятор (регистр общего пользования)
.def accum2 = r17 ; второй аккумулятор
.def accum3 = r18 ; ...
.def xl = r26
.def xh = r27
.def yl = r28
.def yh = r29

(инициализация таймера в основной программе - включение прерывания по переполнению и установка делителя. Установка ноги Tx в "1")

(фрагмент прерывания от переполнения таймера 0, передача очередного бита):
ldi accum, counter_preset ; 256-125
out timer0_data, accum ; загрузить регистр данных таймера 0
(...)
; accum = байт для передачи
; accum3 = номер передаваемого бита

cpi accum3, 0 ; start-bit ? (0)
breq tx_send_start
cpi accum3, max_bit-1 ; stop-bit ? (9)
breq tx_send_stop

; если не старт-бит и не стоп-бит - передавать биты с 1 по 8
lsr accum ; сдвинуть весь передаваемый байт через Carry flag
brcc tx_send_0 ; бит в Cf = 0 ? если да- то переход на "поставить 0"
; если нет - то "поставить 1"

tx_send_stop: ; стоп-бит (1)
nop ; nop-ы - для выравнивания тактовых длительностей удержания разных битов.
tx_send_1:
nop
tx_set_1 ; поставить 1 на ножке порта Tx (MOSI)
rjmp tx_send_continue

tx_send_start: ; поставить старт-бит (0)
nop
nop
nop
nop
tx_send_0:
tx_set_0 ; поставить 1 на ножке порта Tx (MOSI)

tx_send_continue: ; дальше - уже не принципиальные моменты, пересчет и сохранение переменных

inc accum3 ; увеличить номер бита для передачи
cpi accum3, max_bit ; сколько осталось бит для передачи (0..9)
breq tx_next ; если 10 -то поменять указатели и укоротить очередь

st X, accum ; сохранить сдвинутый байт ==>>
rjmp tx_bit_pointer_store ; выход с сохранением нового количества бит

tx_next:
clr accum3 ; подготовить передачу следующего байта (0й)
ldd accum2, Y+1 ; загрузить указатель байта
inc accum2 ; подвинуть указатель байта на следующую позицию
ld accum, Y ; загрузить длину очереди
dec accum ; уменьшить длину на 1
st Y, accum ; и сохранить длину
tst accum ; проверить: длина очереди =0?
brne tx_continue
clr accum2 ; если да - то обнулить указатель байта
tx_continue:
std Y+1, accum2 ; сохранить указатель

tx_bit_pointer_store:
std Y+2, accum3 ; сохранить номер передаваемого бита

Вот в таком виде оно все работает.
НО!
если задать counter_preset=256-125-1 - то уже нет.
А если counter_preset=256-125+5 - то еще да. Почему получается "середина" (от +/- 1%) не там? Я что-то не учитываю в алгоритме? Или ошибочная реализация?

Спасибо за внимание smile.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
VladimirYU
сообщение Jan 22 2008, 13:14
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Сложно что то сказать, так как непонятно какие еще процессы выполняются, особенно есть ли еще прерывания. Если они есть то это может быть причиной потери синхронизации. Побовал подобное делать на меге16, потребовался второй UART по 1 линии причем, передачу удалось сделать надежной на 9600, но прерывания все кроме синхротаймера запрещал на момент посылок. А вот с приемом натрахался всласть, пришлось все длительности как и Вам в ручную подгонять. Но Вам вроде прием не нужен?

Удалил ненужное цитирование, больше ТАК не делайте.
Модератор


Сообщение отредактировал IgorKossak - Jan 22 2008, 17:36
Go to the top of the page
 
+Quote Post
sbw
сообщение Jan 22 2008, 13:44
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 5-10-07
Из: Харьков, Украина
Пользователь №: 31 107



Цитата(VladimirYU @ Jan 22 2008, 15:14) *
Сложно что то сказать, так как непонятно какие еще процессы выполняются, особенно есть ли еще прерывания. Если они есть то это может быть причиной потери синхронизации. Побовал подобное делать на меге16, потребовался второй UART по 1 линии причем, передачу удалось сделать надежной на 9600, но прерывания все кроме синхротаймера запрещал на момент посылок. А вот с приемом натрахался всласть, пришлось все длительности как и Вам в ручную подгонять. Но Вам вроде прием не нужен?


Нет, других прерываний нет. После этой процедуры в этом же прерывании идет процедура добавления в очередь передачи еще 7 байт, но она вызывается два раза в секунду. Скорости процессора хватает, пробовал перейти на 4800 - результат тот же.
Не могу определиться: или "додалбывать" этот алгоритм, вручную подбирая коэффициенты, или переходить на синхронную передачу. В первом случае есть опасность, что в серийном производстве вылезет неточность калибровки безкварцевых процессоров, а переделать схематически уже будет нельзя. Во втором случае - надо все сейчас делать заново, в том числе электрическую схему менять,чтобы перейти на тот же синхронный алгоритм (добавить хотя-бы один провод стробирования)


Цитата(GDI @ Jan 22 2008, 15:34) *
Скорость передачи любого уарта определяется частотой задающего генератора, сколько она у вас? Может не мучиться а программатором все же снять инфу?

Я же писал - встроенный "калиброванный" RC генератор 9.6Мгц.
Делится на 8, после этого счетчик отсчитывает (256-125) отсчетов для прерывания, в котором передается очередной бит.

Может мне увеличить промежуток между передачей байт?..
Go to the top of the page
 
+Quote Post
VladimirYU
сообщение Jan 22 2008, 14:01
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(sbw @ Jan 22 2008, 16:44) *
. В первом случае есть опасность, что в серийном производстве вылезет неточность калибровки безкварцевых процессоров, а переделать схематически уже будет нельзя. Я же писал - встроенный "калиброванный" RC генератор 9.6Мгц.
Делится на 8, после этого счетчик отсчитывает (256-125) отсчетов для прерывания, в котором передается очередной бит.

Может мне увеличить промежуток между передачей байт?..


Я не много по другому делал СТАРТ. Ставил 0, запускал синхротаймер и разрешал прерывания от таймера, запрещал все другие и чистил все флаги от источников всех "лишних прерываний"
Go to the top of the page
 
+Quote Post
sbw
сообщение Jan 22 2008, 14:21
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 39
Регистрация: 5-10-07
Из: Харьков, Украина
Пользователь №: 31 107



Цитата(VladimirYU @ Jan 22 2008, 16:01) *
Я не много по другому делал СТАРТ. Ставил 0, запускал синхротаймер и разрешал прерывания от таймера, запрещал все другие и чистил все флаги от источников всех "лишних прерываний"

Предлагаете удлиннить "старт-бит"?
Но это же вроде будет не по стандарту.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- sbw   software UART на tiny 13   Jan 22 2008, 12:41
- - GDI   Скорость передачи любого уарта определяется частот...   Jan 22 2008, 13:34
- - Ruslan_Shaida   Как вариант, можно использовать код типа «Манчесте...   Jan 22 2008, 14:37
- - prottoss   Может проще софтверного UART соорудить софтверный ...   Jan 22 2008, 15:05
|- - sbw   Цитата(prottoss @ Jan 22 2008, 17:05) Мож...   Jan 22 2008, 15:17
- - _Pasha   Цитата(sbw @ Jan 22 2008, 15:41) Текст фр...   Jan 22 2008, 16:03
|- - sbw   Точно! В этом и была суть! Огромное спасиб...   Jan 23 2008, 00:06
|- - SasaVitebsk   Цитата(sbw @ Jan 23 2008, 04:06) А можете...   Jan 23 2008, 08:42
- - SasaVitebsk   На кварце 73728 я реализовывал так называемый auto...   Jan 22 2008, 16:17
- - defunct   ЦитатаНо столкнулся с тем, что расчетные частоты ч...   Jan 23 2008, 00:10
- - Rst7   ЦитатаДействительно, как раз и набегает на 17 такт...   Jan 23 2008, 06:16
- - _Pasha   По поводу того, зачем паузу ставить - defunct все ...   Jan 23 2008, 08:41
- - Deka   А может быть передать необходиые данные при помощи...   Jan 23 2008, 12:37


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 23:25
Рейтинг@Mail.ru


Страница сгенерированна за 0.01416 секунд с 7
ELECTRONIX ©2004-2016