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

 
 
> ATxmega128A1 USART, как задействовать все порты
NikP
сообщение Apr 10 2012, 10:43
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Возникла необходимость опрашивать 6 устройств по USART, выбрали ATxmega128A1, т.к. по описанию очень похоже на то что надо. Опыта работы с ним нет, сроки жмут, так что читаю даташит (к сожалению, с английским слабо, идет медленно) и параллельно задаю вопросы .
1. В ДШ написано, что имеется 8 одинаковых устройств (Eight Identical USART peripherals). Насколько они независимы? Т.е. можно ли устанавливать на каждый порт свою скорость обмена, или эти установки одни для всех?
2. Как влияет чтение -запись в одном канале на работу других? В том смысле, что возникающее прерывание при , например , приеме пакета данных в одном канале будет "тормозить" работу других и возникнут пропуски информации, или нет?.
Поделитесь опытом , если можно рабочие примеры или ссылки на такие . Я конечно скачал с сайта Atmel примеры , но дается тяжко, слишком большой объем. Мне бы что покороче , но так чтобы понятно было.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 5)
_Артём_
сообщение Apr 10 2012, 11:04
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(NikP @ Apr 10 2012, 13:43) *
1. В ДШ написано, что имеется 8 одинаковых устройств (Eight Identical USART peripherals). Насколько они независимы? Т.е. можно ли устанавливать на каждый порт свою скорость обмена, или эти установки одни для всех?

Установки индивидуальны для каждого порта.
Независимы полностью: для каждого uart есть свой блок регистров и вектора прерываний.

Цитата(NikP @ Apr 10 2012, 13:43) *
2. Как влияет чтение -запись в одном канале на работу других? В том смысле, что возникающее прерывание при , например , приеме пакета данных в одном канале будет "тормозить" работу других и возникнут пропуски информации, или нет?.

Если читать в прерывании быстро то не влияют и потерь не будет.
Если прерывание выполнияется долго (любое, не обязательно от usart). то потери возможны.
К тому же есть возможность задействовать DMA (но на все usart-ы не хватит каналов dma).

Цитата(NikP @ Apr 10 2012, 13:43) *
Поделитесь опытом , если можно рабочие примеры или ссылки на такие . Я конечно скачал с сайта Atmel примеры , но дается тяжко, слишком большой объем. Мне бы что покороче , но так чтобы понятно было.

Скачайте с сайта атмела соотв. апноту с примером(using xmega usart): там есть пример с дма и тп.
Используйте их библиотеку (usart_driver.c/usart_driver.h) - многие нужные функции работы с блоком usart там сделаны (и по моему достаточно удачно), остаётся только включить файл в проект и использовать.
Go to the top of the page
 
+Quote Post
Юрий_СВ
сообщение Apr 10 2012, 11:51
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 4-05-08
Пользователь №: 37 272



Многое уже сказано выше. В дополнение могу поделиться своей функцией настройки передатчика УАПП.
CODE
void TX_On() // Включить передатчик УАПП
{
USARTx_BRR=0x01A1; // делитель формирователя битового интервала
// DIV_Mantissa[11:0]=0x01A // целая часть делителя USART
// DIV_Fraction[3:0] =0x1 // дробная часть делителя USART
// т.к. максимальная битовая частота УАПП
// в 8/16 раз (определяется битом OVER8 в регистре USARTx_CR1)
// меньше частоты синхронизации шины ввода/вывода
// соответсвенно дробная часть включает до 8 или 16 частей
// т.е. дробная часть указывается в восьмых или шестнадцатых долях
// битовая частота = частота синхронизации / (8 * (2-OVER8) * делитель)
// для скорости 57600 при частоте синхронизации шины 24 МГц:
// DIV_Mantissa[11:0]=26
// DIV_Fraction[3:0] = 1
// т.е. делитель=26,0625 для OVER8=0
// можно считать и по-другому (по крайней мере для OVER8=0)
// USARTx_BRR=частота шины/битовую частоту

USARTx_CR2=0x0000;
// LINEN=0 // режим LIN (0 - выкл)
// STOP[1:0]=00 // кол-во стоп-битов (00-1)
// CLKEN=0 // разрешение вывода синхронизации (0 - выкл)
// CPOL=0 // полярность вывода синхронизации (не используется)
// CPHA=0 // фаза вывода синхронизации (не используется)
// LBCL=0 // импульс синхронизации по выдаче последнего бита (не используется)
// LBDIE=0 // разрешение прерываний по сигналу обрыв в режиме LIN (не используется)
// LBDL=0 // длина сигнала обрыв в режиме LIN (не используется)
// ADD[3:0]=0000 // адрес узла в мультипроцессорном режиме (не используется)

USARTx_CR3=0x0000;
// ONEBITE=0 // ? кол-во выборок на бит 0 - 3 выборки, 1 - 1 выборка
// CTSIE=0 // разрешение прерывание по CTS (0 - выкл)
// CTSE=0 // разрешение управление потоком по CTS (0 - выкл)
// RTSE=0 // разрешение управление потоком по RTS (0 - выкл)
// SCEN=0 // режим работы со смарткартами (0 - выкл)
// NACK=0 // разрешение посылки NACK при ошибках
// в режиме работы со смарткартами (0 - выкл)
// HDSEL=0 // режим полудуплекса для однопроводного обмена (0 - выкл)
// IRLP=0 // режим низкого потребления режиме IrDA (0 - выкл)
// IREN=0 // режим IrDA (0 - выкл)
// EIE=0 // разрешение прерывание по ошибкам (0 - выкл)

USARTx_GTPR=0x0000;
// GT[7:0]=0x00 // длина защитного интервала при работе со смарткартами
// PSC[7:0]=0x00 // ?? входной делитель синхронизации (00 или 01)
// описан только для IrDA и смарткарт
// проверено: в режиме обычного асинхронного УАПП
// поле PSC[7:0] на передачу не влияет

USARTx_CR1=0x2008;
// OVER8=0 //
// UE=1 // разрешение работы УАПП (1 - разрешён)
// (разрешает входной делитель и выходы)
// M=0 // длина слова (0 - 8 бит, 1 - 9 бит)
// WAKE=0 // выбор события для просыпания (не используется)
// PCE=0 // разрешение проверки чётности (0 - выкл)
// PS=0 // выбор режима проверки чётности
// PEIE=0 // разрешение прерывания по ошибкам чётности (0 - выкл)
// TXEIE=0 // разрешение прерывания по опустошению (0 - выкл)
// регистра данных передачи
// TCIE=0 // разрешение прерывания по окончанию передачи (0 - выкл)
// RXNEIE=0 // разрешение прерывания по приёму (0 - выкл)
// IDLEIE=0 // разрешение прерывания по состоянию покоя в линии (0 - выкл)
// TE=1 // разрешение передатчика
// RE=0 // разрешение приёмника
// RWU=0 // ??
// SBK=0 // передача слова "обрыв"
}


Сообщение отредактировал IgorKossak - Apr 10 2012, 14:09
Причина редактирования: [codebox] для длинного кода!!!
Go to the top of the page
 
+Quote Post
zombi
сообщение Apr 10 2012, 21:42
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(NikP @ Apr 10 2012, 13:43) *
В том смысле, что возникающее прерывание при , например , приеме пакета данных в одном канале будет "тормозить" работу других и возникнут пропуски информации, или нет?.

UART принимает байт. Пакеты разруливаете сами.
Озвучте скорости уартов и частоту тактирования мк.
Go to the top of the page
 
+Quote Post
Navovvol
сообщение Apr 11 2012, 06:51
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 9-09-11
Пользователь №: 67 080



Вот пример на Си для Avr Studio
CODE

//Atxmega128A1
//скорость 115200
// тактовая частота 24000000
//bauddivider = 24000000/(8*115200)-1 = 26(dec) - 0x19
#define bauddivider_low 0x19
#define bauddivider_high 0x00
void usartf1_init(void)
{
PORTF_OUTSET=0x80; // удерживаем пин 7 в "1"
// асинхр // паритет выкл// 8 бит
USARTF1_CTRLC=USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;

// низкое прерывание по окончанию приема и передачи данных
USARTF1_CTRLA=(USARTF1_CTRLA & (~(USART_RXCINTLVL_gm | USART_TXCINTLVL_gm | USART_DREINTLVL_gm))) |
USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc | USART_DREINTLVL_OFF_gc;

// скорость 115200
USARTF1_BAUDCTRLA=bauddivider_low;
USARTF1_BAUDCTRLB=bauddivider_high;
// Прием : вкл
// Передача:вкл
// двойная скорость: вкл
// Мульти-процессор: выкл
USARTF1_CTRLB=(USARTF1_CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm | USART_MPCM_bm | USART_TXB8_bm))) |
USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm;

Аналогично конфигурируем остальные USART.
Разрешаем низкие прерывания и "карусельную приоритезацию" (или как там ее) по инглишу вот так называется: Round-robin.// карусель работает только по низким прерываниям.
Код
//конфигурация контроллера прерываний
void PMIC_init(void)
{
    unsigned char a;
a=(PMIC_CTRL & (~(PMIC_RREN_bm | PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm))) |
    PMIC_LOLVLEN_bm | PMIC_RREN_bm;//| PMIC_MEDLVLEN_bm;//| PMIC_HILVLEN_bm;
//CCP=CCP_IOREG_gc;
PMIC_CTRL=a;
PMIC_INTPRI=0x00;    
}

нужен еще таймер на 1мсек. Для того что бы установить интервал времени между соседними пакетами.
CODE

// инициализация таймера0
void tcc0_init(void) // таймер на 1 мсек
{
TCC0_CCA=24000000/(1000*2);// частота 1000 Hz
// тактирование DIV 2
TCC0_PER=24000000/(1000*2);// частота 1000 Hz
TCC0_CTRLA=(TCC0_CTRLA & (~TC0_CLKSEL_gm)) | TC_CLKSEL_DIV2_gc;
//режим FRQ/разрешение сравнения в канале А
TCC0_CTRLB=(TCC0_CTRLB & (~(TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm | TC0_WGMODE_gm))) |
TC0_CCAEN_bm | TC_WGMODE_NORMAL_gc;
// разрешение низкого прерывания по сравнению в канале А
TCC0_INTCTRLB=(TCC0_INTCTRLB & (~(TC0_CCDINTLVL_gm | TC0_CCCINTLVL_gm | TC0_CCBINTLVL_gm | TC0_CCAINTLVL_gm))) |
TC_CCDINTLVL_OFF_gc | TC_CCCINTLVL_OFF_gc | TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_LO_gc;
}

Далее в обработчике прерывания таймера увеличиваем счетчик.
Код
/// обработчики прерываний
ISR(TCC0_CCA_vect) // обработчик прерывания по таймеру 1msec
{
    counter_msec++;
}

в основном цикле, сравнивая переменную counter_msec с уставкой, отправляем первый байт пакета. (и сбросить counter_msec не забыть)
В обработчике по окончанию передачи данных нужно отправить следующий байт пакета.
Пример:
CODE

#define RX_BUFFER_SIZE 12 //размер приемного буффера
#define TX_BUFFER_SIZE 41 //размер буффера передачи

#define p RX_BUFFER_SIZE // р - размер окончательного буфера, входящего пакета
#define n p*2+1 // буфер двойной для входящего пакета

// переменные для передачи пакета
char TX_B[41];
unsigned char B_tx_offset; //смещение по пакету
char flag_TX_pack_co;//флаг завершения передачи пакета;

ISR(USARTF1_TXC_vect) //обработчик прерывания по передаче данных
{
if ((B_tx_offset<TX_BUFFER_SIZE)&(flag_TX_pack_complite!=1))
{
USARTF1_DATA = TX_B[++B_tx_offset];
}
if (B_tx_offset==TX_BUFFER_SIZE)
{
B_tx_offset=0;
flag_TX_pack_complite=1;
}
}

И так для всех усартов. Пример обработчика приема данных:
CODE

// переменные для приема пакета char wbuf[n];
//рабочий буфер, где n= удвоенный размер принимаемого пакета + 1 char ebuf[p];
//окончательный буфер, к которому будет обращаться программа, размер = размеру принимаемого пакета char pb, pe;
//индексы в буфере, первый указывает на начало пакета, второй на конец, вначале оба равны нулю
// (пакет в буфере может располагаться не в начале буфера) char flag_RX_pack_co;
// флаг завершения приема пакета unsigned int counter_RX_pack;
// счетчик пакетов

ISR(USARTF1_RXC_vect) //обработчик прерывания по приему данных
{
char x;
wbuf[pe]=USARTF1_DATA; //Пишем принятый символ в массив wbuf[pe]
if((pe-pb)==p) //Если pe - pb равно размеру пакета
{

if((wbuf[pb]==0x0A)&(wbuf[pb+1]==0x20)&(wbuf[pe-1]==0x0D))
//Если wbuf[pb] = стартовому символу И wbuf[pb+1] = индентификатору пакета И wbuf[pe] = стоповому символу
{
for (x=0;x<p;x++)
{
ebuf[x]=wbuf[x+pb];
}
pb=pe=0;
flag_RX_pack_co=1;
counter_RX_pack++;
}
else
{
pb++;
pe++;
}
if(pe==n)
{
pb=pe=0 ;
}
}
else pe++;
}

Разжевал как мог.

Сообщение отредактировал IgorKossak - Apr 12 2012, 06:49
Причина редактирования: длинные строки в [codebox] не переносятся, разбивайте вручную
Go to the top of the page
 
+Quote Post
NikP
сообщение Apr 11 2012, 12:15
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-08-05
Пользователь №: 7 944



Спасибо всем откликнувшимся! Сейчас пытаюсь освоить информацию. На попутные вопросы : устройства покупные, с установленной скоростью - 9600 (бит/с). С тактированием пока не решили, будем действовать по обстановке. Для начала думаю 8МГц хватит.
Go to the top of the page
 
+Quote Post

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

 


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


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