uint32_t data;
SPDR = ((uint8_t*) & data)[x];
我可以看到这一行的作用 - 它可以放在一个for循环中来读取" data"的每一个字节。进入SPDR
,但我不太明白它是如何运作的。
答案 0 :(得分:3)
让我们把它分成不同的部分:
&data
为您指向data
,类型为uint32_t *
(uint8_t*)
将uint32_t
指针转换为指向uint8_t
(或无符号字节数组)的指针如果将其置于循环中,则从四字节uint32_t
值开始一次占用一个字节,并将其分配给SPDR
。
答案 1 :(得分:1)
正如StackOverflow的Tag Info所说
串行外设接口(SPI)是串行,同步,完整的 双工总线常用于嵌入式系统。它最常用 用于微控制器和外围硬件之间的通信 如记忆,移位寄存器,传感器,显示器等,但也可以 用于MCU到MCU的通信。
传输通常涉及一些给定字的两个移位寄存器 大小,例如八位,一位在主人中,一位在奴隶中;他们 连接在一起。数据通常最多移出 首先是有效位,同时将一个新的最低有效位移入 同一个登记册。在该寄存器被移出后, 主设备和从设备已交换寄存器值。然后是每个设备 获取该值并对其执行某些操作,例如将其写入 记忆。如果有更多数据要交换,移位寄存器是 装载了新数据[1]并重复该过程。传输可能 涉及任意数量的时钟周期。当没有更多数据时 发送后,主机停止切换其时钟。通常,它然后 取消选择奴隶。 传输通常包含8位字。一个 如果希望/需要,主设备可以发起多个这样的传输。 但是,其他字大小也很常见,例如16位字 触摸屏控制器或音频编解码器,如德克萨斯州的TSC2101 仪器;或许多数字到模拟或12位字 模数转换器。
SPDR = ((uint8_t*) & data)[x];
将导致uint32_t
指针转换为指向uint8_t
的指针 - 指向8位的指针。指针算法基于指针类型,数组子映射基于指针算法
C标准n1124 § 6.5.2.1/2数组下标
后缀表达式后跟方括号[]中的表达式是下标 指定数组对象的元素。下标运算符[]的定义 是E1 [E2]与(*((E1)+(E2)))相同。由于转换规则 应用于二进制+运算符,如果E1是一个数组对象(等效地,指向 数组对象的初始元素),E2是整数,E1 [E2]表示E2 E1的元素(从零开始计数)。
因此索引数组将移动一个关于sizeof(*指针)的指针,因此为1个字节。这样你就可以遍历32位的所有4个字节。
答案 2 :(得分:0)
data
是4字节,(uint8_t*) & data
正在将它转换为1字节值的指针x
,你没有显示,正在索引到1字节数组价值观。
答案 3 :(得分:0)
我仍然遇到这个问题。请采取以下措施:
uint16_t EN_A_WrRd_OP16(uint8_t opcode,uint16_t write_data)
{
uint16_t read_data;
uint8_t i;
EN_A_CS_Low();
SPIC_DATA=opcode;
while (!(SPIC_STATUS&SPI_IF_bm));
for (i=0;i<2;i++)
{
SPIC_DATA=((uint8_t*)&write_data)[i];
while (!(SPIC_STATUS&SPI_IF_bm));
((uint8_t*)&read_data)[i]=SPIC_DATA;
}
EN_A_CS_High();
return read_data;
}
绕过循环两次以读取SPIC_DATA,它读取0x34然后读取0x12。但是,在退出循环时,read_data包含0x0000! 如果我以“长”方式执行此操作并使用以下内容替换循环:
SPIC_DATA=write_data;
while (!(SPIC_STATUS&SPI_IF_bm));
read_data=SPIC_DATA;
SPIC_DATA=write_data>>8;
while (!(SPIC_STATUS&SPI_IF_bm));
read_data|=SPIC_DATA<<8;
它正常工作,即read_data返回值0x1234。