GD32的SPI程序读写程序,SPI特性研究

拿到一个SPI芯片的时序图:
在这里插入图片描述
能够知道这个过程需要24位,因此SPI的的帧长度设置为8位,然后读写3次。

    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;

如果帧长度设置为16位,读写两次就有32位了。
当然也可以设置帧长度为12位,读写两次,但是这样读回来的数据就需要移位处理。

因此就可以编写下面的程序:

GD_SPI_CS_LOW();

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x05<<4);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
spi_i2s_data_receive(SPI0);

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
spi_i2s_data_receive(SPI0);

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
buf=spi_i2s_data_receive(SPI0);

GD_SPI_CS_HIGH();	

上板后波形如下:
在这里插入图片描述

需要注意的是,读取一个字节下面的4条语句是必须的:

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
buf=spi_i2s_data_receive(SPI0);

先等待发送buf变空,然后再把要发送的数据装入发送buf。接着等待接收buf有数据,然后把接收buf中的数据读出来。
spi_i2s_data_transmit 控制当前字节MOSI引脚波形
spi_i2s_data_receive 读取当前字节MISO引脚的波形

不能因为前面两个字节只发送数据,不需要接收数据,就把后面两行删掉!!
经过测试,不去读取数据,接收buf的数据就不会更新。

如果遇到只需要发送数据,不需要接收数据的,就可以:

GD_SPI_CS_LOW();

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x05<<4);

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);

while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {}  //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);

//while(SET == spi_i2s_flag_get(SPI0, SPI_FLAG_TRANS));	 //等待SPI传输完成,变成空闲
GD_SPI_CS_HIGH();	

看到波形,最后一个字节还没有发送完,CS就拉高了

在这里插入图片描述
因此通过 spi_i2s_data_transmit(SPI0, 0x00); 把数据装入发送buf,程序就继续往下执行了,不管SPI发送完没有,因此要加上一句:

while(SET == spi_i2s_flag_get(SPI0, SPI_FLAG_TRANS));	 //等待SPI传输完成,变成空闲

用库函数太慢了,可以换成寄存器:

    GD_SPI_CS_LOW();	
	
	while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_TBE));  //等待发送buf变空	
	SPI_DATA(SPI0) = 0x05<<4;
	while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_RBNE));  //等待接收buf有数据	
	SPI_DATA(SPI0);
	
	while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_TBE));  //等待发送buf变空	
	SPI_DATA(SPI0) = 0x00;
	while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_RBNE));  //等待接收buf有数据
	SPI_DATA(SPI0);	

	while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_TBE));  //等待发送buf变空	
	SPI_DATA(SPI0) = 0x00;
	while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_RBNE));  //等待接收buf有数据
	buf=SPI_DATA(SPI0);
	
	GD_SPI_CS_HIGH();	

在这里插入图片描述

这段代码是一个函数声明,属于 `FramebufferNativeWindow` 类的一部分。下面是对它的详细分析: ### 函数原型解析 ```cpp int FramebufferNativeWindow::dequeueBuffer( ANativeWindow* window, ANativeWindowBuffer* buffer, int* fenceFd) ``` #### 返回值类型 - **返回值**:`int` - 表示该函数会返回一个整数值,通常用于指示操作是否成功(如0表示成功,非零表示错误),或者是某种状态码。 #### 成员函数所属类 - **成员函数所属类**:`FramebufferNativeWindow` - 这表明这是一个 C++ 的类成员函数,定义在 `FramebufferNativeWindow` 类中。从名字可以看出,这个类很可能与帧缓冲区(framebuffer)以及原生窗口系统有关。 #### 参数列表 1. **`ANativeWindow* window`** - 指针类型的参数,指向一个 `ANativeWindow` 对象。 - 根据 Android NDK 的 API 定义,`ANativeWindow` 是 Android 原生窗口的一个结构体,封装了底层显示表面的相关信息,比如宽高、像素格式等。 2. **`ANativeWindowBuffer* buffer`** - 同样是指向 `ANativeWindowBuffer` 结构体的指针。 - 此参数的作用是用来存储即将出队列的缓冲区数据。`ANativeWindowBuffer` 包含了关于图像缓冲区的信息,例如宽度、高度、像素格式及物理地址等。 3. **`int* fenceFd`** - 文件描述符(file descriptor)指针类型。 - 在图形处理场景下,同步机制非常重要。`fenceFd` 可能会被用来传递信号量文件描述符,在异步任务完成后通知调用方可以访问共享资源。 --- ### 功能推测 结合上下文来看,这可能是 Android 系统中原生图形渲染框架中的一个核心功能点之一——管理双缓存或多缓存系统的函数。其主要职责是从某个特定的对象 (`window`) 中取出一块可用的缓冲区域,并将相关信息赋给输入变量(即第二个和第三个参数)。以下是进一步的功能解读: - **作用**: 调度缓冲区供客户端程序绘制下一帧内容之用; - **应用场景**: 主要应用于涉及 GPU 或者 CPU 图形流水线的应用场景之中,比如游戏开发引擎或者视频播放器等等; 此外,“deque”这个词意味着这是个“先进先出”的过程链表式的数据结构模型下的操作动作,因此它不仅简单地提取了一个元素还隐含着维护整个序列顺序的工作流含义在里面。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qlexcel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值