打印

STM8S103 SPI 问题求帮助

[复制链接]
1432|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
doykee|  楼主 | 2017-8-25 17:51 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
使用STM8S103作为SPI Slave设备,但是STM8中断里面收到的全是0x1,收不到正确的数据,STM8发送看起来是对的。求大神帮忙指点一下,下面是代码:
void spi_slave_init()
{
    //NSS
    GPIOA->DDR &= ~SPI_SSEL_PIN; //输入模式
    GPIOA->CR1 &= ~SPI_SSEL_PIN; //浮空输入
    GPIOA->ODR &= (uint8_t)~SPI_SSEL_PIN; //write low

    GPIOC->DDR |= SPI_MISO_PIN; //输出模式
    GPIOC->CR1 |= SPI_MISO_PIN; //推挽输出
   
    GPIOC->DDR &= ~SPI_MOSI_PIN; //输入模式
    GPIOC->CR1 &= ~SPI_MOSI_PIN; //浮空输入
   
    GPIOC->DDR &= ~SPI_CLK_PIN;  //输入模式
    GPIOC->CR1 &= ~SPI_CLK_PIN;  //浮空输入
   
        SPI_DeInit();       
        // Initialize SPI in Slave mode, NSS hardwere management  */
        SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_SLAVE, SPI_CLOCKPOLARITY_HIGH,
                SPI_CLOCKPHASE_2EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,(uint8_t)0x07);
        SPI_ITConfig(SPI_IT_RXNE, ENABLE);// Receive buffer not empty interrupt Enable
        SPI_Cmd(ENABLE); // SPI enable
}

uint8_t spi_rw(uint8_t byte)
{
    char ch = 0;
   
    while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
    SPI->DR = byte;

    while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET);
    ch = ((uint8_t)SPI->DR);
   
    return ch;
}

INTERRUPT_HANDLER(SPI_IRQHandler, 10)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
  uint8_t Rx_byte;
  Rx_byte = spi_rw(0x18);
  printf("%x ", Rx_byte);
}
中断里面收到的打印全是0x1,不知道什么原因啊,

相关帖子

沙发
doykee|  楼主 | 2017-8-25 17:54 | 只看该作者
补充一下: 没有使用片选引脚,不知道会有什么问题呢? 在spi master能正确收到stm8发送的0x18,

使用特权

评论回复
板凳
feelhyq| | 2017-8-25 17:59 | 只看该作者
doykee 发表于 2017-8-25 17:54
补充一下: 没有使用片选引脚,不知道会有什么问题呢? 在spi master能正确收到stm8发送的0x18, ...

STM8 作为slave的时候,收发数据的处理不是这样的。

发数据:只要发送FIFO不为空, 一个劲的往里面丢数据

收数据:利用中断,接收到一个数据后立马发数据,判断条件和上面一样

使用特权

评论回复
地板
doykee|  楼主 | 2017-8-25 18:22 | 只看该作者
feelhyq 发表于 2017-8-25 17:59
STM8 作为slave的时候,收发数据的处理不是这样的。

发数据:只要发送FIFO不为空, 一个劲的往里面丢数 ...

你的意思是接收中断应该是这样的吗?
INTERRUPT_HANDLER(SPI_IRQHandler, 10)
{
  uint8_t Rx_byte;
  Rx_byte = (uint8_t)SPI->DR;
  SPI->DR = 0x18;
  printf("%x ", Rx_byte);
}

使用特权

评论回复
5
doykee|  楼主 | 2017-8-25 18:24 | 只看该作者
feelhyq 发表于 2017-8-25 17:59
STM8 作为slave的时候,收发数据的处理不是这样的。

发数据:只要发送FIFO不为空, 一个劲的往里面丢数 ...

有slave 模式的sample code吗? 希望有code参考一下,

使用特权

评论回复
6
山东电子小菜鸟| | 2017-8-25 19:56 | 只看该作者
MARK下 谢谢

使用特权

评论回复
7
feelhyq| | 2017-8-25 21:08 | 只看该作者
本帖最后由 feelhyq 于 2017-8-25 21:11 编辑
doykee 发表于 2017-8-25 18:24
有slave 模式的sample code吗? 希望有code参考一下,

闭上眼睛,想象一下SPI slave传输应该是什么样子的,关键点在于slave 端不知道master什么时候要读或者写数据(准确的讲是什么时候来时钟),既然不知道,那么我作为slave就应该提前把数据准备好,这样就能保证master准确访问slave

使用特权

评论回复
8
feelhyq| | 2017-8-25 22:41 | 只看该作者
doykee 发表于 2017-8-25 18:22
你的意思是接收中断应该是这样的吗?
INTERRUPT_HANDLER(SPI_IRQHandler, 10)
{

不好意思,只谈思想不谈代码,这样的代码我都写吐了,你明白了其中的原理,代码根本不是问题

使用特权

评论回复
9
zhangxiyi5277| | 2017-8-26 01:15 | 只看该作者
买个逻辑分析,对着最新的数据手册上的时序图,,一点一点啃就是了,

使用特权

评论回复
10
doykee|  楼主 | 2017-8-28 11:21 | 只看该作者
feelhyq 发表于 2017-8-25 22:41
不好意思,只谈思想不谈代码,这样的代码我都写吐了,你明白了其中的原理,代码根本不是问题 ...

用逻分抓时序图看起来没有问题啊,slave的输出也是对的,既然slave可以输出,也可以触发中断,为什么中断里面读的数据不对呢?
附近是逻分抓的时序图。

spi.png (42.42 KB )

SPI时序

SPI时序

使用特权

评论回复
11
feelhyq| | 2017-8-28 11:40 | 只看该作者
doykee 发表于 2017-8-28 11:21
用逻分抓时序图看起来没有问题啊,slave的输出也是对的,既然slave可以输出,也可以触发中断,为什么中断 ...

SPI的模式配置对了吗?  PHA 和PCLK的配置

使用特权

评论回复
12
doykee|  楼主 | 2017-8-28 12:09 | 只看该作者
feelhyq 发表于 2017-8-28 11:40
SPI的模式配置对了吗?  PHA 和PCLK的配置

用的是库函数,配置 SPI_MODE_SLAVE 模式,
SPI_DeInit();        
SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_SLAVE, SPI_CLOCKPOLARITY_HIGH,     SPI_CLOCKPHASE_2EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,(uint8_t)0x07);
SPI_ITConfig(SPI_IT_RXNE, ENABLE);// Receive buffer not empty interrupt Enable
SPI_Cmd(ENABLE); // SPI enable

另外 好像没有看到 PHA 和PCLK 呢? 这2个寄存器在哪里?

使用特权

评论回复
13
feelhyq| | 2017-8-28 12:27 | 只看该作者
这个是时钟的:SPI_CLOCKPOLARITY_HIGH     这个是相位PHASE: SPI_CLOCKPHASE_2EDGE ,从你设置的看,从机都设置的是1 ,那么主机也要设置为1

使用特权

评论回复
14
doykee|  楼主 | 2017-8-28 12:42 | 只看该作者
feelhyq 发表于 2017-8-28 12:27
这个是时钟的:SPI_CLOCKPOLARITY_HIGH     这个是相位PHASE: SPI_CLOCKPHASE_2EDGE ,从你设置的看,从机 ...

是的,是Mode 3, 主机master这边也是mode 3,逻分能正确解析,感觉还是slave端的设置问题,不知道哪里还需要设置的了,

使用特权

评论回复
15
feelhyq| | 2017-8-28 16:18 | 只看该作者
doykee 发表于 2017-8-28 12:42
是的,是Mode 3, 主机master这边也是mode 3,逻分能正确解析,感觉还是slave端的设置问题,不知道哪里还 ...

0x18是slave要发送数据之一吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

8

帖子

0

粉丝