Это звучит как подход, такой как следующее, в соответствии с тем, как вы хотели бы пойти с решением.
Я не тестировал это, так как у меня нет оборудования, однако это должно обеспечить альтернативу для просмотра.
Предполагается, что вы хотите включить определенные контакты или отключить отдельные контакты, но не будет случая, когда вы захотите включить некоторые контакты и отключить другие контакты для определенного устройства за одну операцию. Если это так, я бы подумал о том, чтобы тип RegPinNo
был беззнаковым коротким, чтобы включать код op для каждой комбинации номеров регистра/вывода.
Это также предполагает, что время операций не является критическим ограничением и что аппаратное обеспечение имеет достаточную мощность, так что небольшие петли не являются большой нагрузкой на пропускную способность и затормаживают процессорное время, необходимое для других целей. Таким образом, этот код может потребовать изменений для улучшения оптимизации, если это необходимо.
Я предполагаю, что вы хотите какой-то легко читаемый способ выражения команды, которая включает и выключает ряд бит, разбросанных по нескольким областям памяти.
Первое, что нужно сделать, чтобы представить, как будет выглядеть такая команда, и мне кажется, что достаточно заимствования из массива char
для представления строки.
typedef byte RegPinNo; // upper nibble indicates register number 0 - 7, lower nibble indicates pin number 0 - 7
const byte REGPINNOEOS = 0xff; // the end of string for a RegPinNo array.
И они будут использоваться для определения массива номеров регистров/выводов, как в следующем.
RegPinNo myLed[] = { 0x01, 0x12, REGPINNOEOS }; // LED is addressed through Register 0, Pin 0 and Register 1, Pin 1 (zero based)
Так что на данный момент у нас есть способ, чтобы описать, что конкретное устройство, светодиод в данном случае рассматривается через ряд регистры/контактные пункты номера.
Далее следует создать небольшую библиотеку функций, которая будет использовать это представление для фактического изменения конкретных контактов в определенных регистрах путем прохождения этого массива номеров регистров/выводов и выполнения на нем операции, таких как установка бита в регистре или очистка бит в регистре.
typedef unsigned char byte;
typedef union {
byte Byte;
struct {
byte PTAD0 : 1;
byte PTAD1 : 1;
byte PTAD2 : 1;
byte PTAD3 : 1;
byte PTAD4 : 1;
byte PTAD5 : 1;
byte PTAD6 : 1;
byte PTAD7 : 1;
} Bits;
} PTADSTR;
// Define a pointer to the beginning of the register area. This area is composed of
// 8 different registers each of which is one byte in size.
// We will address these registers as Register 0, Register 1, ... Register 7 which just happens
// to be how C does its zero based indexing.
// The bits representing pins on the PCB we will address as Pin 0, Pin 1, ... Pin 7.
extern volatile PTADSTR (* const _PTAD) = 0x00000000;
void SetRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte |= pins[bPinNo];
}
}
void ClearRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte &= ~pins[bPinNo];
}
}
void ToggleRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte ^= pins[bPinNo];
}
}
Вы бы использовали приведенное выше следующее. Не уверен, что функция временной задержки будет выглядеть в вашей среде, поэтому я использую функцию Sleep()
, которая принимает аргумент о количестве миллисекунд для задержки или сна.
void LightLed (int nMilliSeconds)
{
RegPinNo myLed[] = { 0x01, 0x12, REGPINNOEOS }; // LED is addressed through Register 0, Pin 0 and Register 1, Pin 1 (zero based)
SetRegPins(myLed); // turn on the LED
Sleep(nMilliSeconds); // delay for a time with the LED lit
ClearRegPins(myLed); // turn the LED back off
}
Edit - Уточнение
Более эффективная реализация, которая позволила бы несколько штырей быть установлен в определенном регистре в то же время было бы определить использование RegPinNo
как беззнаковое короткое `с верхним байтом, являющимся номером регистра, а нижний байт является штырьками для управления в качестве битовой маски для байта.
При таком подходе у вас будет функция SetRegPins()
, которая будет выглядеть следующим образом. Аналогичные изменения потребуются для других функций.
void SetRegPins(RegPinNo *x)
{
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 8) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0xFF; // get the pin mask
_PTAD[bRegNo].Byte |= bPinNo;
}
}
И определения типов будет выглядеть так:
typedef unsigned short RegPinNo; // upper byte indicates register number 0 - 7, lower byte provides pin mask
const byte REGPINNOEOS = 0xffff; // the end of string for a RegPinNo array.
и эти элементы будут использоваться как:
void LightLed (int nMilliSeconds)
{
RegPinNo myLed[] = { 0x0002, 0x0103, REGPINNOEOS }; // LED is addressed through Register 0, Pin 1 and Register 1, Pin 0 and Pin 1 (zero based)
SetRegPins(myLed); // turn on the LED
Sleep(nMilliSeconds); // delay for a time with the LED lit
ClearRegPins(myLed); // turn the LED back off
}
Есть ли адреса памяти, которые отображаются в отдельных регистрах? Например, адрес памяти 0x00000000 отображается в регистр 0, а адрес памяти 0x00000001 сопоставляется с регистром 1 (при условии, что 1 байтовый или 8-битный регистры)? Я ожидал бы использовать ту же конструкцию «PTADSTR» для определения, а затем создать создать указатель на начало области памяти, где расположены регистры, и ссылаться на них как на массив структуры «PTADSTR». –
У вас не может быть указатель на бит-поле. Посмотрите http://stackoverflow.com/questions/13547352/c-cannot-take-address-of-bit-field. –
@RichardChambers Я могу сказать, что далее в определении структура PTADDSTR определена как 0x00000001, а затем PTBDSTR до 0x00000002, затем PTBDDSTR до 0x00000003 и т. Д. И да 8-битные регистры, я думаю, это отвечает на ваши первые вопросы, но я Подумайте, создайте массив с указателями на биты каждой структуры, вы говорите? – Hans