神农鼎
发表于 2024-4-8 09:06:04
SPI从机,你用
STC32/STC8H/STC8G/STC8C/STC8A/STC12H1K16
我们有完善的从机演示程序
晓飛飛
发表于 2024-4-8 13:44:25
SPI有四种时序,看看是不是前后沿问题,导致多出一位
虹涛犹珷
发表于 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);时,可以正确返回数据:
下面是主机的程序,比较简单,也是移植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管脚
}
}
}
虹涛犹珷
发表于 2024-4-8 13:47:20
晓飛飛 发表于 2024-4-8 13:44
SPI有四种时序,看看是不是前后沿问题,导致多出一位
主丛机使用的都是SPI1_MODE0,时钟在逻辑 0 处空闲 ,数据会在SCK的上升沿上读取,在下降沿上发送。
虹涛犹珷
发表于 2024-4-8 13:49:32
虹涛犹珷 发表于 2024-4-8 13:44
您好,我移植ISP软件上面的SPI程序,丛机终于可以返回正确的数据了,但是还有个问题,如果丛机的中断里面 ...
这是使用读取的FLASH后:
虹涛犹珷
发表于 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++;
return;
}
SPDAT = 0x00;
}
这是主机发送的数据:
乘风飞扬
发表于 2024-4-8 18:51:03
虹涛犹珷 发表于 2024-4-8 18:20
现在可以连续读取数据了,就是丛机这里的中断里面不能操作太久,太久会导致丢数据,有没有好办法?
这是 ...
中断里面接收完数据,设置必要标志后就退出,不要执行太多功能。
在主循环里面判定标志再执行后续操作。
虹涛犹珷
发表于 2024-4-9 09:15:25
乘风飞扬 发表于 2024-4-8 18:51
中断里面接收完数据,设置必要标志后就退出,不要执行太多功能。
在主循环里面判定标志再执行后续操作。 ...
把读取EEPROM的操作放到主函数里面,会不会来不及传输给主机,主机就发送下一个数据过来了。想问下,主机是不是不会等待丛机发送数据?丛机想做到接收到数据,再回传给主机,只能把主机的通信速度放慢,这样估计可行。我再试试。PS:那些FLASH芯片是如何做到快速回传数据的,我感觉单片机做不到快速回传数据。{:dizzy:}
乘风飞扬
发表于 2024-4-9 09:19:33
虹涛犹珷 发表于 2024-4-9 09:15
把读取EEPROM的操作放到主函数里面,会不会来不及传输给主机,主机就发送下一个数据过来了。想问下,主机 ...
如果回传的数据是存放在EEPROM里面的话,在芯片上电初始化时就可以读取出来放到RAM里面,回传时从RAM里面获取。
虹涛犹珷
发表于 2024-4-9 15:21:44
乘风飞扬 发表于 2024-4-9 09:19
如果回传的数据是存放在EEPROM里面的话,在芯片上电初始化时就可以读取出来放到RAM里面,回传时从RAM里面 ...
RAM没这么大吧?有4K的EEPROM,而且丛机开始不知道主机需要读取哪里的数据,需要接收到主机的命令和地址才知道读取哪些数据。如果读取几个数据,倒是可以放RAM。