Код тестирую в протеусе по упрощённой схеме, на входы вместо компараторов кнопки с фиксацией, на выходе вместо реле светодиоды. Принцип работы таков при появлении на первом входе РВ5=0 на PD0=1; PB5=0 PB4=0 > PD0=0 PD1=1; PB5=0 PB4=0 PB3=0>PD0=1 PD1=1; PB5=0 PB4=0 PB3=0 PB2=0> PD0=1 PD1=1 PD2=1;
PB5=0 PB4=0 PB3=0 PB2=0 PB1=0> PD0=1 PD1=1 PD2=0 PD3=1;
PB5=0 PB4=0 PB3=0 PB2=0 PB1=0 PB0=0> PD0=1 PD1=1 PD2=1 PD3=1;
В написаном мною коде почемуто мигают на выходе светодиоды, не могу разобратся почему, а должны гореть!
#include <asf.h>
#define F_CPU 1000000UL //Выбор частоты микроконтроллера
#include <util/delay.h> //Программа рабочая
#include <avr/io.h>
// Макросы для управления светодиодами
//Макросы вход
#define BUTTON0_PB 0 //Каждый макрос сответствует номеру порта.
#define BUTTON1_PB 1
#define BUTTON2_PB 2
#define BUTTON3_PB 3
#define BUTTON4_PB 4
#define BUTTON5_PB 5
#define BUTTON6_PB 6
#define BUTTON7_PB 7
//Макросы выход
#define LED_B_PD 0
#define LED_O_PD 1
#define LED_G_PD 2
#define LED_Y_PD 3
#define LED_R_PD 4
#define LED_V_PD 5
#define LED_P_PD 6
#define LED_W_PD 7
int main (void) {
DDRB &= ~((1<<BUTTON0_PB)|(1<<BUTTON1_PB)|(1<<BUTTON2_PB)|(1<<BUTTON3_PB)|(1<<BUTTON4_PB)|(1<<BUTTON5_PB)|(1<<BUTTON6_PB)|(1<<BUTTON7_PB)); //порт B - вход
PORTB |= ((1<<BUTTON0_PB)|(1<<BUTTON1_PB)|(1<<BUTTON2_PB)|(1<<BUTTON3_PB)|(1<<BUTTON4_PB)|(1<<BUTTON5_PB)|(1<<BUTTON6_PB)|(1<<BUTTON7_PB)); //подключаем нагрузочный резистор
DDRD |= ((1<<LED_B_PD)|(1<<LED_O_PD)|(1<<LED_G_PD)|(1<<LED_Y_PD)|(1<<LED_R_PD)|(1<<LED_V_PD)|(1<<LED_P_PD)|(1<<LED_W_PD)); //порт D - выход
PORTD &= ~((1<<LED_B_PD)|(1<<LED_O_PD)|(1<<LED_G_PD)|(1<<LED_Y_PD)|(1<<LED_R_PD)|(1<<LED_V_PD)|(1<<LED_P_PD)|(1<<LED_W_PD)); //устанавливаем 0 на выходе D
while(1)
{
if ( (PINB & 1<<BUTTON5_PB) == 0 ) { // Опрос порта.кнопки 1
PORTD |= 1<<LED_O_PD ;//Включаем первое реле при замыкании выключателя
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(50);
}
if( (PINB & 1<<BUTTON4_PB) == 0 ) { //Опрос порта.кнопки 2
PORTD |= 1<<LED_Y_PD; //Включаем второе реле при замыкании выключателя
PORTD &= ~(1<<LED_O_PD); //Выключаем первое реле при замыкании выключателя
}
else {
PORTD &= ~(1<<LED_Y_PD); // Выключаем второе реле при размыкании выключателя
_delay_ms(50);
}
if( (PINB & 1<<BUTTON3_PB) == 0 ) { //Опрос порта.кнопки3
PORTD |= ((1<<LED_O_PD)|(1<<LED_Y_PD)); //Включаем первое и второе реле при замыкании выключателя
}
else {
PORTD &= ~((1<<LED_B_PD)|(1>>LED_Y_PD)); //Выключаем первое и второе реле
_delay_ms(50);
}
if( (PINB & 1<<BUTTON2_PB) == 0 ) { //Опрос порта.кнопки 4
PORTD |= ((1<<LED_O_PD)|(1<<LED_Y_PD)|(1<<LED_B_PD)); //Включаем первое, второе и третье реле при замыкании выключателя
}
else {
PORTD &= ~(1<<LED_B_PD); //Выключаем третье реле
_delay_ms(50);
}
if( (PINB & 1<<BUTTON1_PB) == 0 ) { //Опрос порта.кнопки 5
PORTD |= ((1<<LED_O_PD)|(1<<LED_Y_PD)|(1<<LED_G_PD)); //Включаем первое, второе, четвёртое реле при замыкании выключателя
PORTD &= ~(1<<LED_B_PD); //Выключаем третье реле
}
else {
PORTD &= ~(1<<LED_G_PD); //Выключаем реле при размыкании выключателя
_delay_ms(50);
}
if( (PINB & 1<<BUTTON0_PB) == 0 ) { //Опрос порта.кнопки6
PORTD |= ((1<<LED_O_PD)|(1<<LED_Y_PD)|(1<<LED_G_PD)|(1<<LED_B_PD)); //Включаем первое, второе, третье, четвёртое реле при замыкании выключателя
}
else {
PORTD &= ~((1<<LED_O_PD)|(1<<LED_Y_PD)|(1<<LED_G_PD)|(1<<LED_B_PD));
_delay_ms(50);
}
}
}
1. Начинающий - 09 Августа, 2025 - 13:03:59 - перейти к сообщению
2. Admin - 09 Августа, 2025 - 20:34:08 - перейти к сообщению
Возможно, имеет место явление дребезга контактов...
(Добавление)
Попробуйте поставить задержку
_delay_ms(100);
во всех случаях переключений
(Добавление)
Про дребезг контактов можно почитать здесь: https://myrobot.ru/stepbystep/mc...esp32_button.php
(Добавление)
Попробуйте поставить задержку
_delay_ms(100);
во всех случаях переключений
CODE:
if ( (PINB & 1<<BUTTON5_PB) == 0 ) { // Опрос порта.кнопки 1
PORTD |= 1<<LED_O_PD ;//Включаем первое реле при замыкании выключателя
_delay_ms(100);
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(100);
}
PORTD |= 1<<LED_O_PD ;//Включаем первое реле при замыкании выключателя
_delay_ms(100);
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(100);
}
(Добавление)
Про дребезг контактов можно почитать здесь: https://myrobot.ru/stepbystep/mc...esp32_button.php
3. Начинающий - 10 Августа, 2025 - 10:24:20 - перейти к сообщению
Спасибо за участие. Пробовал и так всё равно мигают. Дребезга контактов нет так как кнопки фиксируются (в протеусе)! И при выстовлении времени задержки влияет на мигание светодиодов!
4. Admin - 10 Августа, 2025 - 11:34:33 - перейти к сообщению
Логику тоже надо менять
нажали кнопку 1, включилось первое реле
if ( (PINB & 1<<BUTTON5_PB) == 0 ) { // Опрос порта.кнопки 1
PORTD |= 1<<LED_O_PD ;//Включаем первое реле при замыкании выключателя
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(50);
}
...
чуть дальше в программе (кнопка 3 не нажата), выключилось первое реле
if( (PINB & 1<<BUTTON3_PB) == 0 ) { //Опрос порта.кнопки3
PORTD |= ((1<<LED_O_PD)|(1<<LED_Y_PD)); //Включаем первое и второе реле при замыкании выключателя
}
else {
PORTD &= ~((1<<LED_B_PD)|(1>>LED_Y_PD)); //Выключаем первое и второе реле
_delay_ms(50);
}
нажали кнопку 1, включилось первое реле
if ( (PINB & 1<<BUTTON5_PB) == 0 ) { // Опрос порта.кнопки 1
PORTD |= 1<<LED_O_PD ;//Включаем первое реле при замыкании выключателя
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(50);
}
...
чуть дальше в программе (кнопка 3 не нажата), выключилось первое реле
if( (PINB & 1<<BUTTON3_PB) == 0 ) { //Опрос порта.кнопки3
PORTD |= ((1<<LED_O_PD)|(1<<LED_Y_PD)); //Включаем первое и второе реле при замыкании выключателя
}
else {
PORTD &= ~((1<<LED_B_PD)|(1>>LED_Y_PD)); //Выключаем первое и второе реле
_delay_ms(50);
}
5. Начинающий - 10 Августа, 2025 - 13:12:38 - перейти к сообщению
Огромное спасибо за участие, исправил ваше замечание итог тот же. Привожу исправленый код. Ниже этого приведу код который хочу попробывать вместо этого, только никак не соображу как там продлить (кнопки добавить).
#include <asf.h>
#define F_CPU 1000000UL //Выбор частоты микроконтроллера
#include <util/delay.h> //Программа рабочая
#include <avr/io.h>
// Макросы для управления светодиодами
//Макросы вход
#define BUTTON0_PB 0 //Каждый макрос сответствует номеру порта.
#define BUTTON1_PB 1
#define BUTTON2_PB 2
#define BUTTON3_PB 3
#define BUTTON4_PB 4
#define BUTTON5_PB 5
#define BUTTON6_PB 6
#define BUTTON7_PB 7
//Макросы выход
#define LED_B_PD 0
#define LED_O_PD 1
#define LED_G_PD 2
#define LED_Y_PD 3
#define LED_R_PD 4
#define LED_V_PD 5
#define LED_P_PD 6
#define LED_W_PD 7
int main (void) {
DDRB &= ~((1<<BUTTON0_PB)|(1<<BUTTON1_PB)|(1<<BUTTON2_PB)|(1<<BUTTON3_PB)|(1<<BUTTON4_PB)|(1<<BUTTON5_PB)|(1<<BUTTON6_PB)|(1<<BUTTON7_PB)); //порт B - вход
PORTB |= ((1<<BUTTON0_PB)|(1<<BUTTON1_PB)|(1<<BUTTON2_PB)|(1<<BUTTON3_PB)|(1<<BUTTON4_PB)|(1<<BUTTON5_PB)|(1<<BUTTON6_PB)|(1<<BUTTON7_PB)); //подключаем нагрузочный резистор
DDRD |= ((1<<LED_B_PD)|(1<<LED_O_PD)|(1<<LED_G_PD)|(1<<LED_Y_PD)|(1<<LED_R_PD)|(1<<LED_V_PD)|(1<<LED_P_PD)|(1<<LED_W_PD)); //порт D - выход
PORTD &= ~((1<<LED_B_PD)|(1<<LED_O_PD)|(1<<LED_G_PD)|(1<<LED_Y_PD)|(1<<LED_R_PD)|(1<<LED_V_PD)|(1<<LED_P_PD)|(1<<LED_W_PD)); //устанавливаем 0 на выходе D
while(1)
{
if ((PINB& (1 << BUTTON5_PB)) == 0 ) { // Опрос порта.кнопки 1
PORTD |= 1 << LED_O_PD ;//Включаем первое реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(50);
}
if((PINB& (1 << BUTTON4_PB)) == 0 ) { //Опрос порта.кнопки 2
PORTD |= 1 << LED_Y_PD; //Включаем второе реле при замыкании выключателя
PORTD &= ~(1 << LED_O_PD); //Выключаем первое реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~(1 << LED_Y_PD); // Выключаем второе реле при размыкании выключателя
_delay_ms(50);
}
if((PINB& (1 << BUTTON3_PB)) == 0 ) { //Опрос порта.кнопки3
PORTD |= ((1 << LED_O_PD)|(1 << LED_Y_PD)); //Включаем первое и второе реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~((1 << LED_O_PD)|(1 << LED_Y_PD)); //Выключаем первое и второе реле
_delay_ms(50);
}
if((PINB& (1 << BUTTON2_PB)) == 0 ) { //Опрос порта.кнопки 4
PORTD |= (( 1<< LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_B_PD)); //Включаем первое, второе и третье реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~((1 << LED_B_PD)|( 1<< LED_O_PD)|(1 << LED_Y_PD)); //Выключаем третье реле
_delay_ms(50);
}
if((PINB& (1 << BUTTON1_PB)) == 0 ) { //Опрос порта.кнопки 5
PORTD |= ((1 << LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_G_PD)); //Включаем первое, второе, четвёртое реле при замыкании выключателя
PORTD &= ~(1 << LED_B_PD); //Выключаем третье реле
_delay_ms(50);
}
else {
PORTD &= ~((1<<LED_G_PD)|(1 << LED_O_PD)|(1 << LED_Y_PD)); //Выключаем реле при размыкании выключателя
_delay_ms(50);
}
if((PINB& (1 << BUTTON0_PB)) == 0 ) { //Опрос порта.кнопки6
PORTD |= ((1 << LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_G_PD)|(1 << LED_B_PD)); //Включаем первое, второе, третье, четвёртое реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~((1 << LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_G_PD)|(1 << LED_B_PD));
_delay_ms(50);
}
}
}
Этот код более лучше в плане задержки, вот только не соображу как продлить его в моём случае.
#define F_CPU 1000000UL //Выбираем частоту микроконтроллера
#include <avr/io.h> // подключение параметров микроконтроллера из библиотеки
#include <util/delay.h> //Включаем функцию задержек
int main (void)
{//Нало основной программы
unsigned char butcount =0;
DDRB = 0b00000000; //Устанавливаем вывод порта на вход
PORTB = 0b11111111;
DDRD = 0b11111111;//Устанавливаем вывод порта на выход
PORTD = 0b00000000;
while(1)
{
if (!(PINB&0b00000010)) //Начало цикла
{
if (butcount <5)
{
butcount ++;
}
else
{
PORTD = 0b00000001;
}
}
else
{
if (butcount >0)
{
butcount --;
}
else
{
PORTD = 0b00000000;
}
}
}
}
Будте добры подсказать что лучше и что делать дальше. Просто я с этим блоком питания вожусь уже 2 год из за этого!
#include <asf.h>
#define F_CPU 1000000UL //Выбор частоты микроконтроллера
#include <util/delay.h> //Программа рабочая
#include <avr/io.h>
// Макросы для управления светодиодами
//Макросы вход
#define BUTTON0_PB 0 //Каждый макрос сответствует номеру порта.
#define BUTTON1_PB 1
#define BUTTON2_PB 2
#define BUTTON3_PB 3
#define BUTTON4_PB 4
#define BUTTON5_PB 5
#define BUTTON6_PB 6
#define BUTTON7_PB 7
//Макросы выход
#define LED_B_PD 0
#define LED_O_PD 1
#define LED_G_PD 2
#define LED_Y_PD 3
#define LED_R_PD 4
#define LED_V_PD 5
#define LED_P_PD 6
#define LED_W_PD 7
int main (void) {
DDRB &= ~((1<<BUTTON0_PB)|(1<<BUTTON1_PB)|(1<<BUTTON2_PB)|(1<<BUTTON3_PB)|(1<<BUTTON4_PB)|(1<<BUTTON5_PB)|(1<<BUTTON6_PB)|(1<<BUTTON7_PB)); //порт B - вход
PORTB |= ((1<<BUTTON0_PB)|(1<<BUTTON1_PB)|(1<<BUTTON2_PB)|(1<<BUTTON3_PB)|(1<<BUTTON4_PB)|(1<<BUTTON5_PB)|(1<<BUTTON6_PB)|(1<<BUTTON7_PB)); //подключаем нагрузочный резистор
DDRD |= ((1<<LED_B_PD)|(1<<LED_O_PD)|(1<<LED_G_PD)|(1<<LED_Y_PD)|(1<<LED_R_PD)|(1<<LED_V_PD)|(1<<LED_P_PD)|(1<<LED_W_PD)); //порт D - выход
PORTD &= ~((1<<LED_B_PD)|(1<<LED_O_PD)|(1<<LED_G_PD)|(1<<LED_Y_PD)|(1<<LED_R_PD)|(1<<LED_V_PD)|(1<<LED_P_PD)|(1<<LED_W_PD)); //устанавливаем 0 на выходе D
while(1)
{
if ((PINB& (1 << BUTTON5_PB)) == 0 ) { // Опрос порта.кнопки 1
PORTD |= 1 << LED_O_PD ;//Включаем первое реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~(1 << LED_O_PD); // Выключаем первое реле при размыкании выключателя
_delay_ms(50);
}
if((PINB& (1 << BUTTON4_PB)) == 0 ) { //Опрос порта.кнопки 2
PORTD |= 1 << LED_Y_PD; //Включаем второе реле при замыкании выключателя
PORTD &= ~(1 << LED_O_PD); //Выключаем первое реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~(1 << LED_Y_PD); // Выключаем второе реле при размыкании выключателя
_delay_ms(50);
}
if((PINB& (1 << BUTTON3_PB)) == 0 ) { //Опрос порта.кнопки3
PORTD |= ((1 << LED_O_PD)|(1 << LED_Y_PD)); //Включаем первое и второе реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~((1 << LED_O_PD)|(1 << LED_Y_PD)); //Выключаем первое и второе реле
_delay_ms(50);
}
if((PINB& (1 << BUTTON2_PB)) == 0 ) { //Опрос порта.кнопки 4
PORTD |= (( 1<< LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_B_PD)); //Включаем первое, второе и третье реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~((1 << LED_B_PD)|( 1<< LED_O_PD)|(1 << LED_Y_PD)); //Выключаем третье реле
_delay_ms(50);
}
if((PINB& (1 << BUTTON1_PB)) == 0 ) { //Опрос порта.кнопки 5
PORTD |= ((1 << LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_G_PD)); //Включаем первое, второе, четвёртое реле при замыкании выключателя
PORTD &= ~(1 << LED_B_PD); //Выключаем третье реле
_delay_ms(50);
}
else {
PORTD &= ~((1<<LED_G_PD)|(1 << LED_O_PD)|(1 << LED_Y_PD)); //Выключаем реле при размыкании выключателя
_delay_ms(50);
}
if((PINB& (1 << BUTTON0_PB)) == 0 ) { //Опрос порта.кнопки6
PORTD |= ((1 << LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_G_PD)|(1 << LED_B_PD)); //Включаем первое, второе, третье, четвёртое реле при замыкании выключателя
_delay_ms(50);
}
else {
PORTD &= ~((1 << LED_O_PD)|(1 << LED_Y_PD)|(1 << LED_G_PD)|(1 << LED_B_PD));
_delay_ms(50);
}
}
}
Этот код более лучше в плане задержки, вот только не соображу как продлить его в моём случае.
#define F_CPU 1000000UL //Выбираем частоту микроконтроллера
#include <avr/io.h> // подключение параметров микроконтроллера из библиотеки
#include <util/delay.h> //Включаем функцию задержек
int main (void)
{//Нало основной программы
unsigned char butcount =0;
DDRB = 0b00000000; //Устанавливаем вывод порта на вход
PORTB = 0b11111111;
DDRD = 0b11111111;//Устанавливаем вывод порта на выход
PORTD = 0b00000000;
while(1)
{
if (!(PINB&0b00000010)) //Начало цикла
{
if (butcount <5)
{
butcount ++;
}
else
{
PORTD = 0b00000001;
}
}
else
{
if (butcount >0)
{
butcount --;
}
else
{
PORTD = 0b00000000;
}
}
}
}
Будте добры подсказать что лучше и что делать дальше. Просто я с этим блоком питания вожусь уже 2 год из за этого!
6. Admin - 10 Августа, 2025 - 19:28:17 - перейти к сообщению
Эх, если бы хотя бы приблизительно понимать, что вы хотите...
7. Начинающий - 11 Августа, 2025 - 06:29:39 - перейти к сообщению
Мне нужна программа для переключения реле в Блоке питания, которая бы работала от срабатывания 6 компараторов по мере возрастания напряжения на выходе БП в автоматическом режиме и двух кнопок (+/-) в ручном режиме. Соответственно ещё одна кнопка для переключения режима.
В качестве входа для компараторов (разводка на плате) мне лучше всего подходят порт PC5…..PC0(6) или PB5….PB0, PB6 и PB7 кнопки+/-(ручное управление)
В качестве выхода при срабатывании компараторов PD0….PD3, В качестве выхода(ручное управление) при срабатывании кнопок PD4…PD7.
Поскольку компараторы можно прировнять к кнопкам то необходима задержка на срабатывание.
Логика работы:
При повышении напряжения на выходе БП
При появлении на PC5(PВ5) логического 0 на PD1 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) логического 0 то на PD1 появляется лог 0 на PD2 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) + PC2(PВ2) логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1 на PD0 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) + PC2(PВ2) + PC1(PВ1) логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1 на PD3 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) + PC2(PВ2) + PC1(PВ1) + PC0(PВ0)логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1 на PD3 появляется лог 1 на PD0 появляется лог 1
При понижении напряжения в обратном порядке.
При работе кнопки РВ6 +
При первом нажатии на PD5 появляется лог 1
При втором нажатии на PD5 появляется лог 0 на PD6 появляется лог 1
При третьем нажатии на PD5 появляется лог 1 на PD6 появляется лог 1
При четвёртом нажатии на PD5 появляется лог 1 на PD6 появляется лог 1 на PD4 появляется лог 1
При пятом нажатии на PD5 появляется лог 1 на PD6 появляется лог 1 на PD7 появляется лог 1
При пятом нажатии на PD5 появляется лог 1 на PD6 появляется лог 1 на PD7 появляется лог 1 на PD4 появляется лог 1
При работе кнопки минус РВ7 – всё в обратном порядке.
В качестве входа для компараторов (разводка на плате) мне лучше всего подходят порт PC5…..PC0(6) или PB5….PB0, PB6 и PB7 кнопки+/-(ручное управление)
В качестве выхода при срабатывании компараторов PD0….PD3, В качестве выхода(ручное управление) при срабатывании кнопок PD4…PD7.
Поскольку компараторы можно прировнять к кнопкам то необходима задержка на срабатывание.
Логика работы:
При повышении напряжения на выходе БП
При появлении на PC5(PВ5) логического 0 на PD1 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) логического 0 то на PD1 появляется лог 0 на PD2 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) + PC2(PВ2) логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1 на PD0 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) + PC2(PВ2) + PC1(PВ1) логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1 на PD3 появляется лог 1
При появлении на PC5(PВ5) + PC4(PВ4) + PC3(PВ3) + PC2(PВ2) + PC1(PВ1) + PC0(PВ0)логического 0 то на PD1 появляется лог 1 на PD2 появляется лог 1 на PD3 появляется лог 1 на PD0 появляется лог 1
При понижении напряжения в обратном порядке.
При работе кнопки РВ6 +
При первом нажатии на PD5 появляется лог 1
При втором нажатии на PD5 появляется лог 0 на PD6 появляется лог 1
При третьем нажатии на PD5 появляется лог 1 на PD6 появляется лог 1
При четвёртом нажатии на PD5 появляется лог 1 на PD6 появляется лог 1 на PD4 появляется лог 1
При пятом нажатии на PD5 появляется лог 1 на PD6 появляется лог 1 на PD7 появляется лог 1
При пятом нажатии на PD5 появляется лог 1 на PD6 появляется лог 1 на PD7 появляется лог 1 на PD4 появляется лог 1
При работе кнопки минус РВ7 – всё в обратном порядке.
8. Admin - 12 Августа, 2025 - 12:13:11 - перейти к сообщению
Я ничего не понял, но, мне кажется, вам стоит составить таблицу истинности, а потом запрограммировать ее "в лоб" с помощью набора условий, которые будут отслеживать все возможные наборы входных сигналов.
Каждое условие может выглядеть примерно так:
(Добавление)
тоже самое для кнопок + -
Кнопка + увеличивает переменную butcount на единицу, если не дошли до верхнего порога
Кнопка - уменьшает переменную butcount на единицу, если не дошли до нижнего порога
и набор условий
Каждое условие может выглядеть примерно так:
CODE:
если PC1 == 0 и PC2 == 1 и PC3 == 0 и PC4 == 1 и PC5 == 0 {
PD1 = 1;
PD2 = 1;
PD3 = 0;
PD4 = 1;
PD5 = 0;
}
PD1 = 1;
PD2 = 1;
PD3 = 0;
PD4 = 1;
PD5 = 0;
}
(Добавление)
тоже самое для кнопок + -
Кнопка + увеличивает переменную butcount на единицу, если не дошли до верхнего порога
Кнопка - уменьшает переменную butcount на единицу, если не дошли до нижнего порога
и набор условий
CODE:
если butcount == 1 {
PD1 = 1;
PD2 = 1;
PD3 = 0;
PD4 = 1;
PD5 = 0;
}
если butcount == 2 {
PD1 = 0;
PD2 = 0;
PD3 = 1;
PD4 = 1;
PD5 = 0;
}
...
если butcount == 1 {
PD1 = 1;
PD2 = 1;
PD3 = 0;
PD4 = 1;
PD5 = 0;
}
если butcount == 2 {
PD1 = 0;
PD2 = 0;
PD3 = 1;
PD4 = 1;
PD5 = 0;
}
...
9. Начинающий - 13 Августа, 2025 - 09:52:18 - перейти к сообщению
Спасибо большое за участие смысл примерно понял попробую. Хотелось бы узнать ещё один момент, при написании кода я столкнулся с тем что при проектировании порта PC на вход, то на входные сигналы 1/0 реагировали всего два порта(ноги) микроконтроллера (порт RESET во внимание не берем). То есть при команде DDRC = 0b0000000; грубо говоря на входные сигналы реагировали всего PC0 PC1, на выход без проблем. Связано ли это что этот порт работает и с другими сигналами, а также ШИМ.
10. Admin - 13 Августа, 2025 - 12:04:20 - перейти к сообщению
Порт C у Atmega8 содержит семь битов.
Кроме направления порта
DDRC = 0b0000000;
неплохо выставить еще внутренние подтягивающие резисторы, чтобы выводы не болтались в неизвестности.
Для высокого уровня:
PORTС = 0b1111111;
Тогда управляющий сигнал будет 0.
https://myrobot.ru/stepbystep/pr_mcports.php
Кроме направления порта
DDRC = 0b0000000;
неплохо выставить еще внутренние подтягивающие резисторы, чтобы выводы не болтались в неизвестности.
Для высокого уровня:
PORTС = 0b1111111;
Тогда управляющий сигнал будет 0.
https://myrobot.ru/stepbystep/pr_mcports.php
11. Начинающий - 13 Августа, 2025 - 18:06:24 - перейти к сообщению
Спасибо за ответ , я всё так и делал, плюс к этому схематически в Протеусе добавлял резисторы по 10к ко всем входным портам.
12. Начинающий - 27 Августа, 2025 - 13:18:18 - перейти к сообщению
Помогите объеденить два кода в один. Как это сделать?
13. Admin - 27 Августа, 2025 - 15:52:37 - перейти к сообщению
Можно сделать переключалку, которая будет триггериться кнопкой и переключать переменную режима.
Если переменная режима равна 0, то выполнять КОД1. Если переменная режима равна 1, выполнять КОД2.
Если переменная режима равна 0, то выполнять КОД1. Если переменная режима равна 1, выполнять КОД2.
14. Начинающий - 28 Августа, 2025 - 08:09:23 - перейти к сообщению
Я согласен вот попытка соеденить код в нем не работают две кнопки PB5 PB4, PC0 ...PC5 работают. Как сделать так чтобы PB5 PB4заработали. Если вы специалист то помогите а если поприкалываться то спасибо, и не надо советовать применить два микроконтроллера.
Атмега 8
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Прототип функции
// void update_leds(void);
// Определяем пины для кнопок и светодиодов
#define BUTTON1_PIN PC5 // Кнопка 1 на порту B, пин 0
#define BUTTON2_PIN PC4 // Кнопка 2 на порту B, пин 1
#define BUTTON3_PIN PC3 // Кнопка 3 на порту B, пин 1
#define BUTTON4_PIN PC2 // Кнопка 4 на порту B, пин 1
#define BUTTON5_PIN PC1 // Кнопка 5 на порту B, пин 1
#define BUTTON6_PIN PC0 // Кнопка 6 на порту B, пин 1
#define BUTTON_UP_PIN PB5 // Кнопка увеличения +
#define BUTTON_DOWN_PIN PB4 // Кнопка уменьшения -
#define LED1_PIN PD0 // Светодиод 1 на порту D, пин 0
#define LED2_PIN PD1 // Светодиод 2 на порту D, пин 1
#define LED3_PIN PD2 // Светодиод 3 на порту D, пин 2
#define LED4_PIN PD3 // Светодиод 4 на порту D, пин 3
#define LED_PD4 PD4 // Светодиод 4 на порту D
#define LED_PD5 PD5 // Светодиод 5 на порту D
#define LED_PD6 PD6 // Светодиод 6 на порту D
#define LED_PD7 PD7 // Светодиод 7 на порту D
// Состояние светодиодов PD4-PD7
uint8_t state = 0; // Начальное состояние (все выключены)
uint8_t last_buttons = 0;
// Функция обновления светодиодов
void update_leds(void) {
PORTD = 0x00; // Очищаем все биты
switch(state) {
case 0: break;
case 1: PORTD |= (1 << LED_PD5); break;
case 2: PORTD |= (1 << LED_PD6); break;
case 3: PORTD |= ((1 << LED_PD6) | (1 << LED_PD5)); break;
case 4: PORTD |= ((1 << LED_PD4) | (1 << LED_PD6) | (1 << LED_PD5)); break;
case 5: PORTD |= ((1 << LED_PD7) | (1 << LED_PD6) | (1 << LED_PD5)); break;
case 6: PORTD |= ((1 << LED_PD4) | (1 << LED_PD5) | (1 << LED_PD6) | (1 << LED_PD7)); break;
}
}
int main(void)
{
// Настройка портов
DDRC &= ~(_BV(BUTTON1_PIN) | _BV(BUTTON2_PIN) | _BV(BUTTON3_PIN) | _BV(BUTTON4_PIN) | _BV(BUTTON5_PIN) | _BV(BUTTON6_PIN)); // Входы для кнопок
PORTC |= _BV(BUTTON1_PIN) | _BV(BUTTON2_PIN) | _BV(BUTTON3_PIN) | _BV(BUTTON4_PIN) | _BV(BUTTON5_PIN) | _BV(BUTTON6_PIN); // Подтягивающие резисторы
DDRD |= (_BV(LED1_PIN) | _BV(LED2_PIN) | _BV(LED3_PIN) | _BV(LED4_PIN) | (1 << LED_PD4) | (1 << LED_PD5) | (1 << LED_PD6) | (1 << LED_PD7)); // Выходы для светодиодов
// DDRD |= _BV(LED_UP_PIN) | _BV(LED_DOWN_PIN) | _BV(LED_LEFT_PIN) | _BV(LED_RIGHT_PIN); // Выходы для новых светодиодов
DDRB &= ~((1 << BUTTON_UP_PIN) | (1 << BUTTON_DOWN_PIN)); // Входы для кнопок
PORTB |= (1 << BUTTON_UP_PIN) | (1 << BUTTON_DOWN_PIN); // Подтягивающие резисторы
while(1)
это начало.
(Добавление)
Я согласен вот попытка соеденить код в нем не работают две кнопки PB5 PB4, PC0 ...PC5 работают. Как сделать так чтобы PB5 PB4заработали. Если вы специалист то помогите а если поприкалываться то спасибо, и не надо советовать применить два микроконтроллера.
Это вторая часть
{
// Считываем состояние кнопок
uint8_t button1 = (PINC & _BV(BUTTON1_PIN)) == 0; // 1 если нажата
uint8_t button2 = (PINC & _BV(BUTTON2_PIN)) == 0; // 1 если нажата
uint8_t button3 = (PINC & _BV(BUTTON3_PIN)) == 0; // 1 если нажата
uint8_t button4 = (PINC & _BV(BUTTON4_PIN)) == 0; // 1 если нажата
uint8_t button5 = (PINC & _BV(BUTTON5_PIN)) == 0; // 1 если нажата
uint8_t button6 = (PINC & _BV(BUTTON6_PIN)) == 0; // 1 если нажата
// uint8_t buttons = (PINB & ((1 << BUTTON_UP_PIN) | (1 << BUTTON_DOWN_PIN)));
uint8_t buttons = PINB;
// Обработка кнопки увеличения
if ((buttons & (1 << BUTTON_UP_PIN)) == 0) {
if ((last_buttons & (1 << BUTTON_UP_PIN)) != 0) {
state = (state + 1) % 7;
// update_leds();
}
}
// Обработка кнопки уменьшения
if ((buttons & (1 << BUTTON_DOWN_PIN)) == 0) {
if ((last_buttons & (1 << BUTTON_DOWN_PIN)) != 0) {
state = (state == 0) ? 6 : state - 1;
// update_leds();
}
}
last_buttons = buttons;
// Обработка комбинаций основных кнопок
if (button1 && !button2 && !button3 && !button4 && !button5 && !button6) {
// Нажата только кнопка 1
PORTD = (1 << LED1_PIN);
}
else if (button1 && button2 && !button3 && !button4 && !button5 && !button6) {
// Нажаты кнопки 1 и 2
PORTD = (1 << LED2_PIN);
}
else if (button1 && button2 && button3 && !button4 && !button5 && !button6) {
// Нажаты кнопки 1-3
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN);
}
else if (button1 && button2 && button3 && button4 && !button5 && !button6) {
// Нажаты кнопки 1-4
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED3_PIN);
}
else if (button1 && button2 && button3 && button4 && button5 && !button6) {
// Нажаты кнопки 1-5
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED4_PIN);
}
else if (button1 && button2 && button3 && button4 && button5 && button6) {
// Нажаты все кнопки
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED3_PIN) | (1 << LED4_PIN);
}
else {
// Нет нажатых кнопок
PORTD = 0;
}
_delay_ms(20); // Дебаунс задержка
}
return 0;
}
Атмега 8
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Прототип функции
// void update_leds(void);
// Определяем пины для кнопок и светодиодов
#define BUTTON1_PIN PC5 // Кнопка 1 на порту B, пин 0
#define BUTTON2_PIN PC4 // Кнопка 2 на порту B, пин 1
#define BUTTON3_PIN PC3 // Кнопка 3 на порту B, пин 1
#define BUTTON4_PIN PC2 // Кнопка 4 на порту B, пин 1
#define BUTTON5_PIN PC1 // Кнопка 5 на порту B, пин 1
#define BUTTON6_PIN PC0 // Кнопка 6 на порту B, пин 1
#define BUTTON_UP_PIN PB5 // Кнопка увеличения +
#define BUTTON_DOWN_PIN PB4 // Кнопка уменьшения -
#define LED1_PIN PD0 // Светодиод 1 на порту D, пин 0
#define LED2_PIN PD1 // Светодиод 2 на порту D, пин 1
#define LED3_PIN PD2 // Светодиод 3 на порту D, пин 2
#define LED4_PIN PD3 // Светодиод 4 на порту D, пин 3
#define LED_PD4 PD4 // Светодиод 4 на порту D
#define LED_PD5 PD5 // Светодиод 5 на порту D
#define LED_PD6 PD6 // Светодиод 6 на порту D
#define LED_PD7 PD7 // Светодиод 7 на порту D
// Состояние светодиодов PD4-PD7
uint8_t state = 0; // Начальное состояние (все выключены)
uint8_t last_buttons = 0;
// Функция обновления светодиодов
void update_leds(void) {
PORTD = 0x00; // Очищаем все биты
switch(state) {
case 0: break;
case 1: PORTD |= (1 << LED_PD5); break;
case 2: PORTD |= (1 << LED_PD6); break;
case 3: PORTD |= ((1 << LED_PD6) | (1 << LED_PD5)); break;
case 4: PORTD |= ((1 << LED_PD4) | (1 << LED_PD6) | (1 << LED_PD5)); break;
case 5: PORTD |= ((1 << LED_PD7) | (1 << LED_PD6) | (1 << LED_PD5)); break;
case 6: PORTD |= ((1 << LED_PD4) | (1 << LED_PD5) | (1 << LED_PD6) | (1 << LED_PD7)); break;
}
}
int main(void)
{
// Настройка портов
DDRC &= ~(_BV(BUTTON1_PIN) | _BV(BUTTON2_PIN) | _BV(BUTTON3_PIN) | _BV(BUTTON4_PIN) | _BV(BUTTON5_PIN) | _BV(BUTTON6_PIN)); // Входы для кнопок
PORTC |= _BV(BUTTON1_PIN) | _BV(BUTTON2_PIN) | _BV(BUTTON3_PIN) | _BV(BUTTON4_PIN) | _BV(BUTTON5_PIN) | _BV(BUTTON6_PIN); // Подтягивающие резисторы
DDRD |= (_BV(LED1_PIN) | _BV(LED2_PIN) | _BV(LED3_PIN) | _BV(LED4_PIN) | (1 << LED_PD4) | (1 << LED_PD5) | (1 << LED_PD6) | (1 << LED_PD7)); // Выходы для светодиодов
// DDRD |= _BV(LED_UP_PIN) | _BV(LED_DOWN_PIN) | _BV(LED_LEFT_PIN) | _BV(LED_RIGHT_PIN); // Выходы для новых светодиодов
DDRB &= ~((1 << BUTTON_UP_PIN) | (1 << BUTTON_DOWN_PIN)); // Входы для кнопок
PORTB |= (1 << BUTTON_UP_PIN) | (1 << BUTTON_DOWN_PIN); // Подтягивающие резисторы
while(1)
это начало.
(Добавление)
Я согласен вот попытка соеденить код в нем не работают две кнопки PB5 PB4, PC0 ...PC5 работают. Как сделать так чтобы PB5 PB4заработали. Если вы специалист то помогите а если поприкалываться то спасибо, и не надо советовать применить два микроконтроллера.
Это вторая часть
{
// Считываем состояние кнопок
uint8_t button1 = (PINC & _BV(BUTTON1_PIN)) == 0; // 1 если нажата
uint8_t button2 = (PINC & _BV(BUTTON2_PIN)) == 0; // 1 если нажата
uint8_t button3 = (PINC & _BV(BUTTON3_PIN)) == 0; // 1 если нажата
uint8_t button4 = (PINC & _BV(BUTTON4_PIN)) == 0; // 1 если нажата
uint8_t button5 = (PINC & _BV(BUTTON5_PIN)) == 0; // 1 если нажата
uint8_t button6 = (PINC & _BV(BUTTON6_PIN)) == 0; // 1 если нажата
// uint8_t buttons = (PINB & ((1 << BUTTON_UP_PIN) | (1 << BUTTON_DOWN_PIN)));
uint8_t buttons = PINB;
// Обработка кнопки увеличения
if ((buttons & (1 << BUTTON_UP_PIN)) == 0) {
if ((last_buttons & (1 << BUTTON_UP_PIN)) != 0) {
state = (state + 1) % 7;
// update_leds();
}
}
// Обработка кнопки уменьшения
if ((buttons & (1 << BUTTON_DOWN_PIN)) == 0) {
if ((last_buttons & (1 << BUTTON_DOWN_PIN)) != 0) {
state = (state == 0) ? 6 : state - 1;
// update_leds();
}
}
last_buttons = buttons;
// Обработка комбинаций основных кнопок
if (button1 && !button2 && !button3 && !button4 && !button5 && !button6) {
// Нажата только кнопка 1
PORTD = (1 << LED1_PIN);
}
else if (button1 && button2 && !button3 && !button4 && !button5 && !button6) {
// Нажаты кнопки 1 и 2
PORTD = (1 << LED2_PIN);
}
else if (button1 && button2 && button3 && !button4 && !button5 && !button6) {
// Нажаты кнопки 1-3
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN);
}
else if (button1 && button2 && button3 && button4 && !button5 && !button6) {
// Нажаты кнопки 1-4
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED3_PIN);
}
else if (button1 && button2 && button3 && button4 && button5 && !button6) {
// Нажаты кнопки 1-5
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED4_PIN);
}
else if (button1 && button2 && button3 && button4 && button5 && button6) {
// Нажаты все кнопки
PORTD = (1 << LED1_PIN) | (1 << LED2_PIN) | (1 << LED3_PIN) | (1 << LED4_PIN);
}
else {
// Нет нажатых кнопок
PORTD = 0;
}
_delay_ms(20); // Дебаунс задержка
}
return 0;
}
15. Admin - 28 Августа, 2025 - 10:02:15 - перейти к сообщению
Вроде бы над вами никто не прикалывался и никто два микроконтроллера не советовал.
А кнопки не работают из-за того, что инициализированы не в том месте...
А кнопки не работают из-за того, что инициализированы не в том месте...