Страница 268 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 22, 2018 19:10:04
ROMan2947
/ sz: делаем каноничненько - алиасим тип указателя на функцию
Спойлер
ничешно так-то
// sz: когда устанете бороться с компилятором - напишите так: TvvPtr PtrPunkt;
ну это после ваших вмешательств придется так написать
// sz: не выйдет в мышь впихнуть кота - любой заметит: - "Фактура не та!"Синтакс - ужасен - достаточно
здесь да,чет тупанул,этоже и так все адреса.
// sz: да и за полностью прописные имена типов/переменных и прочих не #define-ов - тру-Сишники из вас кактус сделают.

Ибо заповедано: -"Прописными - только #define-ы!"
пока вроде как ничего не выкатывали,но намотаю на ус!
//
sz: а если-бы функция имела аргументы?
тут я позабочусь об этом
И таблицу приоритетов посмотрите - кто кого перетянет.

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

[/spoiler]
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 22, 2018 21:14:41
Siarzhuk
[uquote="ROMan2947",url="/forum/viewtopic.php?p=3336612#p3336612"]
И таблицу приоритетов посмотрите - кто кого перетянет.

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

[/uquote]
Я про те скобки, которые function call. Они с высшим приоритетом, а указатель ешё и разыменовать надо - и у этой операции (dereference) приоритет ниже. За ассоциативность не утверждаю, но
должно сработать как надо.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт мар 22, 2018 21:28:45
ROMan2947
[uquote="Siarzhuk",url="/forum/viewtopic.php?p=3336731#p3336731"]должно сработать как надо.[/uquote]Спасибо,ща испытаю
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 07:09:07
ARV
Siarzhuk писал(а):но
должно сработать как надо.
вроде как и
PtrPunct(); должно сработать, хотя за всеми тонкостями предлагаемой типизации указателей я не следил...
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 12:05:20
ROMan2947
[uquote="ARV",url="/forum/viewtopic.php?p=3336861#p3336861"]вроде как и
PtrPunct(); должно сработать[/uquote]
до этой строчки у меня уже компилятор кипит ошибками и предупреждениями. Для более ясной картины выложу весь код.
ошибки такие:
1) при инициализации указетелей структуры,для того чтобы использовать операцию (->) пишет мол
conflicting types for 'Ptr_MeNU_LEVEL2_HWS чем ему не нравятся мои типы не пойму. При этом еще выдает
invalid type argument of '->' (have 'int') в строках использования операции (->).
2) при использовании операции (.)все устраивает.
P.S В PtrPunkt мне нужно сохранить адрес где хранится указатель на функцию и уже после этого нужно ее вызвать с помощью PtrPunkt
Menu_v20.h
Спойлер
Код: Выделить всё
#ifndef MENUv20_H_
#define MENUv20_H_
void opredelenieUkazatela(uint8_t);// определения указателя
//-----------------------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------------
//---------- вывода на дисплей------------------------------------------------------------------------------------------------------------------
void output_level_1_GWS (void); // выводит на дисплей уровень 1 для ГВС "GWS"
void output_level_21_GWS(void); // выводит на дисплей уровень 2.1(1 подпункт 2 уровня) для ГВС "TEK" текущие параметры
void output_level_22_GWS(void); // выводит на дисплей уровень 2.2(2 подпункт 2 уровня) для ГВС "YAHR" потребление за год
void output_level_23_GWS(void); // выводит на дисплей уровень 2.3(3 подпункт 2 уровня) для ГВС "TEMPER_MIN" минимальная
//---------------------------------------------------------------------------------------------
void output_level_1_HWS (void); // выводит на дисплей уровень 1 для ХВС "HWS"
void output_level_21_HWS(void); // выводит на дисплей уровень 2.1(1 подпункт 2 уровня) для ХВС "TEK" текущие параметры
void output_level_22_HWS(void); // выводит на дисплей уровень 2.2(2 подпункт 2 уровня) для ХВС "YAHR" потребление за год
void output_level_23_HWS(void); // выводит на дисплей уровень 2.2(3 подпункт 2 уровня) для ХВС "TEMPER_MIN" минимальная
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef void(*TvvPtr)(void); // новый тип указателя на функцию
TvvPtr PtrPunkt; // указатель для хранения адреса последненго пункта
//---тип структуры 1 уровня--------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct
{
TvvPtr PtrGWS; // пункт меню на первом уровне
TvvPtr PtrHWS; // пункт меню на первом уровне
}Level1; //---тип структуры 1 уровня
//----тип структуры 2 уровня-------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct
{
TvvPtr PtrTEK; // пункт меню на втором уровне
TvvPtr PtrYAHR; // пункт меню на втором уровне
TvvPtr PtrTEMP_min;
}Level2; //тип структуры 2 уровня
//--объявление структур уровней--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Level1 MeNU_LEVEL1; // структура 1 уровня
Level2 MeNU_LEVEL2_GWS; // структура 2 уровня для GWS
Level2 MeNU_LEVEL2_HWS; // структура 2 уровня для HWS
//---указатель на структуры уровней---------------------------------------------------------------------------------------------------------------------------------------------------
Level1 *Ptr_MeNU_LEVEL1; //указатель на Левел
Level2 *Ptr_MeNU_LEVEL2_GWS; //указатель на Левел 2 ГВС
Level2 *Ptr_MeNU_LEVEL2_HWS; //указатель на Левел 2 ХВС
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#endif /*MENUv20_H_*/
Menu_v20.c
Спойлер
Код: Выделить всё
#include "Menu_v2.0.h"
#include <stdio.h>
#define ENTER 0x25
#define UP 0x23
#define DN 0x56
#define CANCEL 0x26
//---инициализация структур-----------------------------------------------------------------------------------------------------
Level1 MeNU_LEVEL1={output_level_1_GWS,output_level_1_HWS}; // инициализируем структуру 1 уровня
Level2 MeNU_LEVEL2_GWS={output_level_21_GWS,output_level_22_GWS,output_level_23_GWS}; // инициализируем структуру 2 уровня для GWS
Level2 MeNU_LEVEL2_HWS={output_level_21_HWS,output_level_22_HWS,output_level_23_HWS}; // инициализируем структуру 2 уровня для HWS
//----инициализация указателей на структуру--------------------------------------------------------------------
Ptr_MeNU_LEVEL1=MeNU_LEVEL1; // указетелю присваиваем адрес структуры MeNU_LEVEL1
Ptr_MeNU_LEVEL2_GWS=MeNU_LEVEL2_GWS; // указетелю присваиваем адрес структуры MeNU_LEVEL2_GWS;
Ptr_MeNU_LEVEL2_HWS=MeNU_LEVEL2_HWS; // указетелю присваиваем адрес структурыMeNU_LEVEL2_HWS
void opredelenieUkazatela(uint8_t key_kod) // получает код нажатой клавиши
{
switch(key_kod)
{
//---ввод------------------------------------------------------------------------------------------------------------------------------------------------
case ENTER: if(PtrPunkt==NULL) PtrPunkt=Ptr_MeNU_LEVEL1->PtrGWS; break; //
if(PtrPunkt==(Ptr_MeNU_LEVEL1->PtrGWS)) PtrPunkt=Ptr_MeNU_LEVEL2_GWS->PtrTEK; break; //
if(PtrPunkt==(Ptr_MeNU_LEVEL1->PtrHWS)) PtrPunkt=Ptr_MeNU_LEVEL2_HWS->PtrTEK; break; //
//---вниз-------------------------------------------------------------------------------------------------------------------------------------------
case DN: if(PtrPunkt==(MeNU_LEVEL1.PtrGWS)) PtrPunkt=MeNU_LEVEL1.PtrHWS; break; // переход с в 1
if(PtrPunkt==(MeNU_LEVEL2_GWS.PtrTEK)) PtrPunkt=MeNU_LEVEL2_GWS.PtrYAHR; break; // переход
if(PtrPunkt==(MeNU_LEVEL2_GWS.PtrYAHR)) PtrPunkt=MeNU_LEVEL2_GWS.PtrTEMP_min; break; // переход с в 2
if(PtrPunkt==(MeNU_LEVEL2_HWS.PtrTEK)) PtrPunkt=MeNU_LEVEL2_HWS.PtrYAHR; break; //
if(PtrPunkt==(MeNU_LEVEL2_HWS.PtrYAHR)) PtrPunkt=MeNU_LEVEL2_HWS.PtrTEMP_min; break; // переход с в 2
//---вверх-----------------------------------------------------------------------------------------------------------------------------------------------
case UP: if(PtrPunkt==(MeNU_LEVEL1.PtrHWS) ) PtrPunkt=MeNU_LEVEL1.PtrGWS; break; // переход с в 1
if(PtrPunkt==(MeNU_LEVEL2_GWS.PtrTEMP_min)) PtrPunkt=MeNU_LEVEL2_GWS.PtrYAHR; break; // переход с в 2
if(PtrPunkt==(MeNU_LEVEL2_GWS.PtrYAHR) ) PtrPunkt=MeNU_LEVEL2_GWS.PtrTEK; break; // переход с в 2 уровне
if(PtrPunkt==(MeNU_LEVEL2_HWS.PtrTEMP_min)) PtrPunkt=MeNU_LEVEL2_HWS.PtrYAHR; break; // переход с в
if(PtrPunkt==(MeNU_LEVEL2_HWS.PtrYAHR)) PtrPunkt=MeNU_LEVEL2_GWS.PtrTEK; break; // переход с в 2
//----назад---------------------------------------------------------------------------------------------------------------------------------------------
case CANCEL: if(PtrPunkt==(MeNU_LEVEL2_GWS.PtrYAHR)||(MeNU_LEVEL2_GWS.PtrTEMP_min)||(MeNU_LEVEL2_GWS.PtrTEK)) PtrPunkt=MeNU_LEVEL1.PtrGWS; break; // переход с в 1 уровне меню на подменю
if(PtrPunkt==(MeNU_LEVEL2_HWS.PtrYAHR)||(MeNU_LEVEL2_HWS.PtrTEMP_min)||(MeNU_LEVEL2_HWS.PtrTEK)) PtrPunkt=MeNU_LEVEL1.PtrGWS;break; // переход с в 2 уровне меню на подменю
if(PtrPunkt==(MeNU_LEVEL1.PtrGWS)||(MeNU_LEVEL1.PtrHWS)) PtrPunkt=NULL; break; // переход с в 2 уровне меню на подменю
//-------------------------------------------------------------------------------------------------------------------------------------------------------
(*PtrPunkt)(); // вызываем функцию по ссылке
}
}
main.c
Спойлер
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include "Menu_v2.0.c"
#include "Menu_v2.0.h"
int main(void)
{
while (1)
{
opredelenieUkazatela(0x25);
}
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 12:52:23
viiv
1) Двигайтесь последовательно. Исправляйте самую первую ошибку, которую выдал компилятор. При ее исправлении двигайтесь дальше - компилируйте и переходите к п. 1)
Для начала:
Menu_v20.h:
Код: Выделить всё
...
#include "Menu_v2.0.h" // в Menu_v20.h уже определена MeNU_LEVEL1
...
Level1 MeNU_LEVEL1={output_level_1_GWS,output_level_1_HWS}; // Здесь MeNU_LEVEL1 определяется второй раз!!!!
Продолжаем:
Код: Выделить всё
// MeNU_LEVEL2_GWS имеет тип Level2, а MeNU_LEVEL2_GWS имеет тип 'Level2 *'. разница огромная
Ptr_MeNU_LEVEL2_GWS=MeNU_LEVEL2_GWS;
// Возможно Вы хотели написать
Ptr_MeNU_LEVEL2_GWS = &MeNU_LEVEL2_GWS;
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 12:59:50
ARV
ROMan2947 писал(а):при использовании операции (.)все устраивает.
операция -> применима только к
указателю слева, операция . - только к статическому экземпляру структуры. поэтому недопустимо их смешивать.
Код: Выделить всё
typedef struct{
int a;
int b;
} my_ struct;
my_struct var1;
my_struct *var2 = &var1;
var1.a = 12; // правильно
var1->a = 12; // ошибка
var2->b = 13; // правильно
var2.b = 13; // ошибка
Добавлено after 1 minute 18 seconds:
И еще чисто моё личное, предвзятое, мнение: вас, случайно, не в Майкрософте программированию обучали? это у них приняты длиннючие типы с тремя и более подчеркиваниями и мешаниной заглавных и прописных букв...
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 13:31:13
ROMan2947
с понятиями
определена, описана,объявлена, инициализирована одни путаницы.
мое понимание:
ОПРЕДЕЛЕНИЕ ОПИСАНИЕ ОБЪЯВЛЕНИЕ это одно и тоже
ИНИЦИАЛИЗАЦИЯ это присвоение уже ОПРЕДЕЛЕННОМУ, ОПИСАННОМУ, ОБЪЯВЛЕННОМУ
так что есть что?
[uquote="viiv",url="/forum/viewtopic.php?p=3337061#p3337061"]
// в Menu_v20.h уже определена MeNU_LEVEL1 [/quote] Да она там определена,но не инициализирована
...
Код: Выделить всё
Level1 MeNU_LEVEL1={output_level_1_GWS,output_level_1_HWS};
// Здесь MeNU_LEVEL1 определяется второй раз!!!!
здесь я ее инициализирую
Продолжаем:
Код: Выделить всё
// MeNU_LEVEL2_GWS имеет тип Level2, а MeNU_LEVEL2_GWS имеет тип 'Level2 *'. разница огромная
Ptr_MeNU_LEVEL2_GWS=MeNU_LEVEL2_GWS; [/quote] здесь надо подумать
[quote]// Возможно Вы хотели написать
[code]Ptr_MeNU_LEVEL2_GWS = &MeNU_LEVEL2_GWS;
[/uquote] я пробовал так писать, ошибки были
Добавлено after 7 minutes 50 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3337070#p3337070"]операция -> применима только к
указателю слева, операция . - только к статическому экземпляру структуры.
это я понимаю, так у меня в коде где используется операция стрелка слева указатель на структуру
а где операция точка сама структура.
И еще чисто моё личное, предвзятое, мнение: вас, случайно, не в Майкрософте программированию обучали? это у них приняты длиннючие типы с тремя и более подчеркиваниями и мешаниной заглавных и прописных букв...[/uquote]
нет к сожалению,приходиться самому и с помощью форума обучаться!Мне главное, чтоб не запутаться, при этом ничего не нарушать

Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 13:43:58
ARV
ROMan2947 писал(а):с понятиями определена, описана,объявлена, инициализирована одни путаницы.
это плохо.
если своими словами, то:
1. каждая сущность программы на Си может быть ОПИСАНА, РЕАЛИЗОВАНА и ИСПОЛЬЗОВАНА.
2. описана (объявлена) - это значит, что компилятор уведомлен о том, что в программе такая сущность МОЖЕТ существовать. где - пока не ясно
3. реализация сущности - это команда компилятору выделить память и(возможно) заполнить её какими-то данными. теперь эта сущность существует на самом деле.
4. использование - это работа с описанной и реализованой сущностью.
5. описание, реализация и использование могут быть не все сразу, а частично, минимально необходимый вариант - реализация, если её нет - считай, все остальное смысла не имеет
6. любое использование должно быть после реализации, любая реализация - после описания. и никак иначе. при этом реализация заменяет собой описание, т.е. при наличии реализации описание становится необязательным. но при наличии описания не обязательна реализация.
под сущностью я подразумеваю любую элементарную конструкцию языка Си: тип, переменную, структуру, функцию. макрос не является в строгом понимании элементом языка Си (это к препроцессору относится), и поэтому не в полной мере удовлетворяет этому описанию.
примеры
Код: Выделить всё
extern int var; // описание переменной
int var; // реализация переменной
var = 12; // использование переменной
int foo(void); // описание функции
int foo(void){
return 12;
} // реализация функции
var = foo(); // использование функции
разве тут есть путаница?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 13:56:40
ROMan2947
[uquote="ARV",url="/forum/viewtopic.php?p=3337095#p3337095"]примеры
Код: Выделить всё
extern int var; // описание переменной
int var; // реализация переменной
разве тут есть путаница?[/uquote] Страшно тонкая грань

Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 14:02:54
ARV
ничего тонкого: первая строка просто рассказывает, что где-то там (extern - вовне, снаружи) переменная типа int и идентификатором var МОЖЕТ БЫТЬ ЕСТЬ.
вторая явно показывает, что эта переменная ЕСТЬ.
другое дело, что часто применяют термин ОПРЕДЕЛЕНА вместо РЕАЛИЗОВАНА, подразумевая, что определенность - признак существования, но фактически это не корректно (хотя и широко используется). например, никогда не говорят об ОПРЕДЕЛЕНИИ методов класса, но только о РЕАЛИЗАЦИИ (это уже из С++, но сути не меняет). поэтому я сам для себя использую вышеприведенную классификацию, меня понимают все программисты, а я не путаюсь. чего и вам желаю.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 14:08:13
ROMan2947
описание структуры типа Level1. Т.е мы дали понять компилятору, что возможно есть такой тип.
Код: Выделить всё
typedef struct
{
TvvPtr PtrGWS; // пункт меню на первом уровне
TvvPtr PtrHWS; // пункт меню на первом уровне
}Level1; //---тип структуры 1 уровня
- это уже реализация так как компилятор выделяет память для структуры MeNU_LEVEL1 типа Level1 это должно находиться в исходнике модуля
Код: Выделить всё
Level1 MeNU_LEVEL1={output_level_1_GWS,output_level_1_HWS};
это использование и тоже должен быть в исходнкие
правильно мыслю?
Добавлено after 1 minute 59 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3337107#p3337107"]чего и вам желаю.[/uquote]
Спасибо!

подкинули лошадиную долю над чем поразбираться.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 14:13:58
ARV
ROMan2947 писал(а):Т.е мы дали понять компилятору, что возможно есть такой тип
нет, тип в момент описания уже существует, для него два этапа (описание и реализация) неразделимы по по определению, т.к. тип - это не материальное явление, а описательное.
ROMan2947 писал(а):правильно мыслю?
в общем и целом - да, но по-моему, Си не позволяет производить присваивания переменным структурного типа кроме как в момент реализации.
Код: Выделить всё
Level1 MeNU_LEVEL1={output_level_1_GWS,output_level_1_HWS};
такое можно написать в секции ОПРЕДЕЛЕНИЯ/ОПИСАНИЯ, но не внутри функции на этапе ИСПОЛЬЗОВАНИЯ.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 14:27:19
ROMan2947
[uquote="ARV",url="/forum/viewtopic.php?p=3337120#p3337120"][quote="ROMan2947"] но по-моему, Си не позволяет производить присваивания переменным структурного типа кроме как в момент реализации.[/uquote]да верно!
так нельзя!
Код: Выделить всё
Level1 MeNU_LEVEL1;
MeNU_LEVEL1={output_level_1_GWS,output_level_1_HWS};
а так можно!
Код: Выделить всё
Level1 MeNU_LEVEL1= {output_level_1_GWS,output_level_1_HWS};
P.S. как можно все это знать

Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 14:31:56
ARV
ROMan2947 писал(а):как можно все это знать
зададите этот вопрос самому себе примерно через годик

Re: Вопросы по С/С++ (СИ)
Добавлено: Пт мар 23, 2018 14:36:16
ROMan2947
[uquote="ARV",url="/forum/viewtopic.php?p=3337132#p3337132"]зададите этот вопрос самому себе примерно через годик

[/uquote]Дай Бог

Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 25, 2018 13:06:12
ROMan2947
Здравствуйте! Работу модуля опроса клавиатуры нужно отладить с основным модулем.
1) Опрос клавиатуры происходит по таймеру. Где нужно помещать обработчик прерывании, в основном модуле или же в исходнике модуля клавиатуры? На практике пока разницы не заметил.На данный момент обработчик я поместил в исходник главного модуля.
2) Имеется переменная BuTTOn,она объявлена в исходнике главного модуля.при прерывании по таймеру я передаю ее адрес в функцию опроса в модуль клавиатуры. Там по ее адресу присваиваю код кнопки. По выходу из прерывания идет проверка на наличие в переменной BuTTON кода,при ее наличии передаю адрес этой переменной в модуль Меню.Компилируется все хорошо,ошибок нет.Отладчиком проходил, программа производит опрос кнопок и правильно присваивает переменной BuTTON код нажатой кнопки. но не переходит в модуль меню.
3) В чем разница использования внешней переменной и работать просто с адресом переменной? я работаю с адресом переменной в сторонних модулях и ниче вроде все работает как надо.
main.h
Спойлер
Код: Выделить всё
#ifndef MAIN_H_
#define MAIN_H_
#define F_CPU 8000000UL
#include <avr/io.h>
#include <stdio.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <stdint.h>
#endif /*MAIN_H_*/
main.c
Спойлер
Код: Выделить всё
#include "main.h"
#include "Menu_v2.0.c"
#include "Menu_v2.0.h"
#include "KEY.c"
#include "KEY.h"
uint8_t BuTTON;
ISR(TIMER0_COMP_vect)
{
key(&BuTTON);
}
int main(void)
{
//--- инициализация---------------------------------------------------------
KEY_init();
sei();
while (1)
{
if(BuTTON)
{
opredelenieUkazatela(&BuTTON);
}
}
}
KEY.h
Спойлер
Код: Выделить всё
#ifndef KEY_H_
#define KEY_H_
#define KEY_DDR_OUT DDRD
#define KEY_PORT_OUT PORTD
#define KEY_DDR_IN DDRC
#define KEY_PORT_IN PORTC
#define KEY_PIN PINC
#define stroka_1 7
#define stroka_2 6
#define stolbec_1 6
#define stolbec_2 7
#define DREBESK 0x50
#define Enter 0x90 //10010000
#define Cancel 0x60 //01100000
#define DN 0x50 //01010000
#define UP 0xA0 //10100000
void KEY_init(void); // инициализация клавиатуры
void key(uint8_t*); // функция опроса клавиатуры
#endif
KEY.c
Спойлер
Код: Выделить всё
#include "KEY.h"
#include "main.h"
uint8_t RES=0;
//-------инициализация клавиатуры и таймера Т0-----------------------------
void KEY_init(void)
{
KEY_DDR_IN &=~((1<<stolbec_1)|(1<<stolbec_2));
KEY_PORT_IN|=(1<<stolbec_1)|(1<<stolbec_2);
KEY_DDR_OUT |=(1<<stroka_1)|(1<<stroka_2);
KEY_PORT_OUT|=(1<<stroka_1)|(1<<stroka_2);
TCCR0|=(1<<WGM01)|(1<<CS01)|(1<<CS00); // режим СТС, предделитель 8
TIMSK|=(1<<OCIE0); // включение прерывания при совпадении
TCNT0=0;
OCR0=254;
}
//-------------------------------------------------------------------------
void key(uint8_t*BuTTON_key)
{
uint8_t buffer=0;
static uint8_t count =0;
for(char i=stroka_1; i>=stroka_2;i--)
{
for(char i=stroka_1; i>=stroka_2;i--)
{
KEY_PORT_OUT&=~(1<<i);
RES=(KEY_PORT_OUT&0xC0)|((KEY_PIN&0xC0)>>2);
KEY_PORT_OUT|=1<<i;
switch (RES)
{
case Enter : buffer=Enter ;break;
case Cancel: buffer=Cancel ;break;
case UP : buffer=UP ;break;
case DN : buffer=DN ;break;
}
}
if(buffer)
{
if(count==DREBESK)
{
(*BuTTON_key)=buffer;
buffer=0;
count=0;
//TIMSK&=~(1<<OCIE0);
}
else count++;
}
else count=0;
}
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 25, 2018 13:37:15
da-nie
Где нужно помещать обработчик прерывании, в основном модуле или же в исходнике модуля клавиатуры?
Там, где он логически согласуется с принятой структурой программы. Если у вас принято все обработчики держать в главном модуле, то там. А если вы их хотите держать в модулях (с логикой подобное к подобному), то держите там.
Имеется переменная BuTTOn,она объявлена в исходнике главного модуля.при прерывании по таймеру я передаю ее адрес в функцию опроса в модуль клавиатуры. Там по ее адресу присваиваю код кнопки.
Вам нужен модификатор volatile при объявлении переменной BuTTOn. Компилятор не знает, что эта переменная может измениться где-то ещё, потому способен "оптимизировать" все обращения к этой переменной. Ну и красиво было бы запрещать прерывания при работе с переменной в основном потоке.
В чем разница использования внешней переменной и работать просто с адресом переменной? я работаю с адресом переменной в сторонних модулях и ниче вроде все работает как надо.
Работайте так, как вам удобно. Правда, смысла передавать адрес нет никакого в вашем случае. Объявите переменную как extern в модулях, её использующих, и она станет там доступна как обычно, по имени. Я так понимаю, вы именно из-за недоступности этой переменной в key.c и придумали передавать адрес?
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 25, 2018 13:49:10
ROMan2947
Там, где он логически согласуется с принятой структурой программы. Если у вас принято все обработчики держать в главном модуле, то там. А если вы их хотите держать в модулях (с логикой подобное к подобному), то держите там
Для меня логичнее ее держать в модуле клавиатуры,т.к. обработчик относиться к клавиатуре.Я хотел узнать наличие разницы кроме как логики.
Вам нужен модификатор volatile при объявлении переменной BuTTOn. Компилятор не знает, что эта переменная может измениться где-то ещё, потому способен "оптимизировать" все обращения к этой переменной.
Учту!Хотя изменения этой переменной происходят без проблем, да и предупреждение думаю было бы,а его нет.
Ну и красиво было бы запрещать прерывания при работе с переменной в основном потоке.
Понял!
И имейте в виду вот что - компилятор не обязан все инструкции выполнять по-порядку.
как это не обязан
это же страшно важно!!!
Я так понимаю, вы именно из-за недоступности этой переменной в key.c и придумали передавать адрес?
Нет! просто пока мне не совсем понятна работы c extern на практике, а с указателями понятно, вот решил работать с ними.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс мар 25, 2018 13:55:48
da-nie
Для меня логичнее ее держать в модуле клавиатуры,т.к. обработчик относиться к клавиатуре.Я хотел узнать наличие разницы кроме как логики.
Тогда там и держите.

Разницы никакой.
как это не обязан

это же страшно важно!!!
Вот чтобы вас не пугать и не запутать, я и стёр то, что написал.

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

Подробности вы прочтете в "Барьеры памяти и компилятора". Например, тут:
http://scrutator.me/post/2015/05/16/mem ... riers.aspx
Нет! просто пока мне не совсем понятна работы c extern на практике, а с указателями понятно, вот решил работать с ними.
На практике в модуле key.h вы пишете после #include
extern uint8_t BuTTON;
И дальше работаете с этой переменной, как с глобальной.
Учту!Хотя изменения этой переменной происходят без проблем, да и предупреждение думаю было бы,а его нет.
Предупреждения и не будет. Это не ошибка. Кстати, у вас этот самый BuTTON стоит инициализировать.
Фишка в том, что вот это:
Код: Выделить всё
if(BuTTON)
{
opredelenieUkazatela(&BuTTON);
}
после компиляции (не в Debug-конфигурации!) превратится в:
И будет выброшено из программы. А что? BuTTON внутри цикла не меняется.