乐此不疲 发表于 2023-5-17 21:38:08

请教,硬件SPI单主从通讯例程中的标志busy的用途

本帖最后由 乐此不疲 于 2023-5-17 22:16 编辑

请教各位管理员及各位大神,希望能指点一下,先谢了!
问题:我没能理解程序中的busy这个标志的用途是什么,在mcu主机与单个从机(单片机spi总线上仅有一个设备)通讯时没有这个标志会出现什么状况?


数据手册中的例程如下:

#include "stc8h.h"
#include "intrins.h"
sbit SS = P1^0;
sbit LED = P1^1;
bit busy;
void SPI_Isr() interrupt 9
{
SPSTAT = 0xc0; //清中断标志
SS = 1; //拉高从机的 SS 管脚
busy = 0;
LED = !LED; //测试端口
}
void main()
{
P_SW2 |= 0x80; //使能访问 XFR
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
LED = 1;
SS = 1;
busy = 0;
SPCTL = 0x50; //使能 SPI 主机模式
SPSTAT = 0xc0; //清中断标志
IE2 = ESPI; //使能 SPI 中断
EA = 1;
while (1)
{
while (busy);
busy = 1;
SS = 0; //拉低从机 SS 管脚
SPDAT = 0x5a; //发送测试数据

}
}




乘风飞扬 发表于 2023-5-18 13:36:33

SPI是串行接口,发送一个字节的数据需要一位一位的发送,一个字节发送完成会产生中断标志,如果开了中断的话就会进入中断。
程序里发送数据前设置 busy = 1; 在发送完成中断里设置 busy = 0;
这样就可以通过判断 busy 值来确定写入 SPDAT 的数据是否发送完成,发送完成就可以发送下一个数据。
否则,如果没有发送完成就写入新的内容到 SPDAT 会产生覆盖导致数据丢失。

乐此不疲 发表于 2023-5-18 19:03:38

乘风飞扬 发表于 2023-5-18 13:36
SPI是串行接口,发送一个字节的数据需要一位一位的发送,一个字节发送完成会产生中断标志,如果开了中断的 ...

多谢指点,因为我没有想到新旧数据的覆盖问题所以没能理解这个标志的意义,现在清楚了。

梁工 发表于 2023-5-18 21:48:03

如果么有busy标志,则一个数据还没发送完毕,又装下一个数据,最终乱套了。

乐此不疲 发表于 2023-5-19 19:52:52

本帖最后由 乐此不疲 于 2023-5-19 21:19 编辑

梁工 发表于 2023-5-18 21:48
如果么有busy标志,则一个数据还没发送完毕,又装下一个数据,最终乱套了。 ...
多谢指点,我用STC8H8K64U(开天斧实验板)做硬件SPI通讯测试时遇到一个问题,好几天没有理出头绪,希望帮忙看看我的代码哪里弄错了,先谢了!
我实验用到TFT-LCD的驱动是ILI9481,他是三线SPI,要求数据中包含一位指令/数据(D/CX控制)的命令,也就是传输的字节为9位的数据,我曾经在本坛发帖分享过用硬件SPI以查询方式每次发送两个字节的方法的驱动方法,原帖:开天斧三.1板测试——硬件SPI驱动三线SPI_TFT屏(代码分享)https://www.stcaimcu.com/forum.php?mod=viewthread&tid=1091(出处: 国芯论坛-STC全球32位8051爱好者互助交流社区)
此贴之后我又实验了I/0模拟输出一个脉冲+以查询方式发送8位字节数据的模式,实验也很成功,在时钟设定为40mhz状态下刷屏很爽很稳定。接下来我继续测试用硬件SPI以中断的方式来驱动这个屏幕,结果调试了很久也没能成功刷屏,请帮忙看看。
没有调试成功的代码如下:

//====硬件SPI初始化函数=========================
void spi_init()
{
    u8 n;
    n = 2;                        //分频系数n取值0、1、2、3对应的时钟分频系数为:1/4、1/8、1/16、1/2
    P_SW1|= 0x01<<2;//使用SPI通道2
    P2PU = 0x2A;        //SDA、SCL、CS端口配置内部上拉电阻(4.1K)
    P2M1 = 0x00;
    P2M0 = 0x2A;
    SPDAT = 0;                 //清空数据寄存器
    SPSTAT = 0xC0;         //清除所有标志(共两个)
    SPCTL = 0x9C|(n);//忽略SS、禁止SPI、高位先行、主机模式、时钟空闲时为高、上升沿(第二个边沿)采样、1/16时钟分频
    IE2 = ESPI;
    busy = 0;
    cs = 1;
}
//====写8位数据函数============================
//中断方式
void SPI_WriteByte(u8 temp)
{
    SPI_Enable();                //使能硬件SPI
    NOP1();
    SPDAT = temp;         //发送数据
    busy=1;                        //保持发送状态
    while(busy);

    /*
            if(busy==0)                        //判断总线状态
            {
                    busy=1;                        //保持发送状态
                    SPDAT = temp;         //发送数据
            }
            else
            {
                    sda=1;                        //释放总线
                    scl=1;
              cs= 1;                        //挂断从机
            }
    */
}
//==============写指令函数======================
void write_command(u8 comd)
{
    cs=0;                        //使能从机响应
    sda=0;                        //D/CX=0(发送指令)
    NOP1();
    scl=0;                        //模拟一个下跳时钟脉冲
    NOP1();                        //适当延时保障脉冲宽度
    scl=1;                        //拉高时钟线恢复空闲状态
    NOP1();
    sda=1;                        //释放总线
    SPI_WriteByte(comd);//使能硬件SPI发送一个字节
}
//==============写数据函数======================
void write_data(u8 dat)
{
    cs=0;                        //使能从机响应
    sda=1;                        //D/CX=1(发送数据)
    NOP1();
    scl=0;                        //模拟一个下跳时钟脉冲
    NOP1();                        //适当延时保障脉冲宽度
    scl=1;                        //拉高时钟线恢复空闲状态
    NOP1();
    SPI_WriteByte(dat);//使能硬件SPI发送一个字节
}
//====SPI中断函数=================================
void SPI_Isr() interrupt 9
{
    busy=0;
    SPSTAT = 0xc0; //中断发生时一个字节数据已经发送完毕、清中断标志等待下一次触发
    SPI_Disable();//禁止硬件SPI
    sda=1;
    scl=1;
    cs= 1;
}






梁工 发表于 2023-5-19 21:33:14

乐此不疲 发表于 2023-5-19 19:52
多谢指点,我用STC8H8K64U(开天斧实验板)做硬件SPI通讯测试时遇到一个问题,好几天没有理出头绪,希望帮忙 ...

查询方式SPI都成功了,改SPI中断不应该有问题啊!

乐此不疲 发表于 2023-5-20 12:47:33

梁工 发表于 2023-5-19 21:33
查询方式SPI都成功了,改SPI中断不应该有问题啊!

这几天就陷入到这里扑腾不出去了,我使用开天斧板子加这个彩屏的的实验计划是I/O模拟SPI、硬件SPI双字节发送、硬件查询1bit+SPI发送,硬件中断1bit+SPI发送、SPI-DMA发送,结果弄到这里就咋弄都不行了,而这段中断方式的代码如果发送一个字节数据时、用逻辑分析仪看时序波形也是没有问题的,但就是无法点亮屏幕,诡异!

神农鼎 发表于 2023-5-20 12:53:10

使用开天斧板子====你先用仿真来调试


STC8H8K64U自带硬件USB直接仿真步骤 - 编译器/仿真器/ISP下载/做自己的ISP/ID号加密/程序加密后传输 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

页: [1]
查看完整版本: 请教,硬件SPI单主从通讯例程中的标志busy的用途