Прием rs232 без UART на AVR - сети не ловят.

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
AndyKorg
Встал на лапы
Сообщения: 93
Зарегистрирован: Пт янв 07, 2011 08:52:08
Откуда: Санкт-Петербург

Прием rs232 без UART на AVR - сети не ловят.

Сообщение AndyKorg »

Дорогие любители рыбы!
Помогите поймать золотую рыбку, ну или хотя бы малька. :)
Требуется принимать на ATMega328 поток байт по протоколу RS232 на скорости 9600. Причем штатный UART занят своими делами и его трогать нельзя.
Вот накропал шедевр, а он не пашет. Может кто чего подскажет?

Код: Выделить всё

#include <avr\io.h>
#include <util/delay.h>

#define BIT_DELAY 104 //Это длительность бита на скорости 9600 в микросекундах

unsigned char RxByte(void){//Функция которая принимает битики на лапе PB1

unsigned char buf = 0, //Холодильник для рыбы, он же буфер куда битики принимаются
     i;//Просто счетчик

	while(1){
		buf = 0;
		while(PINB & 2);//Ждем кода приплывает рыба-лоцман, он же старт-бит
		_delay_us(BIT_DELAY/4);//Обождем 1/4 от длительности бита
		for (i = 7; i!=0; i--){//Как говорится - пошла вода по трубам! 
			_delay_us(BIT_DELAY);//Обождем еще длительность бита
			if (PINB & 2)//Как оно? рыба или пусто?
				buf |= 0b10000000;//Есть рыбка
			else
				buf &= 0b01111111;//Нету ничего
			buf >>= 1;//Пихаем в холодильник, то бишь в буфер
		}
                //Все! Косяк прошел, проверим замыкающую акулу 
		_delay_us(BIT_DELAY);//через длительность бита
		if (PINB & 2)//Акула проплыла, усе нормально. Холодильник закрываем
			return(buf);
		}
}
Так вот. Косяк байт представляет собой четкую последовательность:
символ "R" - начало тела косяка
три байта цифр - собственно промысловая рыба
и 0x0D - хвостик косяка
А принимается вот что: 0x1f, 0x4f, 0x68, 0x68, 0x30,, 0x3, 0x, 0x72, 0x36, 0x3, 0x19, 0x0 и т.д.
Че-то я уже измучился ловить не то, что надо. Гуглосетью забредал - ничего толкового не выловил.
Помогите пожалуйста найти косяк!
Последний раз редактировалось AndyKorg Ср мар 16, 2011 11:30:51, всего редактировалось 1 раз.
Реклама
Аватара пользователя
-==MAXCELERON==-
Встал на лапы
Сообщения: 96
Зарегистрирован: Сб авг 15, 2009 07:31:56
Откуда: г. Кемерово

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение -==MAXCELERON==- »

Чтобы выполнить задержку с помощью переменной нужно делать ее через дополнительную функцию задержки:

delay(x); // делаем задержку продолжительностью x мкс


void delay(int us){

for(;us;us--)

_delay_us(1);
}
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18592
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение ARV »

мне кажется, у вас не получается синхронизироваться... т.е. ваш цикл ожидания "косяка" ловит не старт-бит, а один из битов передаваемого байта, и далее пошло уже все шиворот-навыворот.

если известно, что пакет всегда начинается с символа 'R', то надо терпеливо дожидаться его приема для синхронизации. т.е. алгорит такой примерно:

1. принимаем байт
2. байт == 'R' ? если да - переходим к приему пакета
3. если нет, то принимаем (пропускаем) 1 БИТ
4. переходим к п.1

этот алгоритм будет пропускать кучу пакетов, пока наконец не поймает синхронизацию, после чего уже дело пойдет нормально. смысл в том, что каждый новый пакет принимается с пропуском 1 бита перед ним - рано или поздно (можете посчитать максимальное время синхронизации) программа поймает именно первый бит начала пакета и далее все пойдет как по маслу.

эта процедура должна делаться 1 раз - в начале приема, или каждый раз после длительного перерыва в приеме пакетов.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
AndyKorg
Встал на лапы
Сообщения: 93
Зарегистрирован: Пт янв 07, 2011 08:52:08
Откуда: Санкт-Петербург

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение AndyKorg »

ARV писал(а):.....
1. принимаем байт
2. байт == 'R' ? если да - переходим к приему пакета
3. если нет, то принимаем (пропускаем) 1 БИТ
4. переходим к п.1
.......
Эх, я так делал. Но увы, в течение получаса ни разу не приходило "R". Где то глубже в алгоритме плавает моя рыбка.
-==MAXCELERON==- писал(а):.....
Чтобы выполнить задержку с помощью переменной нужно делать ее через дополнительную функцию задержки:.......
дык как раз препроцессор и отдает компилятору строку после обработки:
_delay_us(104); или _delay_us(26);
Так что не вижу смысла в такой подстановке.
Реклама
Эиком - электронные компоненты и радиодетали
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение uk8amk »

1)Кажись у вас код кривой, сначала так:
buf |= 0b10000000;//Есть рыбка
затем вот так:
buf >>= 1;//Пихаем в холодильник, то бишь в буфер
Распишите в линейный код. Что произошло на восьмой итерации цикла?
2)Это полный код программы или только прилизанная его часть для данного случая? Я имею в виду что у вас могуть быть обработчики прерываний которые влияют на длительность выполнения _delay_us(BIT_DELAY); Если есть свободный таймер, то положите на него функцию захвата бита.
Реклама
AndyKorg
Встал на лапы
Сообщения: 93
Зарегистрирован: Пт янв 07, 2011 08:52:08
Откуда: Санкт-Петербург

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение AndyKorg »

uk8amk писал(а):1)Кажись у вас код кривой, сначала так:
buf |= 0b10000000;//Есть рыбка
затем вот так:
buf >>= 1;//Пихаем в холодильник, то бишь в буфер
Распишите в линейный код. Что произошло на восьмой итерации цикла?
Да действительно, одна итерация лишняя. Вы правы, спасибо за подсказку. Подправил, но не помогло :(
uk8amk писал(а): 2)Это полный код программы или только прилизанная его часть для данного случая? Я имею в виду что у вас могуть быть обработчики прерываний которые влияют на длительность выполнения _delay_us(BIT_DELAY); Если есть свободный таймер, то положите на него функцию захвата бита.
[/quote]
К сожалению все запрещено - таймеры, прерывания и прочее безобразия. Так что на это грешить не могу. Таймер кончено задействую в конченой реализации, но я думаю что ошибка в плюс минус 5 микросекунд (на частоте 16Мгц это чертова туча команд даже если используются прерывания) не должна влиять на косяк, рыба то толстая, аж в 104 микросекунды.
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение uk8amk »

Итерация то не лишняя, а вот один сдвиг как раз лишний. Попробуйте тупо записать:
if(PINB.2) buf=0x01;
delay_us(BIT_DELAY);
if(PINB.2) buf|=0x02;
belay_us(BIT_DELAY);
и т.д., может вскроется какая-нибудь ошибка которую мы из вида упускаем...
Еще как вы определяете значение которое захватили, выводите куда-то, на LCD например, есть уверенность что там тоже без косяков?

Правильно ли выставлена тактовая частота процессора для функций delay.h?

Upd:
Обновив код вы выкинули одну итерацию а вместе с ней и прием восьмого бита. У вас формат кадра 8N1? Тогда после цикла добавить:
if(PINB.2) buf|=0x80;
delay_us(BIT_DELAY);
AndyKorg
Встал на лапы
Сообщения: 93
Зарегистрирован: Пт янв 07, 2011 08:52:08
Откуда: Санкт-Петербург

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение AndyKorg »

uk8amk писал(а):Итерация то не лишняя, а вот один сдвиг как раз лишний. Попробуйте тупо записать:
....
Upd:
Обновив код вы выкинули одну итерацию а вместе с ней и прием восьмого бита. У вас формат кадра 8N1? Тогда после цикла добавить:
if(PINB.2) buf|=0x80;
delay_us(BIT_DELAY);
Ах ты черт! Точно! Спасибо за наводку! Вечером попробую - отпишусь.
uk8amk писал(а): Правильно ли выставлена тактовая частота процессора для функций delay.h?
Насчет этого нет сомнений - проверено генерацией меандра.
AndyKorg
Встал на лапы
Сообщения: 93
Зарегистрирован: Пт янв 07, 2011 08:52:08
Откуда: Санкт-Петербург

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение AndyKorg »

Не выходит каменный цветок! :(

Код: Выделить всё

#include <avr\io.h>
#include <util/delay.h>

#define BIT_DELAY 104

unsigned char RxByte(void){

unsigned char buf = 0, i;

	while(1){
		buf = 0;
		while(PINB & 2);
		_delay_us(BIT_DELAY/4);
		for (i = 0; i!=8; i++){
			buf >>= 1;
			buf &= 0x7f;
			_delay_us(BIT_DELAY);
			if (PINB & 2)
				buf |= 0x80;
		}
		_delay_us(BIT_DELAY);
		if (PINB & 2)
			return(buf);
		}
}

Все равно гонит какие-то байты непонятные.
Буду еще головой думать. Может кто еще чего подскажет?
phanis
Вымогатель припоя
Сообщения: 513
Зарегистрирован: Сб фев 19, 2011 18:04:08
Откуда: Татарстан, пос. Актюбинский
Контактная информация:

Re: Прием rs232 без UART на AVR - сети не ловят.

Сообщение phanis »

Код: Выделить всё

#include <avr\io.h>
#include <util/delay.h>

#define BIT_DELAY 104

unsigned char RxByte(void){

unsigned char buf = 0, i;
PORTB |= 2; // подтяжка к +
DDRB |=1; // какой нибудь выход здесь PORTB0
	while(1){
		buf = 0;
		while(PINB & 2);
		_delay_us(BIT_DELAY/4);
		for (i = 0; i!=8; i++){
			buf >>= 1;
			buf &= 0x7f;
                         PORTB &= 0xFE; //PORTB0 в ноль
			_delay_us(BIT_DELAY);
                        PORTB |= 0x01 ;//PORTB0 в единичку 
			if (PINB & 2)
				buf |= 0x80;
		}
		_delay_us(BIT_DELAY);
		if (PINB & 2)
			return(buf);
		}
}

Отправляем 0xAA( 10101010 ) или 0x55 ( 01010101 ) по ком порту в мк
В это время двухканальным осциллографом (можно в протеусе) наблюдаем за импульсами на PB0 PB1
Т.е определяем на сколько все синхронно работает..
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»