Первоначально мне нужно отправить и получить серийные данные. Длина пакета составляет 48 бит. Для более коротких пакетов (32 бита), я мог бы сделать что-то вроде этого:Побитовый сдвиг массива символов в AVR C
unsigned long data=0x12345678;
for(i=0;i<32;i++){
if(data & 0x80000000)
setb_MOD;
else
clrb_MOD;
data <<= 1;
}
Этот код сборник действительно приятны мне:
code<<=1;
ac: 88 0f add r24, r24
ae: 99 1f adc r25, r25
b0: aa 1f adc r26, r26
b2: bb 1f adc r27, r27
b4: 80 93 63 00 sts 0x0063, r24
b8: 90 93 64 00 sts 0x0064, r25
bc: a0 93 65 00 sts 0x0065, r26
c0: b0 93 66 00 sts 0x0066, r27
После мне нужно расширить пакет (до 48 бит) I столкнувшись с необходимостью сместить массив:
unsigned char data[6]={0x12,0x34,0x56,0x78,0xAB,0xCD};
for(i=0;i<48;i++){
if(data[5] & 0x80)
setb_MOD;
else
clrb_MOD;
for(j=5;j>0;j--){
data[j]<<=1;
if(data[j-1] & 0x80)
data[j]+=1;
}
data[0] <<= 1;
}
compilled код немного зависит от параметров оптимизации, но в целом она делает то, что Я заповедал в C:
for(j=5;j>0;j--){
code[j]<<=1;
a8: 82 91 ld r24, -Z
aa: 88 0f add r24, r24
ac: 80 83 st Z, r24
if(code[j-1]&0x80)
ae: 9e 91 ld r25, -X
b0: 97 fd sbrc r25, 7
b2: 13 c0 rjmp .+38 ; 0xda <__vector_2+0x74>
clrb_MOD;
}
else{
setb_MOD;
}
for(j=5;j>0;j--){
b4: 80 e0 ldi r24, 0x00 ; 0
b6: a3 36 cpi r26, 0x63 ; 99
b8: b8 07 cpc r27, r24
ba: b1 f7 brne .-20 ; 0xa8 <__vector_2+0x42>
code[j]<<=1;
if(code[j-1]&0x80)
code[j]+=1;
}
Как вы можете видеть, нет очевидного (для человека) решения по смещению байта массива после байта.
Я бы хотел пропустить инъекцию встроенного ассемблера, поскольку я не очень разбираюсь в этой технике, и я действительно не понимаю, как мне адресовать переменные C в Asm. Есть ли альтернативы?
Я не знал о типе uint64_t. Это немного лишнее, но хорошее решение. Просто протестировал его в компиляторе - все сработало! Благодаря! –