Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATxmega128A1 USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
NikP
Возникла необходимость опрашивать 6 устройств по USART, выбрали ATxmega128A1, т.к. по описанию очень похоже на то что надо. Опыта работы с ним нет, сроки жмут, так что читаю даташит (к сожалению, с английским слабо, идет медленно) и параллельно задаю вопросы .
1. В ДШ написано, что имеется 8 одинаковых устройств (Eight Identical USART peripherals). Насколько они независимы? Т.е. можно ли устанавливать на каждый порт свою скорость обмена, или эти установки одни для всех?
2. Как влияет чтение -запись в одном канале на работу других? В том смысле, что возникающее прерывание при , например , приеме пакета данных в одном канале будет "тормозить" работу других и возникнут пропуски информации, или нет?.
Поделитесь опытом , если можно рабочие примеры или ссылки на такие . Я конечно скачал с сайта Atmel примеры , но дается тяжко, слишком большой объем. Мне бы что покороче , но так чтобы понятно было.
_Артём_
Цитата(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 там сделаны (и по моему достаточно удачно), остаётся только включить файл в проект и использовать.
Юрий_СВ
Многое уже сказано выше. В дополнение могу поделиться своей функцией настройки передатчика УАПП.
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 // передача слова "обрыв"
}
zombi
Цитата(NikP @ Apr 10 2012, 13:43) *
В том смысле, что возникающее прерывание при , например , приеме пакета данных в одном канале будет "тормозить" работу других и возникнут пропуски информации, или нет?.

UART принимает байт. Пакеты разруливаете сами.
Озвучте скорости уартов и частоту тактирования мк.
Navovvol
Вот пример на Си для 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++;
}

Разжевал как мог.
NikP
Спасибо всем откликнувшимся! Сейчас пытаюсь освоить информацию. На попутные вопросы : устройства покупные, с установленной скоростью - 9600 (бит/с). С тактированием пока не решили, будем действовать по обстановке. Для начала думаю 8МГц хватит.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.