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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> 2 USART под RS485 на ATMega162
vetalxh
сообщение Mar 15 2009, 20:31
Сообщение #1





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Здравия желаю всем !

Делаю устройство на Mega162 с двумя протоколами modbus.
USART0 - master, посылает всего 11 разных запросов. USART1 - slave, отвечает на эти 11 запросов с некоторыми корректировками. То есть устройство устанавливается между master и slave и общается с ними с нужными мне исправлениями.

В общем, сделал отдельно master и slave - работает, но когда все в целом, то работает только slave, а master зацикливается на 1-й посылке, иногда 2-я проскакивает.

Вроде проблема с прерываниями, т.к. slave постоянно принимает и отвечает, и не дает master работать. Игрался с запретом прерываний, но ничего не помогло.

Также делал чтобы slave принял, ответил, а потом master послал, принял, поочередно, но так теряется слейвом фреймы.

У кого могут быть какие идеи? Такое устройство возможно ли вообще?

Мега162, кварц - 3,6864... Параметры связи обоих 2400-О-1...
Go to the top of the page
 
+Quote Post
smac
сообщение Mar 15 2009, 21:09
Сообщение #2


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

Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003



Цитата(vetalxh @ Mar 15 2009, 23:31) *
...
У кого могут быть какие идеи? Такое устройство возможно ли вообще?
...

Устройство, понятное дело, возможно. Думаю стоит смотреть в сторону буферизации приемника слейва и уменьшения длительности выполнения обработчиков прерывания. А вообще стандартная фраза: Код в студию!
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 15 2009, 21:31
Сообщение #3





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Кода вообще много... Постараюсь основное. Сильно не пинайте, т.к. учусь уму разуму...
Это один из вариантов. Но не один из них корректно не работает


CODE
void StartTrans0(void)
{
DisableReceive0;
SetBit(PORTA,1);
TrCount0=0;
GoTrans0;
}

void StartTrans1(void)
{
SetBit(PORTA,0);
TrCount1=0;
GoTrans1;
}


interrupt [USART0_DRE] void usart0_udre_isr(void)
{
if (TrCount0<cNumTrByte0-1)
{
UDR0=cmTrBuf0[TrCount0];
TrCount0++;
}
else
{
UDR0=cmTrBuf0[cNumTrByte0-1];
StopTrans0;
TrCount0=0;
FinTrans=1;
}
}

interrupt [USART0_TXC] void usart0_tx_isr(void)
{
if (TrCount0<cNumTrByte0-1)
{
StopTrans0;
FinTrans=1;
ClrBit(PORTA,1);
EnableReceive0;
}

interrupt [USART0_RXC] void usart0_rx_isr(void) // USART0 I?a?uaaiea i?eaiieea IANOA?A
{
char status;
status=UCSR0A;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
if (StartRec0==0)
{
StartRec0=1;
RcCount0=0;
cmRcBuf0[RcCount0++]=UDR0;
TCCR1B=0x05;
TCNT1H=0xFF;
TCNT1L=0xEA;
}
else
{
cmRcBuf0[RcCount0++]=UDR0;
TCNT1H=0xFF;
TCNT1L=0xEA;
}
}
}

interrupt [USART1_RXC] void usart1_rx_isr(void)
{
char status,data;
status=UCSR1A;
data=UDR1;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
if (StartRec1==0)
{
StartRec1=1;
RcCount1=0;
cmRcBuf1[RcCount1++]=data;
TCNT0=0xE9;
TCCR0=0x05;
}
else
{
if (RcCount1<MaxLenghtRecBuf1)
{
cmRcBuf1[RcCount1++]=data;
}
else
{
cmRcBuf1[MaxLenghtRecBuf1-1]=data;
}
TCNT0=0xE9;
}
}
}

interrupt [USART1_DRE] void usart1_udre_isr(void) // USART1 I?a?uaaiea ia?aaao?eea IIA?EIAIIIAI
{
if (TrCount1<cNumTrByte1+1)
{
UDR1=cmTrBuf1[TrCount1];
TrCount1++;
}
else
{
StopTrans1;
//ClrBit(DDRA,0);
ClrBit(PORTA,0); //PA0 a 0 - ?aaioa a?aeaa?a 485 ia i?eai
//EnableReceive1;
TrCount1=0;
}
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{

if (StartRec1==1)
{
StartRec1=0;
cNumRcByte1=RcCount1;
bModBus1=1;
TCCR0=0;
}
}

char ModBus0 (void)
{
int TempI;
if (cmRcBuf0[0]==0x01 && cmRcBuf0[1]==0x03 && cmRcBuf0[2]==0x02)
{
...
}
}

char ModBus2 (void)
{
switch (ModFlag)
{
case (1):
{
...
}
}
}


interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
if (StartRec0==1)
{
StartRec0=0;
cNumRcByte0=RcCount0;
bModBus0=1;
TCCR1B=0x00;
DisableReceive0;
}
else
{
TCCR1B=0x00;
TCNT2=0x00;
TCCR2=0x07;
DisableReceive0;
}
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
TrCount0=0;
cNumTrByte0=ModBus2();
StartTrans0();
TCCR2=0x00;
}

char ModBus1 (char NumByte)
{
...
}
}


void main(void)
{
Setup();
StartUART0();
StartUART1();
SetBit(DDRD,0);SetBit(PORTD,0);
ClrBit(DDRD,1);ClrBit(PORTD,1);
SetBit(PORTA,1);
ClrBit(DDRB,2);ClrBit(PORTB,2);
SetBit(DDRB,3);SetBit(PORTB,3);
EnableReceive1;
ClrBit(PORTA,0);
TCCR2=0x07;
TCNT2=0x00;
#asm("sei")
while (1)
{
#asm("cli")
if (bModBus0==1)
{
ModBus0();
bModBus0=0;
TCNT2=0x00;
TCCR2=0x07;
}
if (bModBus1==1)
{
cNumTrByte1=ModBus1(cNumRcByte1);
if (cNumTrByte1!=0) StartTrans1();
bModBus1=0;
}
#asm("sei")
}
}
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 15 2009, 22:38
Сообщение #4





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Цитата(smac @ Mar 16 2009, 01:09) *
Устройство, понятное дело, возможно. Думаю стоит смотреть в сторону буферизации приемника слейва и уменьшения длительности выполнения обработчиков прерывания. А вообще стандартная фраза: Код в студию!

Буфферизация приемника слейва, думАю, не поможет, т.к. мне нужно сразу же отвечать на запрос главного в течении времени 3.5 передачи символа, а обработку тоже старался сделать быструю с минимумом подсчетов...
Может проще все это сделать на 2х мегах8 и соединить их через spi? Не будет ли оно также конфликтовать?
Если в коде не понятны фукции какие-то, пишите..расскажу
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Mar 15 2009, 22:43
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Не разбирался, но взглянул. Заметил такое: выключение передачи - StopTrans1- делается не по TXC, следовательно может подрезать последний байт (стоп-бит). Проверить подручными средствами этот момент проще, если убрать 485 и подключить UART-ы напрямую, но, ИМХО, и так видно. Не думаю, что это единственная проблемка.
Цитата
мне нужно сразу же отвечать на запрос главного в течении времени 3.5 передачи символа
это чего-то надуманное - минимальная пауза нужна как маркер пакета, а реально пауза может достигать сотен миллисекунд и более. В продвинутых реализация даже поддерживается ответ слейва типа "я занят, пинай позже"


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 15 2009, 22:57
Сообщение #6





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



1) С работой слейва проблем не возникало. Смотрю модбас монитором. Но впринципе, спасибо, можно подправить...
2) Вопрос с 3.5 задержкой связан с готовым устройством (мастером), который при отсутствии ответа генерит ошибки в своей программе...На 2-й запрос - точно... Для "моего" то мастера можно и больше задержки делать..

Сообщение отредактировал vetalxh - Mar 15 2009, 23:00
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Mar 15 2009, 23:06
Сообщение #7


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(vetalxh @ Mar 15 2009, 20:31) *
Вроде проблема с прерываниями, т.к. slave постоянно принимает и отвечает, и не дает master работать. Игрался с запретом прерываний, но ничего не помогло.

Откажитесь от прерываний и сделайте опрос уартов в прерывании от таймера.
А вообще, если включить телепатию, я думаю, у вас грабли. Предположительно нет запрета прерываний от передатчика после того, как данные для передачи закончились.

Цитата(vetalxh @ Mar 15 2009, 20:31) *
Мега162, кварц - 3,6864... Параметры связи обоих 2400-О-1...

Так поднимимите кварц, раза в четыре. Хотя на 2400 нагрузка небольшая.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Mar 15 2009, 23:06
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Вопрос с 3.5 задержкой связан с готовым устройством (мастером)

По спецификации Modbus_over_serial_line время 3.5 Тсимвола (точнее параметр описан там же) не задержка на начало ответа, а МИНИМАЛЬНАЯ ПАУЗА, позволяющая определить конец пакета


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 15 2009, 23:42
Сообщение #9





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



sensor_ua, спасибо, буду думать...
А можно по-подробнее про "Откажитесь от прерываний и сделайте опрос уартов в прерывании от таймера" ?
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Mar 15 2009, 23:51
Сообщение #10


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Организуйте прерывание от таймера и проверяйте в нем готовность приемника и передатчика, наличие данных и места в буфере. Только так сможете управлять последовательностью обработки и приоритетами уартов. Кроме того, это позволит исключить затраты на вызовы уартовских прерываний.
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 16 2009, 00:11
Сообщение #11





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Цитата(Огурцов @ Mar 16 2009, 03:51) *
Организуйте прерывание от таймера и проверяйте в нем готовность приемника и передатчика, наличие данных и места в буфере. Только так сможете управлять последовательностью обработки и приоритетами уартов. Кроме того, это позволит исключить затраты на вызовы уартовских прерываний.

Спасибо...Подумаю над этим тоже
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 16 2009, 09:08
Сообщение #12





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



В прерывании таймера проверять оба уарта? А если по прерыванию я попаду на середину фрейма? Если отказаться от прерываний уартов, то как данные попадут в буфер? Что-то туговато...А кусочком кода никто не поделится? Или алгоритмом хотябы...Спасибо
Go to the top of the page
 
+Quote Post
smac
сообщение Mar 16 2009, 19:37
Сообщение #13


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

Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003



Цитата(vetalxh @ Mar 16 2009, 12:08) *
В прерывании таймера проверять оба уарта? А если по прерыванию я попаду на середину фрейма?

Так там же буферизированный приемник, если TXC не установился - значит нет данных, если установился - значит есть, если при этом DOR сброшен, значит данные валидны.
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 16 2009, 22:26
Сообщение #14





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Короче, думал-думал...Решил обойти все это еще одним способом.

1. Разрешаю прием Slave.
2. Slave получил, обработал, ответил.
3. Slave опять получил, обработал, ответил
...
Так раза 3-4...
6. Запрещаю прием Slave и разрешаю посылку Master.
7. Master послал, принял, обработал.
И опять в начало "Разрешаю прием Slave"

В принципе, такое тоже должно меня устроить, но после того, как запретил прием Slave

CODE
UCSR1B&=~(1<<4); UCSR1B&=~(1<<7)


не могу заново разрешить его разрешить... help.gif
Делаю так

CODE
UCSR1B|=(1<<4); UCSR1B|=(1<<7)


Может нога RX повисла в левом состоянии.. Но я включал подтяжку для нее в начале программы (вместе для мастера и слейва)

CODE
void Setup(void)
{
PORTB=0x04;
DDRB=0x00;
PORTD=0x01;
DDRD=0x00;
}


И еще...Может ли камень уходить в рестарт?? Иногда модбас монитором замечаю, что идет цикл программы, а потом Мастер начинает посылку с 1й...По ходу выполнения программы такое не возможно, т.е. имхо или сброс, или хз что...
Go to the top of the page
 
+Quote Post
defunct
сообщение Mar 17 2009, 00:19
Сообщение #15


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(vetalxh @ Mar 15 2009, 22:31) *
У кого могут быть какие идеи? Такое устройство возможно ли вообще?

А какие проблемы? далаете нормальный протоколо-независимый драйвер UART'а c буферизированным приемом и передачей.
Пишете две функции-задачи по очереди вызываемые в основном цикле программы, одна для обслуживания мастера, вторая для слейва. Никаких Delay_ms и прочий хлам не использовать!! Если слейв требует какого-то реалтайма для выдержки 3.5 символьного интервала, что организуется одним из таймеров, то modbus мастер - это совершенно неприхотливая задача. Выплевывать данные в UART и забирать ответ через скажем 100ms. Вот и вся ее суть.

Цитата
Мега162, кварц - 3,6864... Параметры связи обоих 2400-О-1...

Какой смысл ставить такой медленный кварц, и пользовать только ~20% производительности МК?
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 17 2009, 08:15
Сообщение #16





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Цитата(defunct @ Mar 17 2009, 03:19) *
А какие проблемы? далаете нормальный протоколо-независимый драйвер UART'а c буферизированным приемом и передачей.
Пишете две функции-задачи по очереди вызываемые в основном цикле программы, одна для обслуживания мастера, вторая для слейва. Никаких Delay_ms и прочий хлам не использовать!! Если слейв требует какого-то реалтайма для выдержки 3.5 символьного интервала, что организуется одним из таймеров, то modbus мастер - это совершенно неприхотливая задача. Выплевывать данные в UART и забирать ответ через скажем 100ms. Вот и вся ее суть.

В принципе, я так и сделал. На Slave постоянно включено прерывание по приему. И по завершению приема фрейма посылается ответ... А Master вызывается по прерыванию tim2. И вопрос в том, что Slave перебивает работу Mastera своими прерываниями. И Master посылает все время 1й запрос...А если выключаю устройство, которое подключено к Slave (то есть Slave не работает), Master начинает работать нормально...
А если на время работы Мастера запрещать Слейв, то обратно включить не могу его..Молчит..Может подскажите что?
Цитата(defunct @ Mar 17 2009, 03:19) *
Какой смысл ставить такой медленный кварц, и пользовать только ~20% производительности МК?

Ну это да, согласен, что протупил...Исправлю...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 17 2009, 08:43
Сообщение #17


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(defunct @ Mar 17 2009, 04:19) *
для выдержки 3.5 символьного интервала, что организуется одним из таймеров

Можно вообще обнаглеть и использовать dummy writes при выключенном передатчике. Будет 4. Кунсткамера, но экономненько smile.gif
Go to the top of the page
 
+Quote Post
Палыч
сообщение Mar 17 2009, 08:52
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(vetalxh @ Mar 17 2009, 11:15) *
И вопрос в том, что Slave перебивает работу Mastera своими прерываниями. И Master посылает все время 1й запрос...А если выключаю устройство, которое подключено к Slave (то есть Slave не работает), Master начинает работать нормально...
Очень похоже, что у Slave разрешено какое-то прерывание, а соответствующей процедуры обработки этого прерывания - нет. При этом происходит переход на ячейку с адресом 0, и всё - заново с первой посылки Master'а...
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 17 2009, 10:47
Сообщение #19





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Цитата(Палыч @ Mar 17 2009, 11:52) *
Очень похоже, что у Slave разрешено какое-то прерывание, а соответствующей процедуры обработки этого прерывания - нет. При этом происходит переход на ячейку с адресом 0, и всё - заново с первой посылки Master'а...

Точно. a14.gif
Напутал с регистром UCSR1B. Разрешил прерывание по "завершению передачи" (его вообще в программе не использовал), а прерывание по "очистке регистра передатчика" вообще не включено было.. Как оно вообще работало...хз... biggrin.gif
Спасибо beer.gif
Вечером попробую на устройстве..Отпишусь
Go to the top of the page
 
+Quote Post
sitafern
сообщение Mar 22 2009, 10:13
Сообщение #20


Участник
*

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



Цитата(vetalxh @ Mar 15 2009, 22:31) *
Здравия желаю всем !

Делаю устройство на Mega162 с двумя протоколами modbus.
USART0 - master, посылает всего 11 разных запросов. USART1 - slave, отвечает на эти 11 запросов с некоторыми корректировками. То есть устройство устанавливается между master и slave и общается с ними с нужными мне исправлениями.

В общем, сделал отдельно master и slave - работает, но когда все в целом, то работает только slave, а master зацикливается на 1-й посылке, иногда 2-я проскакивает.

Вроде проблема с прерываниями, т.к. slave постоянно принимает и отвечает, и не дает master работать. Игрался с запретом прерываний, но ничего не помогло.

Также делал чтобы slave принял, ответил, а потом master послал, принял, поочередно, но так теряется слейвом фреймы.

У кого могут быть какие идеи? Такое устройство возможно ли вообще?

Мега162, кварц - 3,6864... Параметры связи обоих 2400-О-1...

Делал такое: модбас на меге 162 в два USARTA, без прерываний (только переполнение таймера для интервалов), работает устойчиво на 115200. Кстати, действительно, почему такая маленькая частота кварца? Подсчёт контрольной суммы "на лету". Написано на ассемблере. Если интересно могу выслать исходник без дешифратора команд и других "прибамбасов".
Только работа USATR'ов. Мой адрес sitafern@ukr.net
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 22 2009, 12:44
Сообщение #21


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(sitafern @ Mar 22 2009, 14:13) *
Если интересно могу выслать исходник без дешифратора команд и других "прибамбасов".

Недавний опыт общения показал: не надо сишников снабжать асмовыми исходниками. Пусть задохнутся. sad.gif
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 22 2009, 16:41
Сообщение #22





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Цитата(_Pasha @ Mar 22 2009, 15:44) *
Недавний опыт общения показал: не надо сишников снабжать асмовыми исходниками. Пусть задохнутся. sad.gif


А к чему это написано??
Go to the top of the page
 
+Quote Post
vetalxh
сообщение Mar 22 2009, 20:17
Сообщение #23





Группа: Новичок
Сообщений: 13
Регистрация: 28-06-08
Пользователь №: 38 608



Утройство сделал. Даже хватило кварца на 3,6864....Всем спасибо за помощь. Отдельное спасибо defunct и Палыч a14.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st June 2025 - 15:02
Рейтинг@Mail.ru


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