Jump to content

    

Опрос прибора при помощи ATmega128 и MAX485.

7 минут назад, aaarrr сказал:

1. Реализация кольцевого буфера корявая. Но гораздо менее корявая, чем остальной код.

Буду работать дальше.

7 минут назад, aaarrr сказал:

2. К чему весь этот ужас с switch() вместо передачи в цикле из массива?

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

Share this post


Link to post
Share on other sites
12 minutes ago, Stolbov said:

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

Выше уже указали причину.

 

Не может это не работать:

const uint8_t databuffer[8] = {0x01,0x04,0x00,0x06,0x00,0x02,0x91,0xCA};
int i;

for(i = 0; i < sizeof(databuffer); i++)
	uart_0_send(databuffer[i]);

 

Share this post


Link to post
Share on other sites
1 hour ago, Stolbov said:

#define BUFFER_SIZE 18 //Максимальный размер кольцевого буфера (на две принятые посылки)

#define BUFFER_MASK (BUFFER_SIZE - 1) //Маска обнуления

В том месте, где вы брали кольцевой буфер, не было написано большими буквами, что его размер обязательно должен быть кратен степени двойки?

В противном случае "магия" с маской работает совсем не так, как должна.

 

И вот это безобразие:

	while (1)
	{

		if(get_data() == 0) //Если функция вернула 0, значит, в массиве нет новых данных
		{
			asm("nop");     //И тогда мы ничего не делаем
		}
		else if(get_data() == 1) //Если функция вернула 1, значит, какие-то данные всё же получены
		{
			read_byte_from_ring(local_buffer,index_number()); //Читаем полученные от вольтметра данные в local_buffer
		}
		else
		{
			break;
		}
		uart_1_send(local_buffer[0]);   //Отсылаем данные из local_buffer на ПК
	}

 

Должно быть как-то так:

	while (1)
	{
		if(get_data() == 1) //Если функция вернула 1, значит, какие-то данные всё же получены
		{
	            char local; 		
                    read_byte_from_ring(&local, 1); //Читаем полученные от вольтметра данные в local_buffer
                    uart_1_send(local); //Отсылаем данные из local_buffer на ПК 
		}
	}
Edited by esaulenka
чёртов редактор...

Share this post


Link to post
Share on other sites

Из

void call_voltage() //Отправка сообщения на вольтметр

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

 

Share this post


Link to post
Share on other sites
2 часа назад, aaarrr сказал:

Не может это не работать:

Вы оказались правы, это не может не работать. Я всего лишь увеличил паузу после DDRE |= (1<<PORTE5); в main() до двух 2000ms, и всё заработало. От ужасного и чудовищного switch'а избавился.

1 час назад, esaulenka сказал:

В том месте, где вы брали кольцевой буфер, не было написано большими буквами, что его размер обязательно должен быть кратен степени двойки?

Было написано, и в том месте на этом было заострено внимание. Почему я напортачил на ровном месте - ума не приложу. Сейчас разбираюсь, почему не происходит отсылка данных из условия if(get_data() == 1) (я имею ввиду приведённый Вами кусочек кода). 

 

Share this post


Link to post
Share on other sites
2 hours ago, Stolbov said:

. . . . Я всего лишь увеличил паузу после DDRE |= (1<<PORTE5); в main() до двух 2000ms, и всё заработало. . . .

Это "симптоматическое" лечение. Тем более в таких "особо крупных" размерах (2 сек).

Возможно Вам имеет смысл использовать трансивер RS485 с автоопределением прием/передача, на первом этапе. 

MAX13487EESA-T_C18347.pdf

 

Share this post


Link to post
Share on other sites
3 hours ago, Stolbov said:

Я всего лишь увеличил паузу после DDRE |= (1<<PORTE5);

Какое-то странное лечение. По-хорошему, никаких пауз не надо. Если паузу убрать, переходник в компьютер отправленные байты видит?

Вольтметр как запитан? Может, он просто запускается эти 1-2 секунды, а вы ему постоянно питание дёргаете?

 

3 hours ago, Stolbov said:

Сейчас разбираюсь, почему не происходит отсылка данных из условия

На первый взгляд, правильно всё написано...

Предложения по отладке:

- в прерывание на приём байта добавьте пересылку его в соседний порт. Скорость этого UART1 лучше поставить побольше (например, 115200), чтоб не мешал своими задержками.

- также можно через некоторый промежуток (например, через секунду) после обмена с вольтметром отправить в этот UART1 всю интересующую информацию -  в первую очередь, IndexStart / IndexEnd.

- также ооочень рекомендую отладчик. Называется AVR JTAG ICE. Оригинал стоит каких-то неразумных, на мой взгляд, денег, но китайские клоны продаются за копейки (порядка 200 рублей). Правда, как работают клоны, я не знаю. "Пошагать" по программе у вас не получится (т.к. задействован вольтметр, а он ждать не будет), но посмотреть в любой момент значения переменных, да и за несколько секунд обновить программу - это очень упрощает работу.

Share this post


Link to post
Share on other sites

Перед тем, как закрыть тему, я хотел бы подвести некоторые итоги.

Нет, свою задачу я так и не решил. Пару раз я переписывал свой код, и в прошлую пятницу добился его работоспособности (AVR'ка опрашивала вольтметр раз в пару-секунд и стабильно получала ответ). Не было ни каких сомнительных задержек, и прочих "костылей". В начале этой недели всё внезапно прекратило работать. Ничего не менялось. Просто включил свою отладочную плату во вторник утром, а в мониторе, который я подключил параллельно вольтметру, либо ничего нет, либо передаётся максимум один байт сообщения. Почему это происходит, и как мне найти решение - я не знаю. На одном из форумов прочёл, что при построении таких систем микроконтроллер следует тактировать от внешнего кварца, но в своём случае я не заметил никаких улучшений. Попробую использовать другие микросхемы-аналоги MAX485 (SN75176AP, к примеру). Может быть поможет.

В любом случае, всем спасибо за участие. Как только я доберусь до правильного решения, я обязательно его здесь опубликую. :bye:

 

Edited by Stolbov

Share this post


Link to post
Share on other sites
On 11/7/2019 at 11:11 AM, Stolbov said:

Перед тем, как закрыть тему, ...

AVR очень неудачный выбор (на данное время, за 10 лет назад разговора нет), по причине отсутствия нормальных (доступных и недорогих) средств аппаратной отладки. Возьмите надежный-удобный компилятор (для меня это IAR или Keil) и аппаратный отладчик-программатор. Получите нормальную среду для разработки-отладки и сэкономите массу времени изучив новый нормальный инструмент для работы и процессор (например ARM, к томуже ресурсы даже у "младших" ARM не сравнить с AVR). Тратьте время на изучение того, что перспективно и удобно, а не поиск/психоанализ "черного ящика" (это "аналитическая" отладка софта и программы без JTAG). Не в обиду фанатов AVR, IMHO.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now