Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
12.10.2010, 23:18
|
#11
|
Почётный гражданин KAZUS.RU
Регистрация: 28.02.2010
Сообщений: 2,297
Сказал спасибо: 53
Сказали Спасибо 461 раз(а) в 392 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
скорость нормальная... питание сажается?ну или без земли ...хотя- вряд ли
Последний раз редактировалось OlegNZH; 12.10.2010 в 23:23.
|
|
|
|
12.10.2010, 23:48
|
#12
|
Временная регистрация
Регистрация: 20.05.2010
Сообщений: 64
Сказал спасибо: 8
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Все мимо... все до безобразия просто.
Подсказываю, в проше косячок.
|
|
|
|
13.10.2010, 00:05
|
#13
|
Временная регистрация
Регистрация: 20.05.2010
Сообщений: 64
Сказал спасибо: 8
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Не буду мучать, тем паче время позднее, а завтра дорога дальняя.
Первый косячок:
Забыл LED_DDR = 0xff;
Второй поинтереснее, и всплыл только после первого:
Было:
Код:
|
USART_SendChar('O'); //отвечаем компу "Ok "
USART_SendChar('k');
LED_PORT=LED_PORT & ~(1‹‹send);
LED_PORT=LED_PORT & ~(1‹‹LED2);
LED_PORT=LED_PORT & ~(1‹‹LED1);
__delay_cycles(10000000); |
А надо:
Код:
|
USART_SendChar('O'); //отвечаем компу "Ok "
USART_SendChar('k');
__delay_cycles(10000000);
LED_PORT=LED_PORT & ~(1‹‹send);
LED_PORT=LED_PORT & ~(1‹‹LED2);
LED_PORT=LED_PORT & ~(1‹‹LED1); |
Во втором косяке передатчик ADM'a отключался раньше, чем отправлялись данные запиханные в буфер USART'a.
|
|
|
|
13.10.2010, 00:54
|
#14
|
Вид на жительство
Регистрация: 21.08.2007
Сообщений: 318
Сказал спасибо: 12
Сказали Спасибо 67 раз(а) в 61 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Пользуйте лучше
while (!(UCSRA & (1 ‹‹ TXC)));
|
|
|
|
13.10.2010, 09:51
|
#15
|
Временная регистрация
Регистрация: 20.05.2010
Сообщений: 64
Сказал спасибо: 8
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Сообщение от Cybermaker
|
Пользуйте лучше
while (!(UCSRA & (1 ‹‹ TXC)));
|
Спасибо, возьму на заметку.
|
|
|
|
13.10.2010, 11:45
|
#16
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Сообщение от DimanVIP
|
Такой мелкий косячок.....
Ну что господа, кто угадает в чем был косячок?
|
Да у тебя вся программа - один большой косячёк.
1) После приёма байта - переключается на передачу и задержка, о которой уже писали. Таким образом, всё что будет послано в это время - уйдёт в бан.
2) Мощный буфер на 1 символ. Посмотри хотя бы как другие реализовывали. Почитай что есть кольцевой буфер или вообще буфер. Почитай как с 485 работать. (3 прерывания должно быть. Приём байта - пауза - передача ответа - завершение передачи (переключение передатчика) ).
3) Где вы видели распознавание по ненулевому байту. Как вариант конечно ... Обычно используются спецпротоколы. Почитай что такое байтстаффинг, CRC, пакет, MODBUS, Wake-up.
|
|
|
|
13.10.2010, 17:28
|
#17
|
Временная регистрация
Регистрация: 20.05.2010
Сообщений: 64
Сказал спасибо: 8
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Сообщение от SasaVitebsk
|
Да у тебя вся программа - один большой косячёк.
1) После приёма байта - переключается на передачу и задержка, о которой уже писали. Таким образом, всё что будет послано в это время - уйдёт в бан.
2) Мощный буфер на 1 символ. Посмотри хотя бы как другие реализовывали. Почитай что есть кольцевой буфер или вообще буфер. Почитай как с 485 работать. (3 прерывания должно быть. Приём байта - пауза - передача ответа - завершение передачи (переключение передатчика) ).
3) Где вы видели распознавание по ненулевому байту. Как вариант конечно ... Обычно используются спецпротоколы. Почитай что такое байтстаффинг, CRC, пакет, MODBUS, Wake-up.
|
Эта проша нужна была только для того чтобы протестить работу 485 интерфейса. Ведь нельзя же просто соединить вместе Rx и Tx.
Если бы я сразу нагородил весь "огород", то еще, наверное, долго бы искал ошибку.
Естественно при создании реального устройства всё описанное будет присутствовать + еще кое что.
|
|
|
|
17.10.2010, 14:08
|
#18
|
Временная регистрация
Регистрация: 20.05.2010
Сообщений: 64
Сказал спасибо: 8
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
Добавил к своему приемнику кольцевые буферы. Прикрутил LCD.
Начал разрабатывать протокол. Пакет примерно такой:
0х55 | байты данных(8) | контрольная сумма.
Споткнулся вот на чем: В начале приема ловится 0x55, включается запись остальных байтов в буфер. Когда счетчик считанных байтов = 8, пакет обрабатывается (пока отображается на LCD). Но получается так, что отображается и 0x55 (U).
Код:
|
//прерывание по завершению приема
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_my(void)
{
if (UDR == 'U')
{
stRec = 1; // флаг начала записи в буфер
USART_FlushRxBuf(); // очистка приемного буфера
}
else
{
if (stRec == 1)
{
if (rxCount ‹ SIZE_BUF) //если в буфере еще есть место
{
usartRxBuf[rxBufTail] = UDR; //считать символ из UDR в буфер
rxBufTail++; //увеличить индекс хвоста приемного буфера
if (rxBufTail == SIZE_BUF) rxBufTail = 0;
rxCount++; //увеличить счетчик принятых символов
if (rxCount == 8) stRec = 0;
}
}
} |
После длительных танцев с бубном удалось это победить. Работая через временную переменную.
Код:
|
//прерывание по завершению приема
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_my(void)
{
char temp;
temp = UDR;
if (temp == 'U')
{
temp = 0;
stRec = 1;
USART_FlushRxBuf();
//rxCount = 0;
//rxBufTail = 0;
}
else
{
if (stRec == 1)
{
if (rxCount ‹ SIZE_BUF) //если в буфере еще есть место
{
usartRxBuf[rxBufTail] = temp; //считать символ из UDR в буфер
rxBufTail++; //увеличить индекс хвоста приемного буфера
if (rxBufTail == SIZE_BUF) rxBufTail = 0;
rxCount++; //увеличить счетчик принятых символов
if (rxCount == 8) stRec = 0;
}
}
} |
Но почему так, я не понял.... Может сможет кто объяснить, а то очень не хочется оставлять пробелы в знаниях.
Пробовал и просто выгружать UDR в неиспользуемую переменную. Не помогало (возможно компилятор IAR оптимизировал это место).
Очучение, что при первом входе в прерывании, и сравнении UDR, флаг прерывания не сбрасывался, и прерывание вызывалось повторно.
З.Ы. Знаю, что если 0x55 придет в середине пакета будет косяк и что проверка CRC пока не реализована. Просто на чем пока запнулся, не хочется ошибку запускать.
З.Ы.Ы. Никто не может подсказать, где очень толково расписана работа с битами четности. Хочется иметь и хардварную защиту, но попытался я это сделать у себя... И ничего не получилось. Настраивал МК как положено, но данные от компа он принимал только если те были в обычном виде (без битов четности).
|
|
|
|
18.10.2010, 10:10
|
#19
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
1. Кольцевой буфер на то и кольцевой, чтобы его не очищать. В любой момент у тебя есть указатель на начало и на конец пакета.
2. ![Улыбка](images/smilies/icon_smile.gif) Поясни. Зачем вот это вот. if (rxCount ‹ SIZE_BUF). Короче - какой-то бред. ![Улыбка](images/smilies/icon_smile.gif)
При фиксированной длине пакета достаточно только
Код:
|
if (stRec)
{
usartRxBuf[rxBufTail++] = UDR; //считать символ из UDR в буфер
приемного буфера
if (rxBufTail == SIZE_BUF) rxBufTail = 0;
rxCount = (rxCount++)&7;
if (rxCount)
{
stRec = FALSE;
RxDone = TRUE;
}
} |
3. 55 скорее всего не в начале записывается а в конце.
4. При фиксированной длине пакета можно работать не по байту метке, а по паузе перед началом пакета.
5. Если всё же работать по метке, то почитай байт-стаффинг - поймёшь как выдирать 55 из середины пакета.
6. В AVR флаг прерывания скидывается автоматически при чтении UDR.
|
|
|
Сказали "Спасибо" SasaVitebsk
|
|
|
18.10.2010, 23:14
|
#20
|
Временная регистрация
Регистрация: 20.05.2010
Сообщений: 64
Сказал спасибо: 8
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Проблема с USB > RS-485 > AVR
1. На том этапе это было нужно. Сейчас этого уже нет.
2. Полностью согласен. Тот код просто не давал писать в буфер, когда он полон. Сейчас этого нет.
3. Нет, 55 именно в начале. Комбинация 0 и 1 дает хорошую проверку на синхронизацию.
4. По мне так проще отловить этот байт-метку.
5. Не читал, но код полностью написан и сейчас обкатывается.
6. Я бы сказал должен скидываться. Но не всегда скидывается. Хотя, как я уже писал, это, наверное, от оптимизации компилятора.
Вот код прерывания который сейчас обкатываю:
Код:
|
char temp;
temp = UDR;
if (stRec == 1)
{
usartRxBuf[rxBufTail++] = temp; //считать символ из UDR в буфер
if (rxBufTail == SIZE_BUF) rxBufTail = 0;
rxCount++; //увеличить счетчик принятых символов
if (rxCount == 8)
{
UCSRB = UCSRB | (0‹‹RXEN); //запрет приема
stRec = 0;
}
}
else
if (temp == 'U')
{
stRec = 1;
} |
Обкатываю так:
На компе накатал прожку для работы с COM. Выставил 128000. И погнал байты по такому алгоритму (DELPHI):
Код:
|
CRC := 0;
for a1 := 33 to 127 do
for a2 := 33 to 127 do
for a3 := 33 to 127 do
for a4 := 33 to 127 do
for a5 := 33 to 127 do
for a6 := 33 to 127 do
for a7 := 33 to 127 do
begin
arrWrite[0] := 85;
arrWrite[1] := a1;
arrWrite[2] := a2;
arrWrite[3] := a3;
arrWrite[4] := a4;
arrWrite[5] := a5;
arrWrite[6] := a6;
arrWrite[7] := a7;
for i := 1 to 7 do
CRC := CRC + arrWrite[i];
arrWrite[8] := CRC; |
Сейчас уже на втором лимоне переданных байт крутится ни одного косяка замечено не было. А числа взял такие, чтобы просто визуально на LCD наблюдать можно было.
Ежели CRC_error, байт шлется повторно. Проверял, замыкая проводки Rx-Tx. Правда после примерно 10 ошибок прога на ПК зависает наглухо. Почему, пока не разобрался.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:25.
|
|