bit array to byte

I am working on a project where i need to create a byte from several bits and then send that data to PORTL on the mega as a HEX value(this is being written to an 8254 to read/write high freq)

I'm not sure what I've got wrong.
Any help would be appreciated.

int dataLines[8] = { 49,48,47,46,45,43,42 }; // datalines can either be input or output, need to set mode before performing operation
int A_0 = 37;
int A_1 = 36;
int RD = 34;
int WR = 35;
int CS[8] = { 26,27,28,29,30,31,32,33 };

//Data to send/receive from PORTL
//bits 7-6 counter select
//0 0 -> Counter 0
//0 1 -> Counter 1
//1 0 -> Counter 2
//1 1 -> Read Back Command
//bits 5-4 read/write
//0 0 -> Latch
//0 1 -> LSB only
//1 0 -> MSB only
//1 1 -> LSB followed by MSB
//bits 3-1
//mode -> see data sheet for all
//0 1 1 -> mode 3 (freq generator)
//bit 0 BCD mode
//0 -> Binary counter 16 bit
//1 -> BCD(4 decades)
int controlWord[8] = {0,0,0,0,0,0,0,0};

void setup() {
	Serial.begin(115200);
	for (int i = 0; i < 9; i++) {//chip select lines
		pinMode(CS[i], OUTPUT);
	}
	setDataLines_RW(false);
	setChipRW(0);
	selectChip(10);
}

void loop() {
	selectChip(0);
	setChipRW(2);
	selectChipCounter(0);
	setControlWordCounter(0);
	setControlReadWrite(3);
	setControlMode(3);
	setControlBCDMode(0);
	for (int i = 0; i <= 7; i++) {
		Serial.print(i);
		Serial.print(" : ");
		Serial.println(controlWord[i]);
	}
	Serial.println((byte)controlWord, HEX);
	delay(100);

}


//Data to send/receive from PORTL
//bits 7-6 counter select
//0 0 -> Counter 0
//0 1 -> Counter 1
//1 0 -> Counter 2
//1 1 -> Read Back Command
void setControlWordCounter(int mode) {
	switch (mode)
	{
	case 0: //counter 0
		controlWord[7] = 0;
		controlWord[6] = 0;
		break;
	case 1: //counter 1
		controlWord[7] = 0;
		controlWord[6] = 1;
		break;
	case 2: //counter 2
		controlWord[7] = 1;
		controlWord[6] = 0;
		break;
	case 3: //control word register
		controlWord[7] = 1;
		controlWord[6] = 2;
		break;
	}
}
//bits 5-4 RW Select
//mode 0 -> Latch
//mode 1 -> LSB only
//mode 2-> MSB only
//mode 3 -> LSB followed by MSB
void setControlReadWrite(int mode) {
	switch (mode)
	{
	case 0:
		controlWord[5] = 0;
		controlWord[4] = 0;
		break;
	case 1:
		controlWord[5] = 0;
		controlWord[4] = 1;
		break;
	case 2:
		controlWord[5] = 1;
		controlWord[4] = 0;
		break;
	case 3:
		controlWord[5] = 1;
		controlWord[4] = 1;
		break;
	default:
		break;
	}
}

//bits 3-1 mode select
//mode 0 -> Interrupt on Terminal Count
//mode 1 -> Hardware Re-Triggerable One-Shot
//mode 2 -> Rate Generator
//mode 3 -> Square Wave Mode(freq generator)
//mode 4 -> Softwar Triggered Strobe
//mode 5 -> Hareware Triggered Strobe
void setControlMode(int mode) {
	switch (mode)
	{
	case 0:
		controlWord[3] = 0;
		controlWord[2] = 0;
		controlWord[1] = 0;
		break;
	case 1:
		controlWord[3] = 0;
		controlWord[2] = 0;
		controlWord[1] = 1;
		break;
	case 2:
		controlWord[3] = 0;
		controlWord[2] = 1;
		controlWord[1] = 0;
		break;
	case 3:
		controlWord[3] = 0;
		controlWord[2] = 1;
		controlWord[1] = 1;
		break;
	case 4:
		controlWord[3] = 1;
		controlWord[2] = 0;
		controlWord[1] = 0;
		break;
	case 5:
		controlWord[3] = 1;
		controlWord[2] = 0;
		controlWord[1] = 1;
		break;		
	default:
		break;
	}
}

//bit 0 BCD Select
//0 -> Binary counter 16 bit (65535)
//1 -> BCD(4 decades) (10000)
void setControlBCDMode(int mode) {
	switch (mode)
	{
	case 0:
		controlWord[0] = 0;
		break;
	case 1:
		controlWord[0] = 1;
		break;
	default:
		break;
	}
}

//id -> chip to read/write from
//id=10 -> turn off all chips
void selectChip(int id) {
	for (int i = 0; i < 9; i++) {
		if (i != id) {		
			digitalWrite(CS[i], HIGH); //make sure other chips are turned off
		}
	}
	if (id != 10) {
		digitalWrite(CS[id], LOW);//turn on this chip
	}
}

//Select counter to read/write from
//0 -> Counter 0
//1 -> Counter 1
//2 -> Counter 2
//3 -> Control Word Register
void selectChipCounter(int counter) {
	switch (counter)
	{
		case 0: //counter 0
			digitalWrite(A_1, LOW);
			digitalWrite(A_0, LOW);
			break;
		case 1: //counter 1
			digitalWrite(A_1, LOW);
			digitalWrite(A_0, HIGH);
			break;
		case 2: //counter 2
			digitalWrite(A_1, HIGH);
			digitalWrite(A_0, LOW);
			break;
		case 3: //control word register
			digitalWrite(A_1, HIGH);
			digitalWrite(A_0, HIGH);
			break;
	}
}

running the code as is gives me this result

0 : 0
1 : 1
2 : 1
3 : 0
4 : 1
5 : 1
6 : 0
7 : 0
43 <- this number i believe is wrong

I think it should be 36
The bits look to be set correctly, but the expected output is not what I'm getting.
36 HEX -> 0011 0110 Binary

43 HEX -> 0100 0011 Binary

Not sure how I got this result.

Thank you!

for (int i = 0; i < 9; i++) {//chip select lines

This will set 9 elements ......

You need to read about unions, structures and bitfields.

Example:

union
{
byte controlWord;
struct
{
BCDMode :1;
ControlMode :3;
ReadWrite :2;
WordCounter :2;
};
} setControl;

Now you can assign setControl.BCDMode = 0 or 1 and that value will reside in bit 0 of setControl.controlWord. Similarly, setControl.ReadWrite = n will place the value of n in bits 5:4.

A separate union can be set up with 8 1-bit bitfields to take on the values of the port pins, automatically attaching to the corresponding bit positions in the byte union.

You should turn on all warnings in the IDE and then read them.

C:\Users\Peter\AppData\Local\Temp\arduino_modified_sketch_377309\sketch_oct09a.ino:53:24: warning: cast from 'int*' to 'byte {aka unsigned char}' loses precision [-fpermissive]

   Serial.println((byte)controlWord, HEX);

                        ^

The reason that it prints 0x43 is that you are printing the address of the controlWord array - not its content. This is why it refers to "cast from 'int*'".

controlWord is an array of int whose elements have a value of zero or one. If you want to print that as one hex value you have to assemble it into a byte yourself.

Pete

If you want to print that as one hex value you have to assemble it into a byte yourself.

Here's one way to do that

void setup() {
  Serial.begin(115200);
  byte controlWord[8] = {0, 1, 1, 0, 1, 1, 0, 0};
  byte hexControlWord = 0;
  for (byte i = 0; i <= 7; i++) {
    Serial.print(i);
    Serial.print(" : ");
    Serial.println(controlWord[i]);
    hexControlWord = hexControlWord + (controlWord[i] << i);   
  }
  //Serial.println((byte)controlWord, HEX);
  Serial.print("Hex byte from combined bits = 0x");
  Serial.println(hexControlWord, HEX);
}

void loop() {
  // put your main code here, to run repeatedly:

}

i need to create a byte from several bits and then send that data to PORTL on the mega as a HEX value

There is no such thing as a HEX value, only a HEX representation of a value.

Thank you everyone for your assistance!
I ended up using the union(never even thought about that!) and so I modified the supplied example from DKWatson a little bit, thank you.

sidhabo - Thank you, i missed that error. Would have had me scratching my head later.

el_supremo - After you pointed out that error i realized what you were talking about. Stupid mistake in trying to debug my problem, which was also compounding the issue.

UKHeliBob:
There is no such thing as a HEX value, only a HEX representation of a value.

Yep your right, poor clarity on my part causes confusion frequently.

Again thank you for your help