找回密码
 立即注册
楼主: 虹涛犹珷

STC单片机做为丛机,在SPI通信下第一个数据会丢失?

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2024-4-8 09:06:04 | 显示全部楼层
SPI从机,你用
STC32/STC8H/STC8G/STC8C/STC8A/STC12H1K16
我们有完善的从机演示程序

截图202404080903552906.jpg

截图202404080906009160.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:417
  • 最近打卡:2025-04-30 21:39:09
已绑定手机

34

主题

2096

回帖

2206

积分

荣誉版主

积分
2206
发表于 2024-4-8 13:44:25 | 显示全部楼层
SPI有四种时序,看看是不是前后沿问题,导致多出一位
睁开眼睛做场梦~~~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:57
  • 最近打卡:2025-04-29 14:15:11

6

主题

33

回帖

596

积分

高级会员

积分
596
发表于 2024-4-8 13:44:46 | 显示全部楼层
神*** 发表于 2024-4-8 09:06
SPI从机,你用
STC32/STC8H/STC8G/STC8C/STC8A/STC12H1K16
我们有完善的从机演示程序

您好,我移植ISP软件上面的SPI程序,丛机终于可以返回正确的数据了,但是还有个问题,如果丛机的中断里面的操作稍微有延时,就会导致SPI丢失数据,按道理这个现象可以避免的,一时不知道如何操作了。


这是丛机的程序:

//**************************主函数**********************//
data uint8_t Flag = 0;
data uint16_t Addr = 0;
void main(void)
{       
    /***********************************************************/ //SPI初始化
    SPDAT  = 0x00;  
    SPCTL  = 0x43;  //使能SPI从机模式
    SPSTAT = 0xc0;  //清中断标志
        /***********************************************************/ //设置中断
        EADC_SPI=1;
    AUXR |= 0x08;
    EA = 1;
        while (1)
    {
        if(P22==0)
        {
            while(P22==0);
            HAL_SystemReset(); //免断电下载
        }
    }
}
//**************************中断函数**********************//
void ADC_SPI_ISR() interrupt 5
{
    SPSTAT = 0xc0; //清中断标志
    if(Flag == 0)
    {
        if (SPDAT == 0x03)
        {
            Flag++;
            Addr = 0;
        }
    }
    else
    {
        Flag++;
        Addr <<= 8;
        Addr |= SPDAT;
        if (Flag >= 3)
        {
            Flag = 0;
            if (Addr < 0x1000) //4K EEPROM
            {
                //SPDAT = HAL_FLASH_ReadByte(Addr); //加入读取EEPROM的操作就会返回0x00,就算不使用读取EEPROM的函数,加个100us的延时,也会导致丢数据
                SPDAT = 0xCC;
                P27 = !P27;
                return;
            }
        }
    }
    SPDAT = 0x00;
}

当注释掉SPDAT = HAL_FLASH_ReadByte(Addr);时,可以正确返回数据:

1.png

下面是主机的程序,比较简单,也是移植ISP软件上面的,就发送了4个数据过去,0x03,0x40,0x00,0xFF:

//**************************主函数**********************//
void main(void)
{       
    uint8_t Byte;
   
    P10=1;
    SPCTL = 0x53;   //使能SPI主机模式
    SPSTAT = 0xc0;  //清中断标志
    MyUart_Init();
        while (1)
    {
        if(P22==0)
        {
            while(P22==0);
            //发送数据
            P10 = 0;                    //拉低从机SS管脚
            
            SPDAT = 0x03;               //发送测试数据
            while (!(SPSTAT & 0x80));   //查询完成标志
            SPSTAT = 0xc0;              //清中断标志
            Byte = SPDAT;
            
            SPDAT = 0x04;               //发送测试数据
            while (!(SPSTAT & 0x80));   //查询完成标志
            SPSTAT = 0xc0;              //清中断标志
            Byte = SPDAT;
            
            SPDAT = 0x00;               //发送测试数据
            while (!(SPSTAT & 0x80));   //查询完成标志
            SPSTAT = 0xc0;              //清中断标志
            Byte = SPDAT;
            
            SPDAT = 0xFF;               //发送测试数据
            while (!(SPSTAT & 0x80));   //查询完成标志
            SPSTAT = 0xc0;              //清中断标志
            Byte = SPDAT;
            HAL_UART1_TransmitByte(SPDAT);

            P10 = 1;                    //拉高从机的SS管脚
        }
    }
}

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:57
  • 最近打卡:2025-04-29 14:15:11

6

主题

33

回帖

596

积分

高级会员

积分
596
发表于 2024-4-8 13:47:20 | 显示全部楼层
晓*** 发表于 2024-4-8 13:44
SPI有四种时序,看看是不是前后沿问题,导致多出一位

主丛机使用的都是SPI1_MODE0,时钟在逻辑 0 处空闲 ,数据会在SCK的上升沿上读取,在下降沿上发送。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:57
  • 最近打卡:2025-04-29 14:15:11

6

主题

33

回帖

596

积分

高级会员

积分
596
发表于 2024-4-8 13:49:32 | 显示全部楼层
虹涛*** 发表于 2024-4-8 13:44
您好,我移植ISP软件上面的SPI程序,丛机终于可以返回正确的数据了,但是还有个问题,如果丛机的中断里面 ...

这是使用读取的FLASH后:

2.png

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:57
  • 最近打卡:2025-04-29 14:15:11

6

主题

33

回帖

596

积分

高级会员

积分
596
发表于 2024-4-8 18:20:25 | 显示全部楼层
乘风*** 发表于 2024-4-8 09:03
从机不知道要发什么数据情况下,可以先发固定数据作为握手信号,主机也可以凭此判定从机是否有正常响应。 ...

现在可以连续读取数据了,就是丛机这里的中断里面不能操作太久,太久会导致丢数据,有没有好办法?
这是丛机主函数:

    while (1)
    {
        if (P14 == 1)
        {
            Step=0;
        }
        if(P22==0)
        {
            while(P22==0);
            HAL_SystemReset(); //免断电下载
        }
    }
这是丛机中断程序:

//**************************中断函数**********************//
void ADC_SPI_ISR() interrupt 5
{
    SPSTAT = 0xc0; //清中断标志
    if(Step == 0)
    {
        if (SPDAT == 0x03)
        {
            Step++;
            Addr = 0;
        }
    }
    else if ((Step == 1)||(Step == 2))
    {
        Step++;
        Addr <<= 8;
        Addr |= SPDAT;
    }
    if (Step == 3)
    {
        if (Addr >= 0x1000) //4K EEPROM
        {
            Addr = 0;
        }
        //使用读取EEPROM的操作就会返回0x00,就算不使用读取EEPROM的函数,加个100us的延时,也会导致丢数据
        //SPDAT = HAL_FLASH_ReadByte(Addr);
        SPDAT = Local_Buf[Addr]; //直接读取数组就不会丢数据
        Addr++;
        return;
    }
    SPDAT = 0x00;
}

这是主机发送的数据:


2.png 微信截图_20240408181417.png




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-4-8 18:51:03 | 显示全部楼层
虹涛*** 发表于 2024-4-8 18:20
现在可以连续读取数据了,就是丛机这里的中断里面不能操作太久,太久会导致丢数据,有没有好办法?
这是 ...

中断里面接收完数据,设置必要标志后就退出,不要执行太多功能。
在主循环里面判定标志再执行后续操作。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:57
  • 最近打卡:2025-04-29 14:15:11

6

主题

33

回帖

596

积分

高级会员

积分
596
发表于 2024-4-9 09:15:25 | 显示全部楼层
乘风*** 发表于 2024-4-8 18:51
中断里面接收完数据,设置必要标志后就退出,不要执行太多功能。
在主循环里面判定标志再执行后续操作。 ...

把读取EEPROM的操作放到主函数里面,会不会来不及传输给主机,主机就发送下一个数据过来了。想问下,主机是不是不会等待丛机发送数据?丛机想做到接收到数据,再回传给主机,只能把主机的通信速度放慢,这样估计可行。我再试试。PS:那些FLASH芯片是如何做到快速回传数据的,我感觉单片机做不到快速回传数据。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-4-9 09:19:33 | 显示全部楼层
虹涛*** 发表于 2024-4-9 09:15
把读取EEPROM的操作放到主函数里面,会不会来不及传输给主机,主机就发送下一个数据过来了。想问下,主机 ...

如果回传的数据是存放在EEPROM里面的话,在芯片上电初始化时就可以读取出来放到RAM里面,回传时从RAM里面获取。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:57
  • 最近打卡:2025-04-29 14:15:11

6

主题

33

回帖

596

积分

高级会员

积分
596
发表于 2024-4-9 15:21:44 | 显示全部楼层
乘风*** 发表于 2024-4-9 09:19
如果回传的数据是存放在EEPROM里面的话,在芯片上电初始化时就可以读取出来放到RAM里面,回传时从RAM里面 ...

RAM没这么大吧?有4K的EEPROM,而且丛机开始不知道主机需要读取哪里的数据,需要接收到主机的命令和地址才知道读取哪些数据。如果读取几个数据,倒是可以放RAM。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 02:10 , Processed in 0.124820 second(s), 117 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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