Перейти к содержанию

Управление 24 реле с помощью AtMega32 и 74hc595


Рекомендуемые сообщения

Добрый день. Я, с вашей помощью многого добился вчера. Паралельно с работой над выходами, я еще считывал и 20 входов (74HC165) все получилось.

Вот... Еще вопрос. Этот кусок так и оставить? Или его можно оптимизировать? Ибо я пытался в цикле прокрутить, так оно там такого понаписало. 

void vivod(int nom, _Bool on_off)
{
	// Собираю три байта из 24-х бит.
	// Далее отправляю по очереди в функцию вывода.
	
	s[0] = 0xFF; // Единички, потому что реле реагируют на нули
	s[1] = 0xFF; 
	s[2] = 0xFF;
	
	_byt_out[nom] = on_off;//
	 /* Задвигаю каждый бит на свое место */
	s[2] = _byt_out[0]|(_byt_out[1]<<1)|(_byt_out[2]<<2)|(_byt_out[3]<<3)|(_byt_out[4]<<4)|(_byt_out[5]<<5)|(_byt_out[6]<<6)|(_byt_out[7]<<7);
	s[1] = _byt_out[8]|(_byt_out[9]<<1)|(_byt_out[10]<<2)|(_byt_out[11]<<3)|(_byt_out[12]<<4)|(_byt_out[13]<<5)|(_byt_out[14]<<6)|(_byt_out[15]<<7);
	s[0] = _byt_out[16]|(_byt_out[17]<<1)|(_byt_out[18]<<2)|(_byt_out[19]<<3)|(_byt_out[20]<<4)|(_byt_out[21]<<5)|(_byt_out[22]<<6)|(_byt_out[23]<<7);
	
	output_schift(s);// отправка на указатель
	
	s[0] = 0xFF;s[1] = 0xFF;s[2] = 0xFF;// на всякий случай
}

  

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

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

  • Ответов 59
  • Создана
  • Последний ответ

Топ авторов темы

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

ваш массив _bool-ов и метод работы с ним - это "ужас нерожденного" ©. на Радиокоте я вам показывал, как сделать более-менее прилично...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

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

Если у Вас все биты включения-выключения лежат раздельно в массиве _byt_out[24], то ничего предварительно задвигать-то и не надо - прямо этот массив и пользуем. 

void output_schift(unsigned char *data)
{
   for(char i = 0; i < 24; i++)
   {
         if(data[i] & 0x01)   DS_high();
         else   DS_low();

         SH_CP_high();
         SH_CP_low();
   }
   ST_CP_high();
   ST_CP_low();
}

// Вызов функции сдвига

output_schift(_byt_out);

 

Ссылка на комментарий
Поделиться на другие сайты

Цитата

Сдвиг и AND - две, как и в моем примере

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

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

С каких это пор в программе на Си применяется работа с регистром статуса? Это нормальный подход по-вашему?

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Конечно нормальный. Вообще этот код должен быть частью HAL проекта и совершенно нормально что он аппаратно-зависим.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

@si4karuk , почитайте про битовые поля и объединения. Они Вас очень спасут.

ЗЫ: Ваш код просто ужасен. Не в плане самого кода (то пофиг, сколько там символов напечатано), а в плане вычислений (быстродействия) и занимаемого объёма памяти.
На платформах без аппаратного сдвига на n-ное кол-во битов, конструкция типа "x<<y" превратиться в реальный цикл со сдвигами.


 

Ссылка на комментарий
Поделиться на другие сайты

Дело в том что 

s[2] = _byt_out[0]|(_byt_out[1]<<1)|(_byt_out[2]<<2)|(_byt_out[3]<<3)|(_byt_out[4]<<4)|(_byt_out[5]<<5)|(_byt_out[6]<<6)|(_byt_out[7]<<7);
	s[1] = _byt_out[8]|(_byt_out[9]<<1)|(_byt_out[10]<<2)|(_byt_out[11]<<3)|(_byt_out[12]<<4)|(_byt_out[13]<<5)|(_byt_out[14]<<6)|(_byt_out[15]<<7);
	s[0] = _byt_out[16]|(_byt_out[17]<<1)|(_byt_out[18]<<2)|(_byt_out[19]<<3)|(_byt_out[20]<<4)|(_byt_out[21]<<5)|(_byt_out[22]<<6)|(_byt_out[23]<<7);
	

Этот кусок, я написал так как я понимаю. Предложенные коды, я не могу прочесть, я не понимаю их работы. 

Но самое интересное, это работает, и именно так как я хочу. 

Я бы мог нацарапать что то вроде этого. 

struct bit
{
  _bool_1 :1;
  _bool_2 :1;
  и т.д.
}out_bit[3];

Но потом, работать с ним, мне кажется совсем неудобно:wacko:

Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, si4karuk сказал:

Предложенные коды, я не могу прочесть, я не понимаю их работы

А я ваш код не могу прочесть, тем более не желаю понимать. Я же вам на радиокоте написал практически все в виде примера - может быть, стоило напрячься и понять, что я предложил?

1 час назад, Alexeyslav сказал:

Вообще этот код должен быть частью HAL проекта и совершенно нормально что он аппаратно-зависим

Да бросьте! Или вы в самом деле считаете, что МАТЕМАТИКА и ЛОГИКА работы с ДАННЫМИ должны быть привязаны к аппаратуре?! Работа с портами - согласен, работа с аппаратной периферией - согласен, но логика обработки данных - это никак не HAL! 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

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

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

Нет не решил, мне самому не нравится то что я накалякал, да оно работает, но все говорят что не так. Вот и пытаюсь выяснить что именно не так.

Ссылка на комментарий
Поделиться на другие сайты

да нет проблем, нашел какую то, чю то библиотеку вывовда, вставил в свою программу и пошел от нее плясать.

Да только 

()<< & 1 *buf? ^~1 <<( 0x80?)

Эти закарлючки в голове не укладываются... 

 

Критику надо слушать, без нее ни один шедевр не появился:)

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

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

Я бы мог нацарапать что то вроде этого. 


struct bit
{
  _bool_1 :1;
  _bool_2 :1;
  и т.д.
}out_bit[3];

Но потом, работать с ним, мне кажется совсем неудобно:wacko:

Это только кажется, т.к. Вы просто не попытались почитать и понять. Когда поймёте как оно всё работает, станет удобно.

Вот Вам примерчик :

union{
    struct{
        unsigned    bit_1 :1;
        unsigned    bit_2 :1;
        unsigned    bit_3 :1;
        unsigned    bit_4 :1;
        unsigned    bit_5 :1;
        unsigned    bit_6 :1;
        unsigned    bit_7 :1;
        unsigned    bit_8 :1;
        unsigned    bit_9 :1;
        unsigned    bit_10 :1;
        unsigned    bit_11 :1;
        unsigned    bit_12 :1;
        unsigned    bit_13 :1;
        unsigned    bit_14 :1;
        unsigned    bit_15 :1;
        unsigned    bit_16 :1;
        unsigned    bit_17 :1;
        unsigned    bit_18 :1;
        unsigned    bit_19 :1;
        unsigned    bit_20 :1;
        unsigned    bit_21 :1;
        unsigned    bit_22 :1;
        unsigned    bit_23 :1;
        unsigned    bit_24 :1;
    };
    unsigned char   bytes[3];
}out_data;

Доступ к отдельному биту :

out_data.bit_10 = 1;    // Установить 10-ый бит

Отправить данные в регистры :

output_schift(out_data.bytes, 3);

Или, если по одному байту :

output_schift(out_data.bytes[0]);
output_schift(out_data.bytes[1]);
output_schift(out_data.bytes[2]);

 

Вот и всё. Никаких сдвигов, кучи лишней RAM, лишнего процессорного времени, ...  :)

Ссылка на комментарий
Поделиться на другие сайты

18 минут назад, Alex сказал:

Вот и всё. Никаких сдвигов, кучи лишней RAM, лишнего процессорного времени

Единственный минус - сложно модифицировать в плане изменения количества битов. Ну и обращение по индексу (т.е. по номеру бита) невозможно.

Зато просто. Возможно, это важнее всего.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Только что, Alex сказал:

Возможно.

Почему-то проглядел, что массив внутри union... :( старею, блин...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты



bool get_bit(unsigned char bit_num){
    return (*(long*)out_data.bytes&(1L<<bit_num))!=0;
}

set_bit - будет анологично.

 

Хотя, с long* будет не правильно. Поторопился.Нужно к каждому байту отдельно обращаться...
НУ, в общем, логика понятна. ТС'у пища для мозгов :) 

 

Ссылка на комментарий
Поделиться на другие сайты

out_data.bytes[bit_num / 8] |= 1 << (bit_num % 8);

Не?

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Да и с модификацией по кол-ву сдвиговый регистров, в принципе, можно подшаманить немного :

#define SHIFT_REG_COUNT     3       // Кол-во сдвиговых регистров

typedef union{
    struct{
        unsigned    bit_1 :1;
        unsigned    bit_2 :1;
        unsigned    bit_3 :1;
        unsigned    bit_4 :1;
        unsigned    bit_5 :1;
        unsigned    bit_6 :1;
        unsigned    bit_7 :1;
        unsigned    bit_8 :1;
    };
    unsigned char   bytes;
}t_shift_byte;
t_shift_byte    shift_regs[SHIFT_REG_COUNT];

Обращение к биту регистра :

shift_regs[0].bit_3=1;      // Установить 3-ий бит 1-ого сдвигового регистра в 1-цу

Вывод данных на регистры :

void output_schift(t_shift_byte* pShiftReg, unsigned char size){
    // .......
    // .......
    // .......
}


...............
...............
  
output_schift(shift_regs, SHIFT_REG_COUNT);

...............
...............

 

8 минут назад, ARV сказал:

Не?

Да, оно самое :)

Ссылка на комментарий
Поделиться на другие сайты

Вот ТС'у удочку :

//----------------------------------------------------------------------
#define SHIFT_REG_COUNT     3       // Кол-во сдвиговых регистров
//----------------------------------------------------------------------
typedef union{
    struct{
        unsigned    bit_1 :1;
        unsigned    bit_2 :1;
        unsigned    bit_3 :1;
        unsigned    bit_4 :1;
        unsigned    bit_5 :1;
        unsigned    bit_6 :1;
        unsigned    bit_7 :1;
        unsigned    bit_8 :1;
    };
    unsigned char   byte;
}t_shift_byte;
t_shift_byte    shift_regs[SHIFT_REG_COUNT];
//----------------------------------------------------------------------

//----------------------------------------------------------------------
void output_shift(t_shift_byte ShiftReg){
    unsigned char i, out_val = ShiftReg.byte;
    for(i=0; i<8; i++, out_val>>=1){
        if(out_val&0x01)    DS_high();
        else                DS_low();
        ST_CP_high();
        ST_CP_low();
    }
    SH_CP_high();
    SH_CP_low();
}
//----------------------------------------------------------------------
void update_shifts(t_shift_byte* pShiftRegs, unsigned char size){
    while(size--)   output_shift(*pShiftRegs++);
}
//----------------------------------------------------------------------
void rele_on(unsigned char rele_num, bool val){
    if(!val)    shift_regs[rele_num/8].byte|=1<<(rele_num%8);       // !val - т.к. выхода реле инвертированы
    else        shift_regs[rele_num/8].byte&=~(1<<(rele_num%8));
}
//----------------------------------------------------------------------
    rele_on(10, true);     // Включаем реле №10
    rele_on(5, false);     // Отключаем реле №5
    
    update_shifts(shift_regs, SHIFT_REG_COUNT);    // Обновляем выходы сдвиговых регистров

 

Пусть теперь рыбку ловит :)

Ссылка на комментарий
Поделиться на другие сайты

Часто флаги надо использовать в прерывании, так что объявить надо как volatile. А для многобайтных переменных это может быть неприятно. Предложу еще вариант

#define arg1(a,...)	(a) //вход - список аргументов, выход - первый из них
#define arg2(a,b,...) (b) //вход - список аргументов, выход - второй из них
#define FLAG_SET(x)	do{ arg1(x) |= (1<<arg2(x)); }while(0) //установить бит, заданный вторым аргументом в переменной, заданной первым
#define FLAG_CLR(x)	do{ arg1(x) &=~(1<<arg2(x)); }while(0) //стереть бит, заданный вторым аргументом в переменной, заданной первым
#define FLAG_TST(x)	( arg1(x) & (1<<arg2(x)) ) //проверить, установлен ли бит, заданный вторым аргументом в переменной, заданной первым.

volatile char flags_array1=0; //чем длиннее название, тем лучше: само по себе оно использоваться не будет, зато меньше шанс случайного совпадения
#define F_ANY_FLAG	flags_array,0 //флаги объявляются так
#define F_ADC_RDY	flags_array,1
#define F_UART_RXC	UCSRA,RXC //но можно извратнуться и так
#define BTN_1		PINB,3 //для кнопок и светодиодов такой способ тоже подходит, но можно сделать лучше

...
//примеры использования
FLAG_CLR( F_ADC_RDY );
if(FLAG_TST( F_UART_RXC ))FLAG_SET( F_ANY_FLAG );
if(! FLAG_TST( BTN_1 ))lcd_puts("Button pressed");

На флагах я его не тестировал, только на выводах порта (см. pinmacro.h по ссылке в моей подписи). И для отдельных выводов такой стиль гораздо удобнее, особенно если добавить третий аргумент - активное состояние и подстановку PORT-, DDR- и PIN-, например, #define BTN_1 B,3,0 - кнопка на PB3, коммутируемая на землю.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...