Jump to content

stm32F1 меню


Ион Добрев
 Share

Recommended Posts

Решил я сделать полноценное меню для lcd используя stm32.Пересмотрел куча примеров и всё как то аморфно.С  использыванием  указателей на структуру.Кто может на пальцах объяснить?

Link to comment
Share on other sites

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Почитал ваше сообщение.
Всё как-то аморфно.
В чем проблема-то?
Не умеете работать с указателями, со структурами, или с указателями на структуры?
Сколько пунктов меню, какой дисплей?
Как тут говорят - "экстрасенсы в отпуске", что у вас в голове - никто не знает.

Link to comment
Share on other sites

8 часов назад, LiVit сказал:

Не умеете работать с указателями, со структурами, или с указателями на структуры?

Кстати в чём преимущество при работе со struct через указатель и если именно речь о создании меню ну скажем под lcd ЗНАКОСИНТЕЗИРУЮЩИЕ 20x4?

Link to comment
Share on other sites

Важные нюансы подбора литиевых ХИТ для разработчиков

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

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Преимущество по сравнению с чем?
Вообще, разговор беспредметный. Аморфный.

Какая структура меню? Сколько настроек?

У меня например, 20 настроек.
Для каждой уставки есть минимальное значение, максимальное, шаг приращения, дефолтное значение, адрес в памяти куда надо сохранять.
Есть имя настройки (текстовая подсказка, чего именно настраиваем), префикс и суффикс (кг, МГц, сек...). Причем на нескольких языках.
Вы без структур и указателей как себе такое меню представляете? Switch-case? Это трэш, угар и содомия.

Link to comment
Share on other sites

Литиевые батарейки и аккумуляторы от мирового лидера EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. EVE является поставщиком аккумуляторных элементов круглого формата для электрических моделей автомобилей.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Продукция Hongfa для различных применений в Компэл

Компания HONGFA - это не только крупнейший в мире производитель электромеханических реле, но также производитель конденсаторов, вакуумных прерывателей, трансформаторов и низковольтного коммутационного оборудования. На складе КОМПЭЛ регулярно поддерживаются около 100 самых популярных позиций электромеханических реле. Реле Hongfa могут заместить многие изделия производства недоступных брендов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

51 минуту назад, LiVit сказал:

Мне не жалко, но вы всё равно не поймёте.

К чему столько пафоса? На 1602 не делают проекты на двадцать пунктов настроек меню. И у автора вопроса, похоже, проект попроще. Тебе жалко пару слов на эту тему написать?

Хотя, @LiVit , я буду непредвзят и выдам @Ион Добрев тоже вопрос:

@Ион Добрев , ты зачем такие размытые формулировки ставишь, что не понять, не то ты на 1602 пишешь меню, не то на полноцветный ОЛЕД на кучу мегапикселей. Хочешь нормальный ответ - ставь нормальный вопрос.

Edited by Огонёк
Link to comment
Share on other sites

Причём здесь пафос? 

У меня проект как раз со структурами и указателями, которые ему недоступны. 

Мне что, вместо него программу писать? 

ТС видимо начинающий. Ему в соответствующий раздел нужно. 

Либо в раздел "работа".

Edited by LiVit
Link to comment
Share on other sites

20 минут назад, LiVit сказал:

У меня проект как раз со структурами и указателями, которые ему недоступны. 

И правда,

20 минут назад, LiVit сказал:

Причём здесь пафос? 

 

Link to comment
Share on other sites

Если  у @Ион Добрев  есть программистское мышление, желание и деньги, я могу помочь с пониманием и структур и указателей. Но это - в раздел "работа".
А разным умникам - помогите ему бесплатно, если хотите.
Почему-то никто из вас не привел свой код для меню.
Почему, интересно?

Решил потратить своё время и привести пример организации структуры меню в моих проектах, может кому пригодится:

Спойлер

Вот пример описания переменной:

typedef struct{
	uint8_t*		Hdr;	//header text
	uint8_t*		Clue;	//the clue for the user (leading text)
	uint8_t*		Trail;	//trailing text
	uint32_t		MaxVal;	//max value of the variable
	uint32_t		MinVal;	//min value of the variable
	uint32_t		DefVal;	//default value
	uint32_t		Stp;	//step of the inc/dec
	uint32_t*		VarPtr;	//pointer to the variable
}HmiVarDesc;

Пусть у нас 8 переменных (масштабируемо. хоть миллион, лишь бы FLASH памяти хватило)

Объявим энумератор с перечислением переменных

//sequence of menu items:
typedef enum{
	MNU_VAR_1,			//variable 1
	MNU_VAR_2,			//variable 2
	MNU_VAR_3,			//variable 3
	MNU_VAR_4,			//variable 4
	MNU_VAR_5,			//variable 5
	MNU_VAR_6,			//variable 6
	MNU_VAR_7,			//variable 7
	MNU_VAR_8,			//variable 8
////	
	MNU_VAR__NUM			//number of the variables
}VarList_t;		//

Теперь нам нужна область RAM, где мы будем хранить наши переменные

uint32_t	var_array[MNU_VAR__NUM] = {0};

А теперь таблица с описанием каждой переменной

const HmiVarDesc[MNU_VAR__NUM] = {
	[MNU_VAR_1].Hdr = "Variable #1",
	[MNU_VAR_1].Clue = "Frequency: ",
	[MNU_VAR_1].Trail = "MHz",
	[MNU_VAR_1].MaxVal = 500,
	[MNU_VAR_1].MinVal = 400,
	[MNU_VAR_1].DefVal = 450,
	[MNU_VAR_1].Stp = 2,
	[MNU_VAR_1].VarPtr = &var_array[MNU_VAR_1],

	[MNU_VAR_2].Hdr = "Variable #2",
	[MNU_VAR_2].Trail = "MHz",
	[MNU_VAR_2].MaxVal = 500,
	[MNU_VAR_2].MinVal = 400,
	[MNU_VAR_2].DefVal = 450,
	[MNU_VAR_2].Stp = 2,
	[MNU_VAR_2].VarPtr = &var_array[MNU_VAR_2],

	[MNU_VAR_3].Hdr = "Variable #3",
	[MNU_VAR_3].Trail = "MHz",
	[MNU_VAR_3].MaxVal = 500,
	[MNU_VAR_3].MinVal = 400,
	[MNU_VAR_3].DefVal = 450,
	[MNU_VAR_3].Stp = 2,
	[MNU_VAR_3].VarPtr = &var_array[MNU_VAR_3],

	[MNU_VAR_4].Hdr = "Variable #4",
	[MNU_VAR_4].Trail = "MHz",
	[MNU_VAR_4].MaxVal = 500,
	[MNU_VAR_4].MinVal = 400,
	[MNU_VAR_4].DefVal = 450,
	[MNU_VAR_4].Stp = 2,
	[MNU_VAR_4].VarPtr = &var_array[MNU_VAR_4],

	[MNU_VAR_5].Hdr = "Variable #5",
	[MNU_VAR_5].Trail = "MHz",
	[MNU_VAR_5].MaxVal = 500,
	[MNU_VAR_5].MinVal = 400,
	[MNU_VAR_5].DefVal = 450,
	[MNU_VAR_5].Stp = 2,
	[MNU_VAR_5].VarPtr = &var_array[MNU_VAR_5],

	[MNU_VAR_6].Hdr = "Variable #6",
	[MNU_VAR_6].Trail = "MHz",
	[MNU_VAR_6].MaxVal = 500,
	[MNU_VAR_6].MinVal = 400,
	[MNU_VAR_6].DefVal = 450,
	[MNU_VAR_6].Stp = 2,
	[MNU_VAR_6].VarPtr = &var_array[MNU_VAR_6],

	[MNU_VAR_7].Hdr = "Variable #7",
	[MNU_VAR_7].Trail = "MHz",
	[MNU_VAR_7].MaxVal = 500,
	[MNU_VAR_7].MinVal = 400,
	[MNU_VAR_7].DefVal = 450,
	[MNU_VAR_7].Stp = 2,
	[MNU_VAR_7].VarPtr = &var_array[MNU_VAR_7],

	[MNU_VAR_8].Hdr = "Variable #8",
	[MNU_VAR_8].Clue = "Weight: ",
	[MNU_VAR_8].Trail = "kg",
	[MNU_VAR_8].MaxVal = 500,
	[MNU_VAR_8].MinVal = 400,
	[MNU_VAR_8].DefVal = 450,
	[MNU_VAR_8].Stp = 2,
	[MNU_VAR_8].VarPtr = &var_array[MNU_VAR_8],

};

Всё. Переменные описаны. Теперь пишем процедуру, которая будет обрабатывать нажатие клавиш и соответствующе увеличивать/уменьшать значение переменной, отображать на экране, сохранять результат и переходить к следующей переменной.

Это самый эффективный способ. И самое главное - легко масштабируемый. Сегодня тебе нужно 8 переменных, а завтра заказчику понадобилось 128. Просто редактируем энумератор и таблицу описания переменных, а основная программа не меняется.
 

Если есть способ более эффективный - с удовольствием об этом почитаю.

12 часов назад, MechanicV сказал:

да нет у этого долбача не какого проекта, так попку мучает. 

Это вы про кого? И что дает вам уверенность это утверждать?

Link to comment
Share on other sites

Спасибо на добром слове.Я не программист по образованию.Но продвинутое(древовидное) меню для меня этап повышения знаний и умений.Начал немного понимать.Посмотрел много исходников и во всех автора не дописывают. Или перекручивают программу.Есть вариант в сайте Народ стрим stm32  или на avr.Но тоже до конца меню не показано.Я на верном пути.

[MNU_VAR_8].MaxVal = 500,

Меня интересует вот  первая структура а вторая типа структуры переменная в структуре с правой строны от точки а с лева 

typedef enum

Как то оно не понятно записано.?

Link to comment
Share on other sites

11 часов назад, Ион Добрев сказал:

Я на верном пути.

Есть русская пословица - терпение и труд всё перетрут. Будете стараться - всё получится.

[MNU_VAR_8].MaxVal = 500,

Означает, что полю MaxVal структуры номер MNU_VAR_8 данного массива присваиваем значение 500.
Вы уже знаете что такое энумератор enum?
Каждая запись превращается компилятором в число.
Начинается всё с нуля. Таким образом MNU_VAR_1 компилятором превращается в 0, MNU_VAR_2  в 1 и так далее.
enum используется только для удобства человека. Рекомендуется присваивать какие-то осмысленные имена.

typedef enum{

Это объявление типа данных enum. Можно без typedef. Но мне так привычнее - это чисто мои заморочки.

Ион, вам надо хорошенько изучить книгу «Язык программирования Си» — Брайана Кернигана и Денниса Ритчи. Там всё разжёвано.

Link to comment
Share on other sites

2 часа назад, LiVit сказал:
typedef

Я читал про эту директиву.Вообщем суть понятна вы взяли данные в структуре и в enum образовании  поместили в массив.А массив объявили соnst stuct[ и переменная RAM].

Но в enum она пишется а потом в не её объявляется  .Почему.

В 12.11.2023 в 10:08, LiVit сказал:
[MNU_VAR_8

А это номер меню и её   параметры настроек и данных.Хорошо .Сколько кнопок вы используете?.И как идёт переход допустим с DOUN на управление параметром ++(инкремент).Т как вводите информацию на LCD?

Link to comment
Share on other sites

Добрый день,
как-то давал ссылку на свой проект с меню (AVR + LCD HD44780 16x2).
https://disk.yandex.ru/d/GBRtXyNC0KdEeA
Проект лежит здесь: uC/avr_menu. Как всё выглядит можно посмотреть в Протеусе.

Также можно посмотреть как организовано меню в проекте во вложении (light.7z). Проект для PIC18F2620, но для организации меню это не принципиально.

light.7z

Link to comment
Share on other sites

Лучше всегда по месту делать.

Под конкретный проект.

Ведь и экраны могут быть разными. И клавиатура может быть по разному реализована.

Link to comment
Share on other sites

22 часа назад, MechanicV сказал:

думаю наколдовать вроде как универсальной  функции для обработки структур

Правильно. Так и надо делать.
Потом эту штуку из проекта в проект таскать и все. Просто по месту допиливая

За основу можно те структуры взять, что я привел.
Написать универсальную процедуру обработки и передавать ей указатель на "экземпляр" структуры

20 часов назад, ChePay сказал:

Ведь и экраны могут быть разными. И клавиатура может быть по разному реализована.

Ну и что? Основная обработка должна быть одинаковой.
А драйвер для клавиатуры можно допилить для конкретного устройства, как и драйвер дисплея.
У меня примерно одинаковая логика обработки как для графического монохромного дисплея, так и для символьных дисплеев.
Конечно, есть отличия. На символьном дисплее с графикой очень туго))). Инверсию не сделаешь и ограничен набор символов.

Edited by LiVit
Link to comment
Share on other sites

Менюшка дело довольно не простое. Даже вот эта графика на несчастном LCD 20x4 занимает 200 слишнем строк.

 

 

#include <hallo.h>
#include <meny.h>

// LCD module connections
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D7 at RD3_bit;

sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
short d_m;
char txt2[21];
short tempp, tm=0, page=1;

struct meny_a
{
char *mark;
int I_N;
int I_N1;
float F_L;
char C_H[5];
};
struct meny_a meny_a = {" IAmount-> IPrice--> FWieghi-> CName---> ",250,55,5.33,"name"};

struct meny_b
{
char *mark;
int I_N;
int I_N1;
float F_L;
int I_N2;
};
struct meny_b meny_b = {" IVector-> ISpeed--> FDista--> IStop---> ",1250,7123,2.23,6541};

struct meny_c
{
char *mark;
int I_N;
int I_N1;
int I_N2;
int I_N3;
};
struct meny_c meny_c = {" IBoost--> IFixing-> IUpFix--> IDownFix> ",9950,55123,12533,4852};

struct meny_d
{
char *mark;
int I_N;
char C_H[5];
int I_N1;
float F_L;
};
struct meny_d meny_d = {" IParam1-> CName---> IParam2-> FParam3-> ",7750,"name",55,1.33};

struct meny_e
{
char *mark;
};
struct meny_e meny_e = {" CMeny_1A CMeny_2A CMeny_3A CMeny_4A "};

struct meny_e1
{
char *mark;
};
struct meny_e1 meny_e1 = {" CMeny_1B CMeny_2B CMeny_3B CMeny_4B "};

struct meny_e2
{
char *mark;
};
struct meny_e2 meny_e2 = {" CMeny_1D CMeny_2D CMeny_3D CMeny_4D "};
void main() 
{
TRISE=0;
ANCON1=0b11111111;
INTCON.INT0IE=1;
INTCON.GIE=1;
INTCON.PEIE=1;
INTCON2.RBPU=0;
INTCON2.INTEDG0=0;
hallo();

//==============================================================================
while(1)
{
if(tempp != tm )
{
tm=tempp;
if(page == 1)
{
d_m = GenMeny(meny_e.mark,0,0,0,0,0,0,0,0,"","CCCC",&tempp);
if(d_m > 4)
{
page=2;
tempp=1;
}
}

if(page == 2)
{
d_m = GenMeny(meny_e1.mark,0,0,0,0,0,0,0,0,"","CCCC",&tempp);
if(d_m > 4)
{
page=3;
tempp=1;
}
}

if(page == 3)
{
d_m = GenMeny(meny_e2.mark,0,0,0,0,0,0,0,0,"","CCCC",&tempp);
if(d_m > 4)
{
page=1;
tempp=1;
}
}

sprinti(txt2, "P%-1u", page);
Lcd_Out(1,19,txt2);
}


}
}

//==============================================================================
void interrupt() 
{  
if(INTCON.INT0IF)
{
INTCON.INT0IF=0;
LATE=~LATE;
if(PORTB.RB1)
{
tempp++;
}
else if(PORTB.RB2)
{
tempp--;
}
}
}
/*d_m = GenMeny(meny_e.mark,0,0,0,0,0,0,0,0,"","CCCC");
Delay_ms(1000);
d_m = GenMeny(meny_a.mark,meny_a.I_N,meny_a.I_N1,0,0,0,0,meny_a.F_L,0,meny_a.C_H,"IIFC");
Delay_ms(1000);
d_m = GenMeny(meny_b.mark,meny_b.I_N,meny_b.I_N1,0,meny_b.I_N2,0,0,meny_b.F_L,0,"","IIFI");
Delay_ms(1000);
d_m = GenMeny(meny_c.mark,meny_c.I_N,meny_c.I_N1,meny_c.I_N2,meny_c.I_N3,0,0,0,0,"","IIII");
Delay_ms(1000);
d_m = GenMeny(meny_d.mark,meny_d.I_N,0,meny_d.I_N1,0,0,0,0,meny_d.F_L,meny_d.C_H,"ICIF");
Delay_ms(1000);
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
Delay_ms(1000);
Lcd_Cmd(_LCD_MOVE_CURSOR_LEFT);
Delay_ms(1000);
Lcd_Cmd(_LCD_SECOND_ROW);
Delay_ms(1000);
Lcd_Cmd(_LCD_THIRD_ROW);
Delay_ms(1000);*/

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Сообщения

    • Сравнивается напряжение на транзисторе с напряжением с датчика тока. ОУ, изменяя напряжение на своём выходе, "держит" равным нулю напряжение между своими входами. Получается, что он регулирует сопротивление транзистора в зависимости от тока и напряжения так, чтобы "держать" сопротивление постоянным. Если вы уберёте контроль напряжения на транзисторе (оторвёте его от неинвертирующего входа), то ОУ ничего регулировать-стабилизировать не сможет. Вернее сможет, но не то. Схема станет стабилизатором тока. Uинв.вх. = K1*U*Rш / (Rт + Rш) Uнеинв.вх. = K2*U где: K1, K2 - коэффициенты деления резистивных делителей на входах ОУ; U - напряжение на транзисторе; Rш - сопротивление токоизмерительного резистора;  Rт - сопротивление транзистора. Uинв.вх. - напряжение на инвертирующем входе ОУ; Uнеинв.вх. - напряжение на неинвертирующем входе ОУ; Операционник поддерживает их равными. K1*U*Rш / (Rт + Rш) = K2*U. Напряжение U слева и справа сокращается. Остаётся Rт очевидно равное константе, так как все остальные величины, оставшиеся в этом равенстве, - константы. Измерять напряжение на транзисторе нужно, чтобы поддерживать постоянным сопротивление транзистора вне зависимости от напряжения на нём, а вы эту связь хотите убрать.
    • А под какой магнитофон этот УВ у вас будет работать ?
    • я правильно понимаю такую схему? тогда можно использовать обычные транзисторы или всеравно ключи? тогда переформулируя вопрос, не получится ли что в момент начала срабатывания верхнего возникнет риск, что нижний "проскочит"? может быть я переформулирую вопрос- есть ли некие  характеристики среди  разных видов транзисторов, по которым транзистор может  сработать или  быть "нестабильным" в момент подачи питания? фронты не знаю какие, те которые применимы к катушке    
    • @Газзель Разработайте и рассчитайте схему, и все вопросы отпадут. Наиболее простое решение вашей задачи - сложить логически управляющие импульсы и управлять обычным ключом на одном транзисторе.
    • спасибо. я имелл ввиду сам момент включения. тость в момент срабатывания открытия верхнего, не  получится что нижний от этого может неконтролируемо коротко открыться ?  на картинке не схема, а задумка, поэтому какие празитные емкости и наводки я, честно, не представляю
    • На такой дурацкий вопрос может быть только тупой дурацкий ответ - надо перечислить названия всех известных вам сфер применения конденсаторов. А так как это невозможно, так как новые названия плодятся при появлении новых схемных решений и областей применения электроники в разных сферах жизни человека, то вариантов два. Либо этот туповатый препод удовлетворится вашим ответом, либо нет. Зависит от того, что он рассказывал про "классификацию конденсаторов" в своих лекциях и насколько хорошо вы это слушали. Открою вам преподавательскую тайну: Экзамены принимаются не на знание предмета, а на знание лекций и учебников, которые дали на кафедре.
    • И близко не лежало. Транзисторы включены по схеме "монтажное И". Нижний по схеме вывод катушки будет замкнут на "землю" только когда открыты оба транзистора. Когда закрыт хотя бы один, тока через оба транзистора и катушку нет, напряжение от источника питания плюс противоЭДС катушки, если есть, будет приложено к переходу база-коллектор верхнего по схеме транзистора. Напряжение на коллекторе нижнего по схеме транзистора будет определяться величинами паразитных ёмкостей и наводками, зависящими от крутизны фронтов переключения напряжения на катушке. В общем случае не определено, поэтому для исключения неконтролируемых выбросов, лучше поставить резистор относительно большого номинала, но достаточного для приёма тока через паразитные ёмкости без больших выбросов напряжения, с точки соединения коллектора нижнего с эмиттером верхнего на "землю". На коллекторе нижнего транзистора, если он закрыт, появится напряжение 6-0,6=5,4 В. Если открыт - верхний транзистор сгорит от превышения допустимого тока базы, так как ток в его базу ничем не ограничен. Возможно сгорит и нижний. Биполярные транзисторы управляются током, а не напряжением. В этой схеме последовательно с базами должны быть резисторы. Эту фразу надо переводить на русский язык и сопровождать картинкой схемы. Произвольный набор слов. Нет. Да.
  • Similar Content

×
×
  • Create New...