Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

Доброго времени суток Коты. Объясните пожалуйста как работает МК в строчке кода if(PINC.B5&&!t) при значениях t ноль и единица. При значении ноль выполняются строки в {} скобках , при значении единица вроде бы не должны выполняться {} скобки, но они выполняются. PINC.B5 в обоих случаях равен единице.

подстановка ! t==1 ничего не поменяла.

Добавлено after 42 minutes 12 seconds:
Получается что !t при t равном единице не ноль. Как это исправить?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

Billi34, !t при t не равном нулю всегда ложь. Так что, раз у Вас выражение if истинно, то t не равно нулю. Покажите весь код.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Billi34, не жалей скобок для расстановки приоритетов операций. На первых порах жить станет сильно легче.
Встал на лапы
Аватара пользователя
Сообщения: 128
Зарегистрирован: Пн фев 08, 2016 10:57:14

Сообщение smalcom »

t равном единице не ноль.
"Какие ваши доказательства?"
Есть снимок регистра в симуляторе или отладчике?
Реклама
Эиком - электронные компоненты и радиодетали
Прорезались зубы
Аватара пользователя
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

Сообщение FeCat »

Задолбался с инклюдами, нету понимания, гугл не помогает МЯУ!!! :cry:
Имею main.cpp в котором первой строчкой #include "main.h".

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

//main.h 
.
.// Всякие инклюды
.
#include "ds18b20.h"
.
.// Всякие инклюды
.
#include "PrintFunc.h"	//	В PrintFunc.cpp почему то не видится объявление из ds18b20.h !!!!!
.
.// Всякие инклюды
.
В ds18b20.h соответственно обьявление класса ds18b20.
В PrintFunc.cpp первой строчкой #include "PrintFunc.h", но в PrintFunc.cpp почему то не видится обьявление класса ds18b20 ('ds18b20' has not been declared) из ds18b20.h хотя он обьявлен раньше.
Если в PrintFunc.h подключить ds18b20.h, то всё видится, но как так то? Ведь в main.h "#include "ds18b20.h" стоит раньше "#include "PrintFunc.h".
Вложения
Safe_moonshine_1.zip
Проект целиком Atmel Studio 7.0
(76.92 КБ) 211 скачиваний
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="FeCat",url="/forum/viewtopic.php?p=3704784#p3704784"]Если в PrintFunc.h подключить ds18b20.h, то всё видится, но как так то? Ведь в main.h "#include "ds18b20.h" стоит раньше "#include "PrintFunc.h".[/uquote]
#include тупо делает подстановку, т.е. содержимое хедеров добавится в .cpp и в конечном итоге останутся только main.cpp, PrintFunc.cpp и ds18b20.cpp, которые еще и компилируются в произвольном порядке.
Реклама
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

[uquote="FeCat",url="/forum/viewtopic.php?p=3704784#p3704784"]Если в PrintFunc.h подключить ds18b20.h, то всё видится, но как так то? Ведь в main.h "#include "ds18b20.h" стоит раньше "#include "PrintFunc.h".[/uquote]вот так то. Когда компилятор собирает PrintFunc.cpp, он совершенно ничего не знает о main.cpp - каждый исходник компилируется изолировано.
Прорезались зубы
Аватара пользователя
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

Сообщение FeCat »

Спасибо, когда то читал, но кажись только сейчас начал понимать, когда лбом побился )). Каждый .cpp пользуется только своим набором .h.
И тем не мене опять вопрос с почти теми-же участниками, кто то кого то не хочет видеть.

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

//PrintFunc.h

#include "SensorConf.h" // Если внутри объявить "void print_SensorConf(SensorConf &ptr);" после объявления класса "SensorConf" то всё нормально собирается.
.
.
.
void print_SensorConf(SensorConf &ptr); // Ругается - "variable or field 'print_SensorConf' declared void", 
                                                           // "'SensorConf' was not declared in this scope"
                                                           // "'ptr' was not declared in this scope"
Функция print_SensorConf принимает ссылку на обьект класса, класс обьявлен в SensorConf.h.
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

целиком код покажите. В каком конкретно месте объявляется print_SensorConf при ругани? В этом случае компилятор считает сие переменной или полем класса, а не прототипом функции, о чем прямо и неоднозначно говорит.
Прорезались зубы
Аватара пользователя
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

Сообщение FeCat »

Не собирается если функция print_SensorConf объявляется в PrintFunc.h как в листинге:
Спойлер

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

/*
 * PrintFunc.h
 *
 * Created: 21.09.2019 16:11:05
 *  Author: Admin
 */ 

#ifndef PRINTFUNC_H_
#define PRINTFUNC_H_

//#include "main.h"

#include "stdint.h"
#include "SensorConf.h"	//	Если void print_SensorConf(SensorConf &ptr); - прописать внутри то всё собирается
	
void print_ads1115_value(uint16_t val);
void print_ADC_value(uint16_t val);
void print_Freg100(uint16_t val);
void print_ds18b20_val(int16_t &t);

void print_SensorConf(SensorConf &ptr);		//	Так не собирается

#endif /* PRINTFUNC_H_ */
Объявление класса в SensorConf.h.
Спойлер

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

/* 
* SensorConf.h
*
* Created: 27.04.2019 20:44:02
* Author: Admin
*/

#ifndef SensorConf_h_
#define SensorConf_h_ 



#include <stdint.h>
//#include "pin_macros.h"
//#include "menu.h"
#include "global_vars.h"

//#include "PinDefs.h"

typedef struct{
	bool		DS18B20_Enable;				//	1	<DS18B * ON/OFF>	Вкл/Откл датчика
	uint8_t		Alarm_1_Enable;				//	2	<Alarm 1 ON/OFF>	Разрешение сигнала тревоги 1
	uint8_t		Alarm_1_ifUpTemperature;	//	3	<Alarm 1 if >/<>	Настройка тревоги 1 по превышению(или равно) или понижению(или равно)
	int16_t		Alarm_1_TemperatureVal;		//	4	<Alarm 1 set tC>	Уставка тревоги 1 по температуре
	uint8_t		Action_1_Namber;			//	5	<Choice1 action>	Номер действия для первого аларма
	uint8_t		Alarm_2_Enable;				//	6	<Alarm 2 ON/OFF>	Разрешение сигнала тревоги 2
	uint8_t		Alarm_2_ifUpTemperature;	//	7	<Alarm 1 if >/<>	Настройка тревоги 1 по превышению(или равно) или понижению(или равно)
	int16_t		Alarm_2_TemperatureVal;		//	8	<Alarm 2 set tC>	Уставка тревоги 1 по температуре
	uint8_t		Action_2_Namber;			//	9	<Choice2 action>	Номер действия для второго аларма
	uint8_t		Action_Sensor_ERROR;		//	10
} EEstruct;

using SensorConfEEPROM = EEstruct;

class SensorConf
{
//variables
public:
	public:
	
	SensorConfEEPROM		Conf;						// Настройки в ОЗУ, сохраняемые во шлэше
	
	bool					Check_Alarm(void);			//	Проверка значений датчиков на уставки тревоги. true - тревога.
	unsigned int			AlarmActionsStatus;			//	При алармах тут выставляем флаги.
	bool					AlarmFlag;					//	При любом аларме выставляем флаг, сбрасывается только вручную.
	const signed int		*TValue;					//	Указатель на температуру.
	const bool				*TValueCRC;					//	Указатель на CRC температуры, true-верная.
	
	static bool				SC_eepromERROR;				//	Если при включении eeprom прочти с ошибкой
	unsigned char MenuN;								// номер функцию меню
	
/*
uint8_t		Alarm_1_Enable_EEPROM			EEMEM = 0;
uint8_t		Alarm_1_ifUpTemperature_EEPROM	EEMEM = 1;
uint16_t	Alarm_1_TemperatureVal_EEPROM	EEMEM = (30<<4);
uint8_t		Action_1_Namber_EEPROM			EEMEM = 0;
uint8_t		Alarm_2_Enable_EEPROM			EEMEM = 0;
uint8_t		Alarm_2_ifUpTemperature_EEPROM	EEMEM = 0;
uint16_t	Alarm_2_TemperatureVal_EEPROM	EEMEM = (25<<4);
uint8_t		Action_2_Namber_EEPROM			EEMEM = 0;
uint8_t		Action_Sensor_ERROR_EEPROM		EEMEM = 0;*/

private:
	SensorConfEEPROM *SC_eeprom;					// Указатель на структуру флэша где будем сохранять настройки
	SensorConfEEPROM *SC_eepromXOR;					// Указатель на структуру флэша где будем сохранять XOR настроек
	void menu_1(void);	//	Вкл/откл датчика
	void menu_2(void);	//	<Alarm 1 ON/OFF>	Разрешение сигнала тревоги 1
	void menu_3(void);	//	<Alarm 1 if >/<>	Настройка тревоги 1 по превышению(или равно) или понижению(или равно)
	void menu_4(void);	//	<Alarm 1 set tC>	Уставка тревоги 1 по температуре
	void menu_5(void);	//	<Choice action >	Номер действия для первого аларма
	void menu_6(void);	//	<Alarm 2 ON/OFF>	Разрешение сигнала тревоги 2
	void menu_7(void);	//	<Alarm 1 if >/<>	Настройка тревоги 1 по превышению(или равно) или понижению(или равно)
	void menu_8(void);	//	<Alarm 2 set tC>	Уставка тревоги 1 по температуре
	void menu_9(void);	//	<Choice2 action>	Номер действия для второго аларма
	void menu_10(void);	//	<Sens ERROR act>
	void menu_0(void);
	char RW_EEPROM(bool a=0);	//	true - сохранение, false - восстановление настроек. Возврат 0 если была ошибка.
	
public:
	
	void ToDefoult(void);	//	Сброс к настройкам по умолчанию.
	void menu_start(void);
	
	//void (SensorConf::*Menu[10])(void);	// нулевая и последняя функция в массиве будут выводить в корневое меню
	using FP = void(SensorConf::*) ();
	FP Menu[12]	=	{	&SensorConf::menu_0,
						&SensorConf::menu_1,
						&SensorConf::menu_2,
						&SensorConf::menu_3,
						&SensorConf::menu_4,
						&SensorConf::menu_5,
						&SensorConf::menu_6,
						&SensorConf::menu_7,
						&SensorConf::menu_8,
						&SensorConf::menu_9,
						&SensorConf::menu_10,
						&SensorConf::menu_0};
	
	
	unsigned char Sensor_number;		// Номер датчика
		
protected:
private:
	// Можно сделать статическим...
	void CheckButtonAndSwitchMenu(void);	//	Переключение меню от кнопок LEFT-RIGHT

//functions
public:
	SensorConf(const int*, const bool*, SensorConfEEPROM *eeprom, SensorConfEEPROM *SC_eepromXOR, unsigned char SN);
	SensorConf();
	~SensorConf();
protected:
private:
	SensorConf( const SensorConf &c );
	SensorConf& operator=( const SensorConf &c );

}; //SensorConf


#ifdef MAIN
	#define _Ex
#else
	#define _Ex extern

	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_1;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_2;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_3;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_4;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_5;

	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_XOR_1;	// Для контроля целостности
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_XOR_2;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_XOR_3;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_XOR_4;
	_Ex SensorConfEEPROM EEMEM SensorConfEEPROM_XOR_5;

	_Ex SensorConfEEPROM SensorConfDefoult;	//	Дефолтные настройки

	_Ex SensorConf SensorConf_1;	// DS18B20_1
	_Ex SensorConf SensorConf_2;	// DS18B20_2
	_Ex SensorConf SensorConf_3;	// DS18B20_3
	_Ex SensorConf SensorConf_4;	// DS18B20_4
	_Ex SensorConf SensorConf_5;	// DS18B20_5

#endif


//void print_SensorConf(SensorConf &ptr);	//	Если раскомментировать, и закомментировать в PrintFunc.h то собирается



#endif /*SensorConf_h_*/
Вложения
Safe_moonshine_1.zip
Проект целиком, как есть. Atmel Studio 7.0
(180.58 КБ) 211 скачиваний
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

а какой конкретно исходник не собирается? Пытаюсь сам разгрести все цепочки инклудов, но тут какая-то совсем мешанина из разряда "так делать не надо")
Прорезались зубы
Аватара пользователя
Сообщения: 211
Зарегистрирован: Пт окт 21, 2011 14:39:31

Сообщение FeCat »

Понимаю, что накосячил с подключением инклудов. Ругается на файл PrintFunc.h. Конкретно на строку void print_SensorConf(SensorConf &ptr);
Вложения
Safe_moonshine.png
Скриншот
(59.81 КБ) 161 скачивание
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Ну так и понятно, что ругается на неизвестный тип SensorConf - инклюд, в котором он, видимо, определён, закомментирован чуть выше.
Контактная информация:
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

не про это спрашивал, ну ладно, сойдет. Вижу.
"recipe for target 'SensorConf.o' failed" - т.е. ошибка возникает при попытке скомпилять SensorConf.cpp
из-за адского месива в инклудах прототип из PrintFunc.h появляется в собираемом коде раньше, чем описание класса SensorConf из SensorConf.h. Прикрепил выхлоп препроцессора , гляньте на него.

идея организовать для простоты один мегазаголовочник (здесь - main.h), в который прицеплены вообще все остальные заголовочники и который потом прямо или через какую-нибудь задницу - типа местного global_vars.h или еще чего - появляется в каждом из исходников проекта, очень простая, очевидная и неправильная. Не надо так делать без веских причин.
Вложения
SensorConf-preprocessed.cpp.txt
(51 КБ) 202 скачивания
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

А зачем Вам в PrintFunc.h включать main.h? Что оттуда нужно конкретно здесь, в этом файле?

Добавлено after 4 minutes 49 seconds:
arkhnchul, вопрос не к Вам, естественно.

Хотя идея одного "мега" инклюда вполне могла бы сработать. Лишь бы там были только прототипы функций, описания структур, макросы, и не более того. И, естественно, никаких объявлений переменных. И никаких включений других заголовочных файлов того же проекта, которые могут включать его самого, формируя циклические включения.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

WiseLord, почему в одном общем заголовочном файле нельзя объявлять переменные? Я всегда так делаю, решая проблему одним дефайном в исходнике, в чьем обьектнике будет располагатся статический сегмент.
А рекурсивное включение легко избегается одним #ifndef и дефайном.

Добавлю примеры.
В одном из исходных файлов проекта объявляем

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

#define _MAIN_C_
Во включаемом общем файле делаем так:

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

#ifndef _MAIN_H_INCLUDED
#define _MAIN_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MAIN_C_
#define _MAIN_EXTERNAL_
#else
#define _MAIN_EXTERNAL_ extern
#endif // _MAIN_C_
...
_MAIN_EXTERNAL_ int some_global_static_variable;
...
#ifdef __cplusplus
}
#endif

#endif // _MAIN_H_INCLUDED
Открыл глаза
Аватара пользователя
Сообщения: 64
Зарегистрирован: Чт июн 09, 2016 18:24:41

Сообщение Billi34 »

Прошу прощения за поздний ответ. Утром предоставлю объяснялки. Отладчиков симуляторов нет но есть лишнее "дерганье ногами" в "железе". Код предоставлю.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Billi34, ты же нас фактически послал с советами сделать нормальную структуру программы. Типа "и так сойдёт". Ну теперь пожинай плоды. Твой код в принципе неуправляем. Это было понятно сразу. Когда опытный программист смотрит на код и не понимает как он работает, то такой код в топку. Впрочем, он и не работает, как и ожидалось.

Добавлено after 52 minutes 13 seconds:
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3705026#p3705026"]идея организовать для простоты один мегазаголовочник (здесь - main.h), в который прицеплены вообще все остальные заголовочники и который потом прямо или через какую-нибудь задницу - типа местного global_vars.h или еще чего - появляется в каждом из исходников проекта, очень простая, очевидная и неправильная. Не надо так делать без веских причин.[/uquote]А я так делаю. #pragma once и namespace позволяют безболезненно инклюдить что угодно и куда угодно, если заголовочные файлы у вас действительно заголовочные. Единственный минус такого подхода - время компиляции. Но, во-первых, современные компиляторы умеют не компилировать много раз одни и те же заголовочные файлы. Во-вторых, у меня на ноуте, который является основным местом сборки эмбеддерских проектов, 8-ядерный проц и SSD. Ну будет у навороченного проекта полная сборка на 5 сек больше, да и чёрт с ним. На простых проектах разница вообще о-малое. Зато я получаю кучу плюсов для себя любимого.
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3705079#p3705079"]#pragma once[/uquote]
Не универсально, так как нестандартная конструкция, поддерживаемая не всеми компиляторами. Мой же вариант, приведенный выше, работает с любым компилятором.
Так же #pragma once не позволяет использовать X-Macro, а иногда хочется.

На крупных проектах все редко изменяемые заголовочные файлы предпочитаю объединить включением в один общий файл и скомпилировать, что существенно уменьшает время сборки.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Компиляторы, которые я использую, все поддерживают. Мне этого достаточно. Много компиляторов С++17 не поддерживают, и что, тоже не использовать?
Ответить

Вернуться в «Разные вопросы по МК»