Как решить проблему с Предупреждением : указатель из целого числа без приведения

Решил сделать окончательную версию КОТОФОНА (домофон для котов) и для этого собираю все на 1 проц и на одну плату. При написании кода столкнулся с предупреждением которое не могу победить : Предупреждение передача аргумента 1 ‘eeprom_update_dword’ преобразует указатель из целого числа без приведения . Много чего пробвал реализовать но видимо не все - удачных вариантов небыло. Если отбросить все лишнее по текту кода - то выглядит так ( но тоже не помогло):

//                ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ //
 
 
uint16_t Adress1=0x0100;
uint16_t Adress2=0x0120;
uint16_t Adress3=0x0140;
 
                           ///  ОСНОВНОЙ КОД///
 
if(a==0){eeprom_update_dword(Adress1,IndividID);}     
if(eeprom_read_dword(Adress1==IndividID){ Open_Door();} 

Планировалось, что так я сохраняю в eeprom “ключи” разрешенные для прохода животных. Сработка открытия двери по сравнению текущего ключа с ключём в памяти, решил что 2-3 ключа будет достаточно, а хранение в eeprom начинаю с адреса 0x0100, а далее 0х0120 и 0х0140. - т.е. с шагом по 32 бита

(uint32_t	IndividID;									// 32-разрядная переменная для хранения индивидуального кода)

PS. кому интересно, как работает бета-версия (отпахала целый сезон с весны по осень 2023г) https://cloud.mail.ru/public/5niF/84ioDobrg

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

/********************************************************************************************************************************************
	ДВЕРЬ	- собрал все - нужно проверить сохранение в памяти		СЧИТЫВАНИЕ RFID МЕТОК СТАНДАРТА EM-MARINE НА 125 кГц И ПЕРЕДАЧА 5 БАЙТ ID-КОДА ЧЕРЕЗ UART
Версия 19.04.15


Для генерации сигнала частотой 125 кГц используется режим сброса по совпадению таймера 2
Генерация сигнала 125 кГц производится аппаратно на выводе ОС2 таймера 2 (в микроконтроллере ATmega16 - это вывод PD7)

Микроконтроллер				ATmega16
Тактовая частота			8 MHz

********************************************************************************************************************************************/ 

#define F_CPU 8000000UL											// Тактовая частота микроконтроллера
#include <avr/io.h>
#include <util/delay.h>											// Библиотека программной задержки
#include <avr/eeprom.h>                                        //подключение библиотеки работы с EEPROM

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//					ОСНОВНЫЕ КОНСТАНТЫ
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#define DDR_OPTIK		DDRC									// Определение регистров портов для оптических датчиков и управления блокировкой двери
#define PORT_OPTIK		PORTC
#define PIN_OPTIK		PINC
#define PIN_INCOMING	PC0                                  // датчик положения двери
#define PIN_BOLT_UP	    PC1										// датчик верхнего открытого положения
#define PIN_BOLT_DOWN	PC2                                     // датчик нижнего закрытого положения
#define PIN_OPEN	    PC3                                     // выход сигнала открытия двери
#define PIN_CLOSE       PC4                                     // выход сигнала закрытия двери

#define BOLT_UP		(PIN_OPTIK & (1<<PIN_BOLT_UP))	            // высокий уровень датчика верхнего положения
#define BOLT_DOWN		(PIN_OPTIK & (1<<PIN_BOLT_DOWN))	    // высокий уровень датчика нижнего положения
#define INCOMING		(PIN_OPTIK & (1<<PIN_INCOMING))	            // высокий уровень датчик проходки


#define DDR_FREQ		DDRD									// Определение регистров портов для генерации частоты 125 кГц
#define PORT_RFID		PORTD
#define PIN_RFID		PIND
#define PIN_FREQ		PD6										// Вывод для генерации несущей частоты 125 кГц (в микроконтроллере ATmega16 - это вывод PD7)
#define PIN_MEMORY	    PD4                                  // кнопка памяти ключа
#define RFID			PD7									// Вывод для считывания manchester-кода с номером метки

#define SIGNAL_PIN		(PIN_RFID & (1<<RFID))					// Значение логического уровня на выводе RFID
#define SAVE_IN_MEMORY	(PIN_RFID & (1<<PIN_MEMORY))	        // нажатие кнопки для сохранения ключа

#define	BAUD			9600UL									// Задание скорости обмена по UART
#define SPEED			((F_CPU+BAUD*8)/(BAUD*16)-1)

#define FREQ_OUT		125000UL								// Частота генерируемая антеной считывателя, Гц
#define DIVIDER_125KHZ	(F_CPU/FREQ_OUT/2-1)					// Константа для генерации на выводе частоты FREQ_OUT от таймера 2

#define HALF_INTERVAL	370										// Полутерный интервал от короткого интервала в 250 мкс

#define HI				1										// Признак логической единицы
#define LO				0										// Признак логического нуля
#define OK				1										// Признак нормального завершения функции
#define ERR				0										// Признак завершения функции с ошибкой

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//				ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
uint8_t a=0;
uint8_t Level_Inv;												// Переменная признака прямой/обратной логики
uint16_t Adress1=0x100;
uint16_t Adress2=0x120;
uint16_t Adress3=0x140;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//					ПРОТОТИПЫ ФУНКЦИЙ
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void	out_UART		(uint8_t);
uint8_t read_ID			(uint8_t *, uint32_t *);
uint8_t Read_nibble		(void);
uint8_t level_pin_rfid	(void);
uint8_t Find_Preambula	(void);
void Open_Door();

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//						ОСНОВНОЙ КОД
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int main(void)
{                                                   
	DDR_OPTIK |=(0<<PIN_INCOMING|0<<PIN_BOLT_UP|0<<PIN_BOLT_DOWN|1<< PIN_OPEN|1<<PIN_CLOSE);  //назначаем входы и выходы портадля управления дверью
	DDR_FREQ |= (1<<PIN_FREQ);									// Настраиваем вывод генерации сигнала FREQ_OUT от таймера на выход
	OCR2  = DIVIDER_125KHZ;										// В регистр совпадения заносится делитель для генерации частоты 125 кГц
	TCCR2 = (1<<COM20|1<<WGM21|0<<CS22|0<<CS21|1<<CS20);		// Настройка таймера на сброс по совпадению, деление 1
	
	UCSRB = (1<<TXEN);											// Настройка UART на передачу
	UCSRC = (1<<URSEL|1<<UCSZ1|1<<UCSZ0);
	UBRRL = SPEED & 0xFF;
	UBRRH = SPEED >> 8;
				
    while(1)
    {
		uint32_t	IndividID;									// 32-разрядная переменная для хранения индивидуального кода
		uint8_t		GroupID;									// 8-разрядная переменная для хранения группового кода
		
		if (read_ID(&GroupID, &IndividID) == OK){				// Если read_ID возвращает 1, значит код успешно считан
			
			if(SAVE_IN_MEMORY) {
				
				 if(a==0){eeprom_update_dword(Adress1,IndividID);}                          // записать в eeprom при нажатой кнопке ?
				//if(a==1){eeprom_update_dword(Adress2,IndividID);}                          // как оформить эту запись?
			    //if(a==2){eeprom_update_dword(Adress3,IndividID);}
					a++;
					if(a>2){a=0;}                                                //ограничиваем количество сохраняемых ключей
					}
			
				
			
			out_UART(GroupID);									// Отправка 8-разрядного группового кода
			out_UART((uint8_t)(IndividID>>24));					// Отправка 4 байт индивидуального кода
			out_UART((uint8_t)(IndividID>>16));                 // Наблюдаем через терминал
			out_UART((uint8_t)(IndividID>>8));
			out_UART((uint8_t)(IndividID>>0));}
			
			while(SAVE_IN_MEMORY){}                                           // для однократной записи данных метки в память
			
			 
			if(eeprom_read_dword(Adress1==IndividID){ Open_Door();} // как сравнить текущее значение с данными в памяти
			
			
			
				                                                 
			
			_delay_ms(1000);                                         // Небольшая задержка, перед следующим циклом считывания	
	}
}

////////////////////////////////////////////////////////////
//					СЧИТЫВАНИЕ ID-КОДА
////////////////////////////////////////////////////////////
uint8_t read_ID(uint8_t *Group, uint32_t *ID){
	uint8_t	data;
	uint8_t	xor		= 0;
	*Group			= 0;
	*ID				= 0;
	
	while (Find_Preambula() == ERR) {};							// Поиск преамбулы
		
																// Чтение байта группового идентификатора
	data = Read_nibble();										// Считываем первую тетраду
	if (data & 0xF0)					return ERR;				// Если старшая тетрада равна 1111, значит контрольная сумма не сошлась
	xor ^= data;												// Вычисляем контролльную сумму
	*Group = data<<4;
	
	data = Read_nibble();
	if (data & 0xF0)					return ERR;
	xor ^= data;
	*Group |= data;
	
	for (uint8_t i=0; i<8; i++){								// Цикл считывания 4 байт индивидуального кода
		data = Read_nibble();									// Считываем тетраду
		if (data & 0xF0)				return ERR;				// Если в 4 старших разрядах не ноль, следовательно произошла ошибка в считывании тетрады
		xor ^= data;											// Подсчет контрольной суммы
		*ID |= ((uint32_t)data << (28-i*4));					// Записываем тетрады в 32-разрядное слово
	}

	data = Read_nibble();										// Считывание последние 4 бит контрольной суммы по столбцам
	data &= 0x0F;												// Обнуляем неиспользуемые биты ошибки в старшей тетраде
	xor ^= data;												// Исключающее ИЛИ подсчитанной контрольной суммы и считанной суммы по столбцам
	
	if (xor)							return ERR;				// Если xor не равен нулю, то ошибка в подсчете контрльной суммы
	else								return OK;				// Если xor равен нулю, то контрольная сумма подсчитана верно
}


////////////////////////////////////////////////////////////
//				СЧИТЫВАНИЕ 5 БИТ СЛОТА
////////////////////////////////////////////////////////////
uint8_t Read_nibble(void){										// Чтение 5 бит слота (4 бита тетрады + 1 бит контрольной суммы)
	uint8_t nibble	= 0;										// Переменная для приема тетрады
	uint8_t	xor		= 0;										// Переменная для подсчета контрольной суммы
	
	for (uint8_t i=0; i<5; i++){
		_delay_us(HALF_INTERVAL);								// Ожидание полуторного короткого интервала
		nibble <<= 1;
		if (level_pin_rfid() == HI){							// Считали с вывода ноль
			while (level_pin_rfid() != LO) {};					// Ожидание низкого уровня на выводе
			}else{
			nibble |= 1;										// Считали с вывода единицу
			xor ^= 1;											// На рассчет контрольной суммы влияет только единица
			while (level_pin_rfid() != HI) {};					// Ожидание высокого уровня на выводе
		}//if
	}//for
	
	nibble >>= 1;												// Избавились от 5-го бита контрольной суммы
	if (xor){													// Если контрольная сумма не ноль, то ошибка чтения
		nibble |= 0xF0;											// В старших 4 битах возвращаем 1111 - признак ошибки
	}
	
	return nibble;												// 4 бита считаны без ошибки. В старшей тетраде нули - признак схождения контрольной суммы
}



////////////////////////////////////////////////////////////
//				НАХОЖДЕНИЕ ПРЕАМБУЛЫ
////////////////////////////////////////////////////////////
uint8_t Find_Preambula(){
	
	Level_Inv = HI;												// Признак прямой логики
	
	for (uint8_t i=0; i<70; i++)								// Цикл нахождения преамбулы в прямой логике
	{
		while (!SIGNAL_PIN) {};									// Ожидание высокого уровня на выводе
		while (SIGNAL_PIN) {};									// Ожидание низкого уровня на выводе (ожидание спадающего фронта)
		_delay_us(HALF_INTERVAL);								// Ожидание полуторного короткого интервала после спадающего фронта
		if (SIGNAL_PIN)					continue;				// Если на выводе высокий уровень, то ОШИБКА ЧТЕНИЯ ПРЕАМБУЛЫ
		
		while (!SIGNAL_PIN) {};									// Ожидание высокого уровня на выводе
		
		for (uint8_t j=0; j<8; j++){							// Цикл обнаружения признаков преамбулы
			_delay_us(HALF_INTERVAL);							// Ожидание полуторного короткого интервала
			if (SIGNAL_PIN)				break;					// Если на выводе низкий уровень, то ОШИБКА ЧТЕНИЯ ПРЕАМБУЛЫ
			while (!SIGNAL_PIN) {};								// Ожидание высокого уровня на выводе
			if (j == 7)					return OK;				// Если 8 раз считаны логические 1 в прямой логике, то выходим из функции
		}
	}//for
	
	Level_Inv = LO;												// Признак обратной логики
	
	for (uint8_t i=0; i<70; i++)								// Цикл нахождения преамбулы в прямой логике
	{
		while (SIGNAL_PIN) {};									// Ожидание высокого уровня на выводе
		while (!SIGNAL_PIN) {};									// Ожидание низкого уровня на выводе (ожидание спадающего фронта)
		_delay_us(HALF_INTERVAL);								// Ожидание полуторного короткого интервала после спадающего фронта
		if (!SIGNAL_PIN)				continue;				// Если на выводе высокий уровень, то ОШИБКА ЧТЕНИЯ ПРЕАМБУЛЫ
		
		while (SIGNAL_PIN) {};									// Ожидание высокого уровня на выводе
		
		for (uint8_t j=0; j<8; j++){							// Цикл обнаружения признаков преамбулы
			_delay_us(HALF_INTERVAL);							// Ожидание полуторного короткого интервала
			if (!SIGNAL_PIN)			break;					// Если на выводе низкий уровень, то ОШИБКА ЧТЕНИЯ ПРЕАМБУЛЫ
			while (SIGNAL_PIN) {};								// Ожидание высокого уровня на выводе
			if (j == 7)					return OK;				// Если 8 раз считаны логические 1 в обратной логике, то выходим из функции
		}
	}//for
	
	return ERR;
}


////////////////////////////////////////////////////////////
//СЧИТЫВАНИЕ УРОВНЯ С ВЫВОДА С УЧЕТОМ ПРЯМОЙ/ОБРАТНОЙ ЛОГИКИ
////////////////////////////////////////////////////////////
uint8_t level_pin_rfid(void){
	if (Level_Inv == HI){										// Прямая логика
		if (SIGNAL_PIN)				return HI;
		else						return LO;
		}else{													// Обратная логика
		if (SIGNAL_PIN)				return LO;
		else						return HI;
	}
}


//////////////////////////////////////////////////////////////
//                 ОТКРЫТИЕ ДВЕРИ                       //
//////////////////////////////////////////////////////////////
void Open_Door(){
	
PORT_OPTIK |=(1<<PIN_OPEN);                                                       //________________
while(!(PIN_OPTIK & (1<<PIN_BOLT_UP))){}                                          //
PORT_OPTIK |=(0<<PIN_OPEN);                                                       //  проверено на отладочной плате PinBoard 2
_delay_ms(500);                                                                   //  работа логики для управления люком проверена и
if(PIN_OPTIK & (1<<PIN_INCOMING)){while(PIN_OPTIK & (1<<PIN_INCOMING));}          //  исправно работает
PORT_OPTIK |=(1<<PIN_CLOSE);                                                      //
while(!(PIN_OPTIK & (1<<PIN_BOLT_DOWN))){}                                        //
PORT_OPTIK |=(0<<PIN_CLOSE);
			}
	
	
		
		
	
	
////////////////////////////////////////////////////////////
//				ПРИЕМ/ПЕРЕДАЧА ДАННЫХ UART
////////////////////////////////////////////////////////////
void out_UART(uint8_t data){									// Передача байта через UART
	while(!(UCSRA&(1<<UDRE)));									// Ожидание готовности UART к передаче
	UDR = data;													// Запись в регистр UDR байта данных начинает процесс передачи
}

Совсем короткий быстро не выйдет, но есть полный - там все закоментарено , а в принципе могу самую заморочную переменную превратить в константу и тогда останется совсем немного строк. Это IndividID вокруг которой все наворочено - 32-битное значение

Ну, тогда или делайте не по быстрому, или извините.

Я вставил, запустил, она у меня в принципе не компилируется (Вы ведь даже тип МК не указали, у меня стоит 328 - говорит, что у неё таких регистров нет). А трахаться, смотреть что там за регистры, подбирать МК, чтобы оно как-то скомпилировалось … ну, вот, правда, мне это надо? Вот, вся эта головная боль? Сами-то как думаете?

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

Виноват - я так в проблему погрузился что забыл сказать : Атмега 16. сейчас короткую версию создам

Тебе же всё написано. Какой тип принимает функция eeprom_update_dword, и какой ты ей передаешь?

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

/*   Микроконтроллер				ATmega16
Тактовая частота			8 MHz

********************************************************************************************************************************************/ 

#define F_CPU 8000000UL											// Тактовая частота микроконтроллера
#include <avr/io.h>
#include <util/delay.h>											// Библиотека программной задержки
#include <avr/eeprom.h>                                        //подключение библиотеки работы с EEPROM



//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//				ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
uint8_t a=0;
uint16_t Adress1=0x100;
uint16_t Adress2=0x120;
uint16_t Adress3=0x140;
uint32_t	IndividID=0x3DFFTC3D;                                        // условное значение
uint32_t	IndividID1=0x3D00003D;                                       // фальшивый ключ
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//					ПРОТОТИПЫ ФУНКЦИЙ
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//						ОСНОВНОЙ КОД
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int main(void)
{                                                   
	
				
				 if(a==0){eeprom_update_dword(Adress1,IndividID);}                          // записать в eeprom при нажатой кнопке ?
				if(a==1){eeprom_update_dword(Adress2,IndividID1);}                          // как оформить эту запись?
			    if(a==2){eeprom_update_dword(Adress3,IndividID1);}
					a++;
					if(a>2){a=0;}                                                //ограничиваем количество сохраняемых ключей
					}
			
			
			
			 
			if(eeprom_read_dword(Adress1==IndividID){IndividID1=IndividID } // заменим фальшивый ключ
			
			
			
				                                                 
			
			_delay_ms(1000);                                         // Небольшая задержка, перед следующим циклом считывания	
	}
}

Мы с Вами никак не поймём друг друга. Я прошу нечто, что я могу взять и скомпилировать БЕЗ ТРАХА, без исправления Ваших кодов, просто взять и скомпилировать и увидеть Ваши ошибки.

Вы это компилировали? У Вас правда строка №20 компилируется? А строка №43 и дальше? У Вас это компилируется? А если нет, зачем Вы это мне дали? Чтобы что?

Вы издеваетесь и троллите?

Это что за порнография?

Вообще выше есть полный код, а эта порнуха просо чтоб по нужному условию хоть чтото тупое сделать , т.к. я сократил до минимума код. Главное как верно записать значение переменной uint32_t в адрес 100 ( начало eeprom у атмеги16) и как верно считать данное значение для сравнения с текущими данными.

Если Вы про ошибки в строках №№33-35, то простите, какой тип должен быть у первого параметра функции eeprom_update_dword ?

Смотрим

void eeprom_update_dword (uint32_t *__p, uint32_t __value);

ага - uint32_t *. А Вы ей что суёте? AdressХ у Вас uint16_t . Ну, и чего Вы хотите?

Приведите типы. Например, опишите нормально переменные

uint32_t * Adress1 = reinterpret_cast<uint32_t *>(0x100);
uint32_t * Adress2 = reinterpret_cast<uint32_t *>(0x120);
uint32_t * Adress3 = reinterpret_cast<uint32_t *>(0x140);

и будет Вам счастье!

1 лайк

вот полный код компилируется - он рабочий до тех пор пока я не вношу строки с командами для работы с eeprom -

Ладно, там 3 ошибки, здесь 2, как минимум.

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

На Вашу проблему я ответил выше.

Ок! понял - вижу преобразование типа, я ранее видел, что в библиотеке есть команда
eeprom_update_dword (uint32_t *__p, uint32_t __value), но ожидал, что адрес uint16_t просто дополниться нулями. Сейчас попробую исправить. Спасибо

Вы разницу между типом uint16_t и uint16_t* вообще не вкуриваете? Функция ждет адрес, а вы ей значение подсовываете.

Евгений, привет! Проблему я решил …немного криво, но компилируется, скоро соберу на отладочной плате и проверю. Сделал так:

//  Глобальные переменные //
uint32_t Adress1 =0x00000100;
uint32_t Adress2 =0x00000100;
uint32_t Adress3 =0x00000100;
//  основной код   //
if(SAVE_IN_MEMORY) {
if(a==0){eeprom_update_dword(&Adress1,IndividID);}        //записать при нажатой кнопке			 
if(a==1){eeprom_update_dword(&Adress2,IndividID);}        //в eeprom
if(a==2){eeprom_update_dword(&Adress3,IndividID);}
a++;
if(a>2){a=0;}                      //ограничиваем количество сохраняемых ключей
	}
while(SAVE_IN_MEMORY){}          // для однократной записи данных метки в память
if(eeprom_read_dword(&Adress1)==IndividID){ Open_Door();} // сравнить c разрешенными 
                                                                                                              // ключами из eeprom 
if(eeprom_read_dword(&Adress2)==IndividID){ Open_Door();} 
if(eeprom_read_dword(&Adress3)==IndividID){ Open_Door();}

Но хочу разобраться с вашей записью для полного понимания, назначение записи понятно - много описаний в интернете :

uint32_t * Adress1 = reinterpret_cast <uint32_t*>(0x100);

Так я тоже попытался, но получил предупреждения в системе ( AtmelStudio 7.0)
ругается именно на эту строку и в конце сообщает об ошибке с незнакомой функцией.
Подскажите , какая библиотека используется в этом случае?

и есть еще вариант:

uint32_t EEMEM Adress1;
uint32_t EEMEM Adress2;
uint32_t EEMEM Adress3;

прочитать можно тут Работа с EEPROM в AVR-GCC – RoboCraft