找回密码
 立即注册
查看: 37|回复: 4

AI8051传统库函数SPI通讯问题

[复制链接]
  • 打卡等级:常住居民I
  • 打卡总天数:60
  • 最近打卡:2025-09-30 13:18:37

11

主题

20

回帖

342

积分

中级会员

积分
342
发表于 3 天前 | 显示全部楼层 |阅读模式
//========================================================================
// 函数: void SPI_WriteByte(u8 dat)
// 描述: SPI发送一个字节数据.
// 参数: dat: 要发送的数据.
// 返回: none.
// 版本: V1.0, 2020-09-14
//========================================================================
void SPI_WriteByte(u8 dat)  //SPI发送一个字节数据
{
    if(ESPI)
    {
        B_SPI_Busy = 1;
        SPDAT = dat;
        while(B_SPI_Busy);  //中断模式
    }
    else
    {
        SPDAT = dat;
        while(SPIF == 0);   //查询模式
        SPI_ClearFlag();    //清除SPIF和WCOL标志
    }
}

//========================================================================
// 函数: void SPI_ReadByte(u8 dat)
// 描述: SPI查询模式读取一个字节数据.
// 参数: none.
// 返回: 读取的数据.
// 版本: V1.0, 2020-09-14
//========================================================================
u8 SPI_ReadByte(void)
{
    SPDAT = 0xff;
    if(ESPI)
    {
        B_SPI_Busy = 1;
        while(B_SPI_Busy);  //中断模式
    }
    else
    {
        while(SPIF == 0);   //查询模式
        SPI_ClearFlag();    //清除SPIF和WCOL标志
    }
    return (SPDAT);
}

这段代码我看,感觉像是可以实现全双工通讯的,但是在传统库函数中,把接收和发送分开处理,是因为不能全双工SPI通讯吗

回复

使用道具 举报 送花

3

主题

1928

回帖

704

积分

等待验证会员

积分
704
发表于 3 天前 | 显示全部楼层
您提供的代码片段展示了基于8051架构的SPI通信函数实现,主要包括SPIWriteByte和部分未完成的SPIReadByte函数。以下是对这段代码的专业分析与建议。

一、函数功能与逻辑分析

1. SPIWriteByte(u8 dat) 函数

此函数用于通过SPI接口发送一个字节的数据。函数内部根据ESPI(SPI中断使能位)的值,分别采用中断模式和查询模式进行数据发送。
中断模式(if(ESPI))
设置BSPIBusy = 1;表示SPI总线正在工作。
将数据写入SPDAT寄存器触发发送。
使用while(BSPIBusy);等待发送完成,等待期间由中断服务程序清除BSPIBusy标志。
查询模式(else)
同样将数据写入SPDAT。
使用while(SPIF == 0);轮询SPI发送完成标志。
调用SPIClearFlag()清除SPI中断标志位(如SPIF、WCOL等)。

建议:
BSPIBusy应为一个可被中断服务程序访问并修改的全局变量或位变量。
在中断服务程序中应确保正确清除BSPIBusy标志,防止死锁。
SPIClearFlag()函数的具体实现需明确,尤其是是否清除所有可能的错误标志,例如WCOL(写冲突)。

2. SPIReadByte(u8 dat) 函数(未完成)

从函数名和注释来看,该函数应为SPI查询模式下读取一个字节数据的实现,但目前参数定义为u8 dat,而注释中说明参数为“none”,存在矛盾。

建议:
修改函数原型为:u8 SPIReadByte(void)。
在函数体内:
写入SPDAT以触发SPI主模式下的时钟输出(若为从设备则无需写入)。
等待SPIF标志置位。
读取SPDAT寄存器中的数据。
清除相关标志位。

示例实现:
  1. c
  2. u8 SPIReadByte(void)
  3. {
  4.     SPDAT = 0xFF;           // 发送 dummy byte 以生成时钟
  5.     while(SPIF == 0);       // 等待接收完成
  6.     SPIClearFlag();        // 清除标志位
  7.     return SPDAT;           // 返回接收到的数据
  8. }
复制代码

二、SPI通信模式分析

1. 查询模式 vs 中断模式

| 模式         | 优点                     | 缺点                         |
|--------------|--------------------------|------------------------------|
| 查询模式     | 实现简单,资源占用少     | CPU占用高,效率低            |
| 中断模式     | 高效,适用于多任务环境   | 需要中断服务程序,复杂度增加 |

建议:
对于实时性要求较高的系统,推荐使用中断模式。
若使用中断模式,应确保中断服务程序中及时清除标志并释放BSPIBusy。

三、潜在问题与优化建议

1. 数据类型与命名规范
u8应为标准的typedef定义(如typedef unsigned char u8;),确保可移植性。
函数名使用大写开头(如SPIWriteByte)是良好的命名习惯,建议统一命名风格。

2. 错误处理机制缺失

当前函数未处理SPI通信中可能出现的错误,如写冲突(WCOL)或溢出等。

建议:
在查询模式下,应在等待SPIF后检查WCOL标志。
若发生写冲突,应进行错误处理或重传机制。

3. 中断服务程序缺失

中断模式下需提供对应的中断服务程序(ISR),否则无法触发BSPIBusy的清除。

示例ISR:
  1. c
  2. void SPIISR(void) interrupt SPIVECTOR
  3. {
  4.     if(SPIF)
  5.     {
  6.         BSPIBusy = 0;
  7.         SPIClearFlag();
  8.     }
  9. }
复制代码

四、总结与建议

该SPI通信函数实现较为基础,适合用于简单的8051系统。为提升代码的健壮性与可移植性,建议如下:

1. 完善函数定义:修正SPIReadByte的函数原型与实现。
2. 增强错误处理:加入对WCOL等异常情况的判断与处理。
3. 提供中断服务程序:确保中断模式能正常退出等待。
4. 统一命名与类型定义:提升代码可读性与可维护性。
5. 文档与注释更新:补充函数说明、参数描述与版本变更记录。

如需进一步支持(如DMA模式、SPI主从切换、多从机管理等),欢迎继续交流。

如您有具体的硬件平台或SPI设备型号,也可提供,以便进行更针对性的优化建议。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:525
  • 最近打卡:2025-10-01 17:38:30
已绑定手机

46

主题

2246

回帖

7894

积分

论坛元老

积分
7894
发表于 3 天前 | 显示全部楼层
SPI的读/写是同时进行的,这两个函数可用于单纯的写,或者单纯的读。
回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:60
  • 最近打卡:2025-09-30 13:18:37

11

主题

20

回帖

342

积分

中级会员

积分
342
发表于 3 天前 | 显示全部楼层
乘风*** 发表于 2025-9-30 14:07
SPI的读/写是同时进行的,这两个函数可用于单纯的写,或者单纯的读。

u8 SPI_TransferByte(u8 dat)
{
    if(ESPI)
    {
        B_SPI_Busy = 1;
        SPDAT = dat;
        while(B_SPI_Busy);
    }
    else
    {
        SPDAT = dat;
        while(SPIF == 0);
        SPI_ClearFlag();
    }
    return SPDAT;
}

那我是不是可以写个这个函数,实现同时读写的功能呢

点评

可以  发表于 3 天前
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-3 08:48 , Processed in 0.121450 second(s), 64 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表