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

 
 
> 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
Ответов
Navovvol
сообщение Apr 11 2012, 06:51
Сообщение #2


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

Группа: Участник
Сообщений: 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



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

 


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


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