Reystlin 0 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба Доброго времени суток есть ряд включенных последовательно 74hc165 из которых их состояния записываются в массив каким образом организовать сквозное обращение к битам? имею примерно следующее #define PD_PROTECT 0 //PD PROTECT #define HI_TEMP 1 //HI TEMP #define HI_CURRENT_PR 2 //HI Current PROTECT #define ALARM_ALL 3 //Защита общая #define PWR_DN 4 //Провал питания #define PWR_UP 5 //Превышеие сети #define SHORT_CURCUIT_LED 6 //сигнал КЗ с блока ШИММа #define PROTECT_TIME 7 //Задержка таймера ШИМа #define AUTO_CUTTER 8 //подключен резак для автоматической резки #define KT2_TEN 9 //Термореле тена #define KT4_LEVEL 10 //Датчик уровня жидкости #define KT3_Water 11 //Датчик потока #define HAND_CUTTER 12 //Подключен резак для ручной резки #define TRAILER_CUTTER 13 //Концевик #define BUTTON_CUTTER 14 //Кнопка плазмотрона #define SHORT_CURCUIT 15 //Короткое замыкание пытаюсь обращаться вот так uint8_t data[3]; #define IS(x) (int)data[1] & (int)(1<<x) в итоге к старшей микросхеме доступ есть а вот ко второй уже нет Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба Ткни пальцем, где тут обращение к микросхемам? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба массив заполняется данными в другом месте. микрухи подключены по SPI и обрабатываются вот таким куском кода #include <avr/delay.h> #include <avr/interrupt.h> #include "SPI.h" #include "Periph.h" uint8_t SPI_write[SPI_WRITE_SIZE_ARRAY]; uint8_t SPI_read[SPI_READ_SIZE_ARRAY]; uint8_t pointer = 0; void SPI_Init(void) { SPI_DDRX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO); SPI_PORTX &= ~(1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO); SPCR=( (1<<SPIE)//Разрешить прерывания от SPI |(1<<SPE)//Включить модуль SPI |(1<<DORD)//Младший бит вперед |(1<<MSTR)//SPI в режиме Мастер ); SPSR |= (1<<SPI2X); } void SPI_StartWrite(void) { SPI_PORTX &= ~(1<<SPI_SS); _delay_ms(1); SPI_PORTX |= (1<<SPI_SS); pointer = 0; SPDR = SPI_write[pointer]; } ISR(SPI_STC_vect) { //прерывание по завершению передачи байта if(pointer < SPI_READ_SIZE_ARRAY) SPI_read[pointer] = SPDR; pointer++; if(pointer >= SPI_WRITE_SIZE_ARRAY) return; SPDR = SPI_write[pointer]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 1 час назад, Reystlin сказал: #define IS(x) (int)data[1] & (int)(1<<x) #define IS(x) (data[(x) >> 3] & (1 << ((x) & 0x07))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 1 час назад, Reystlin сказал: есть ряд включенных последовательно 74hc165 из которых их состояния записываются в массив каким образом организовать сквозное обращение к битам? #define SHORT_CURCUIT 15 //Короткое замыкание пытаюсь обращаться вот так uint8_t data[3]; #define IS(x) (int)data[1] & (int)(1<<x) в итоге к старшей микросхеме доступ есть а вот ко второй уже нет Вам надо из общего номера бита вычислить номер байта в массиве и номер бита в этом байте. Номер байта равен номеру бита делённому на 8, а номер бита - остатку от этого деления. Типа так: uint8_t data[3]; #define IS(x) data[x/8] & (1<<(x%8)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба Спасибо, работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 54 минуты назад, AHTOXA сказал: Вам надо из общего номера бита вычислить номер байта в массиве и номер бита в этом байте. Можно всей этой битовой арифметикой не пользоваться, если научиться пользоваться структурами. Примерно так (бит данных 16, зачем 3 байта?) Можно легко добавлять, удалять, смещать, менять порядок бит, не навлекая проблем магических чисел. typedef struct s_s { union { BYTE data[3]; struct { BYTE PD_PROTECT:1; //PD PROTECT BYTE HI_TEMP:1; //HI TEMP BYTE HI_CURRENT_PR:1; //HI Current PROTECT BYTE ALARM_ALL:1; //Защита общая BYTE PWR_DN:1; //Провал питания BYTE PWR_UP:1; //Превышеие сети BYTE SHORT_CURCUIT_LED:1; //сигнал КЗ с блока ШИММа BYTE PROTECT_TIME:1; //Задержка таймера ШИМа BYTE AUTO_CUTTER:1; //подключен резак для автоматической резки BYTE KT2_TEN:1; //Термореле тена BYTE KT4_LEVEL:1; //Датчик уровня жидкости BYTE KT3_Water:1; //Датчик потока BYTE HAND_CUTTER:1; //Подключен резак для ручной резки BYTE TRAILER_CUTTER:1; //Концевик BYTE BUTTON_CUTTER:1; //Кнопка плазмотрона BYTE SHORT_CURCUIT:1; //Короткое замыкание BYTE some; }; }; } s_s; s_s h; void foo(void) { h.AUTO_CUTTER = 1; h.BUTTON_CUTTER = 0; SPDR = h.data[pointer]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба на 3 кнопки висят и обрабатываются отдельно. да, интересное решение:) спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 3 минуты назад, adnega сказал: Можно всей этой битовой арифметикой не пользоваться, если научиться пользоваться структурами. Ага, только это решение будет зависеть от порядка байтов в слове. А после этого всё равно будет передавать эту структуру побайтно:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 2 минуты назад, AHTOXA сказал: Ага, только это решение будет зависеть от порядка байтов в слове. На уровне SPDR = h.data[pointer]; легко корректируется (т.е. в одном месте конкретного драйвера). Либо на уровне описания структуры. 2 минуты назад, AHTOXA сказал: А после этого всё равно будет передавать эту структуру побайтно:) Можно передать хоть через указатель и DMA: структура - это просто память. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 57 минут назад, adnega сказал: На уровне SPDR = h.data[pointer]; легко корректируется (т.е. в одном месте конкретного драйвера). Либо на уровне описания структуры. Да, исправить несложно. Но универсального исходника для разных контроллеров уже не выйдет. Плюс к тому могут быть сложности с полями из нескольких битов, если они лежат на стыке байтов (часть поля в одном байте, часть в соседнем). В общем, выглядит красиво, но в реальности есть нюансы. И ещё один момент. Попробуйте с ходу найти в своём описании бит номер 12 :) Да, вы их сгруппировали по 8, но это всё по ходу работы может съехать:) В общем, я одно время был в восторге от этого решения, и применял его везде, но потом постепенно отказался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 21 июля, 2019 Опубликовано 21 июля, 2019 · Жалоба 2 минуты назад, AHTOXA сказал: Да, исправить несложно. Но универсального исходника для разных контроллеров уже не выйдет. В профиле Cortex-M, вроде, только LE-порядок байт возможен. Там, где есть реальное железо, и внутреннее представление играет роль - нужно применять конкретику, т.к. на абстракциях уже решать не возможно. Переносимость исходника LE<>BE нужно описывать специальным образом. 2 минуты назад, AHTOXA сказал: Плюс к тому могут быть сложности с полями из нескольких битов, если они лежат на стыке байтов (часть поля в одном байте, часть в соседнем). Можно бороть через расширение длины (типа DWORD some:1), а в тяжелых случаях - через union. 2 минуты назад, AHTOXA сказал: В общем, выглядит красиво, но в реальности есть нюансы. С магическими числами нюансов больше. Разве нет? А попробуйте задать не тот номер в define? А попробуйте установить 12 бит, которого в байте просто нет? А если за границу массива после этого вылезли? Нужно помнить размеры всех массивов? А если добавили еще одно поле и размеры массивов стали больше? Все исходники править вручную? 2 минуты назад, AHTOXA сказал: И ещё один момент. Попробуйте с ходу найти в своём описании бит номер 12 :) Да, вы их сгруппировали по 8, но это всё по ходу работы может съехать:) В том-то и суть, что имеет место переход от магического числа 12 к названию бита. Это HAND_CUTTER , а с каким он будет номером - все-равно без дополнительной документации смысла не имеет. Применение структур дает еще один существенный плюс, что код получается читаемый. Кста, он в итоге разворачивается в биты и маски, но без использования define. Структуры - очень мощный инструмент, и если его применять, то где, как ни в таких задачах? Упс: тут AVR 20 минут назад, AHTOXA сказал: В общем, я одно время был в восторге от этого решения, и применял его везде, но потом постепенно отказался. В пользу чего? И почему? Очень интересно знать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 22 июля, 2019 Опубликовано 22 июля, 2019 · Жалоба 8 часов назад, adnega сказал: В профиле Cortex-M, вроде, только LE-порядок байт возможен. А вот маленький STM8 неожиданно оказался BE. Это, кстати, было одной из причин того, что я пересмотрел свой подход. Я понял, что есть живые "большие индейцы". 8 часов назад, adnega сказал: С магическими числами нюансов больше. Разве нет? Зачем сразу магические числа? Объявим в одном месте константу, и будем её использовать. Если HAND_CUTTER - это 12 бит в слове, то определение static constexpr size_t HAND_CUTTER { 12 }; будет однозначным и легко поддерживаемым. 8 часов назад, adnega сказал: В том-то и суть, что имеет место переход от магического числа 12 к названию бита. Но ведь нам нужно, чтобы этот HAND_CUTTER был именно на 12 ноге сдвигового регистра! Ведь мы же не хотим вместо отрезания рук прострелить себе ногу? :) 8 часов назад, adnega сказал: В пользу чего? И почему? Очень интересно знать. Сдвиги и маски. По возможности заворачиваю в шаблонные классы. Почему - вроде описал уже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться