Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Удаленная работа
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 17.05.2018, 01:35  
parovoZZ
Вид на жительство
 
Регистрация: 15.11.2010
Сообщений: 407
Сказал спасибо: 29
Сказали Спасибо 15 раз(а) в 11 сообщении(ях)
parovoZZ на пути к лучшему
По умолчанию Указатели, чтоб их!

Есть такой говнокод

Код:
uint8_t SPI_ReadByte(uint8_t data)
{
	//... Отправляем байт
	SPI_WriteByte(data);

	//... Принятый байт возвращаем
	return reg_SPI; 
}

	//... Отправить и получить несколько байт по SPI. Принятые данные начинаются с data 
void SPI_ReadArray(uint8_t num, uint8_t *data)
{
	while(num--)
	{      
		*data++ = SPI_ReadByte(*data); 
	}
}

Вызываю функцию так


Код:
	//... Функция приема данных. Функция возвращает длину сообщения, 
               // ... rx_data указывает на начало сообщения
uint8_t nRF_Receive(uint8_t *rx_data)
{
	uint8_t length;

	nRF_SELECT();	
								
	SPI_WriteByte(nRF_R_RX_PL_WID);			// Запрашиваем длину сообщения
	length = SPI_ReadByte(nRF_NOP);			// Читаем длину сообщения

	SPI_ReadArray(length, rx_data);				// Читаем сообщение

	nRF_DESELECT();

	return length;
}
И получаю предупреждение
Цитата:
операция над «данными» может быть неопределенной
от компилятора на строчку

Код:
*data++ = SPI_ReadByte(*data);

А если вызвать так

Код:
	//... Функция приема данных. Функция возвращает длину сообщения, rx_data указывает на начало сообщения
uint8_t nRF_Receive(uint8_t *rx_data)
{
	uint8_t length;

	nRF_SELECT();	
								
	SPI_WriteByte(nRF_R_RX_PL_WID);			// Запрашиваем длину сообщения
	length = SPI_ReadByte(nRF_NOP);			// Читаем длину сообщения

	uint8_t Buf[length];

	SPI_ReadArray(length, Buf);				// Читаем сообщение

	nRF_DESELECT();

	rx_data = Buf;

	return length;
}
то всё нормуль.

Что-то с ходу не понимаю, что не нравится компилятору? Или я болван, или спать пора =)
Реклама:
parovoZZ вне форума  
Непрочитано 17.05.2018, 08:03  
Исбанни
Заблокирован
 
Регистрация: 21.04.2018
Сообщений: 176
Сказал спасибо: 1
Сказали Спасибо 65 раз(а) в 52 сообщении(ях)
Исбанни на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Эмм... Чето вы написали какую-то дичь. Утро вечера мудреннее. Проспитесь и попробуйте снова
Исбанни вне форума  
Непрочитано 17.05.2018, 08:47  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 11,669
Сказал спасибо: 1,016
Сказали Спасибо 3,786 раз(а) в 2,081 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Код:
*data++ = SPI_ReadByte(*data);
Вы сначала инкрименируете указатель, а потом пишите в него данные, полученные из функции. А надо наоборот:
Код:
*data = SPI_ReadByte(*data++);
У себя я не определяю функции интерфейсов в явном виде. Это заставляет жестко привязаться к железу и с другим железом использование библиотеки становится затруднительно. Поэтому интерфейсы определяю в отдельных функциях:
Код:
	uint8_t (*Write)(uint8_t reg, uint8_t * buf, uint8_t size);
	uint8_t (*Read) (uint8_t reg, uint8_t * buf, uint8_t size);
Для интерфейсов типа SPI, I2C и им подобных эти функции имеют один и тот же вид. Таким образом, мультиинтерфейсные чипы типа MFRC631 можно подключать как душе угодно без изменения файлов библиотек.
Функции можно определить локально внутри библиотеки или привязать через структуру. Как вам удобнее.

Последний раз редактировалось Easyrider83; 17.05.2018 в 09:00.
Easyrider83 вне форума  
Непрочитано 17.05.2018, 09:30  
eddy
Почётный гражданин KAZUS.RU
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,553
Сказал спасибо: 90
Сказали Спасибо 619 раз(а) в 434 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Чтобы такой жути не было, я бы функцию переделал так (возвращает 0, если все ОК):
Код:
uint8_t SPI_ReadByte(uint8_t *data)
{
	//... Отправляем байт
	if(!SPI_WriteByte(*data)) return 1; // ошибка записи - возврат 1
	//... Принятый байт возвращаем
        *data = reg_SPI;
	return 0; 
}
Потому как операции вида *X++ = f(X) не определены: может сначала инкрементироваться указатель, а может, как оно и ожидалось, сначала выполниться функция.
__________________
https://github.com/eddyem/
http://stackexchange.com/users/2227375/eddy-em
http://eddy-em.livejournal.com/
In the world, only two things are the worst: Windows and Poettering.
eddy вне форума  
Непрочитано 17.05.2018, 09:32  
eddy
Почётный гражданин KAZUS.RU
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,553
Сказал спасибо: 90
Сказали Спасибо 619 раз(а) в 434 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Сообщение от Easyrider83 Посмотреть сообщение
Поэтому интерфейсы определяю в отдельных функциях
А если одновременно работают CAN, USART, USB, SPI и I2C?
__________________
https://github.com/eddyem/
http://stackexchange.com/users/2227375/eddy-em
http://eddy-em.livejournal.com/
In the world, only two things are the worst: Windows and Poettering.
eddy вне форума  
Непрочитано 17.05.2018, 10:07  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 11,669
Сказал спасибо: 1,016
Сказали Спасибо 3,786 раз(а) в 2,081 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Сообщение от eddy Посмотреть сообщение
А если одновременно работают CAN, USART, USB, SPI и I2C?
Наступает эйфория
Easyrider83 вне форума  
Непрочитано 17.05.2018, 10:34  
parovoZZ
Вид на жительство
 
Регистрация: 15.11.2010
Сообщений: 407
Сказал спасибо: 29
Сказали Спасибо 15 раз(а) в 11 сообщении(ях)
parovoZZ на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Сообщение от eddy Посмотреть сообщение
Потому как операции вида *X++ = f(X) не определены: может сначала инкрементироваться указатель, а может, как оно и ожидалось, сначала выполниться функция.
Это от компилятора зависит или от погоды на Марсе?

Цитата:
У себя я не определяю функции интерфейсов в явном виде. Это заставляет жестко привязаться к железу и с другим железом использование библиотеки становится затруднительно. Поэтому интерфейсы определяю в отдельных функциях
Видимо это удобно программисту, но неизбежно влечет затраты памяти.
parovoZZ вне форума  
Непрочитано 17.05.2018, 10:35  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 11,669
Сказал спасибо: 1,016
Сказали Спасибо 3,786 раз(а) в 2,081 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Затраты памяти - это лепить printf туда, где он не нужен. А два указателя - это мелочи.
Easyrider83 вне форума  
Непрочитано 17.05.2018, 10:40  
dgrishin
Вид на жительство
 
Регистрация: 12.02.2013
Сообщений: 360
Сказал спасибо: 8
Сказали Спасибо 64 раз(а) в 63 сообщении(ях)
dgrishin на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Сообщение от Easyrider83 Посмотреть сообщение
*data++ = SPI_ReadByte(*data);
Вы сначала инкрименируете указатель
ИМНО здесь инкремент и запись не в указатель, а в переменную по этому указателю (есть операция разыменования *)
dgrishin вне форума  
Непрочитано 17.05.2018, 12:30  
sat_art
Прописка
 
Регистрация: 27.11.2007
Сообщений: 248
Сказал спасибо: 8
Сказали Спасибо 17 раз(а) в 15 сообщении(ях)
sat_art на пути к лучшему
По умолчанию Re: Указатели, чтоб их!

Компилятор должен ругаться в обоих случаях.

*data++ - постинкриментирование прочитанных данных (переменной по указателю), а не указателя. Что не есть правильно.

Код:
*data = SPI_ReadByte(*data);
data++;
Так правильнее будет.
sat_art вне форума  
Сказали "Спасибо" sat_art
mike-y-k (17.05.2018)
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Указатели и EEPROM 24c16 + stm32 miwutka Embedd С 25 07.01.2018 16:36
Как измерить растояние, чтоб дешево и сердито? NA1S Измерительное оборудование 38 30.11.2010 11:06
Хочу, чтоб мой комп меня будил koks81 Делимся опытом 33 03.05.2010 13:59
Косвеная адресация и указатели CERGEI1982 Микроконтроллеры, АЦП, память и т.д 7 08.09.2007 18:43
[Решено] Как мне нопаять схему, чтоб работало. Аудиотехника 3 21.05.2005 14:16


Часовой пояс GMT +4, время: 02:05.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot