打印
[STM8]

实验分享【STM8-SO8】05-SPI的使用

[复制链接]
459|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
spi, STM8, IO, AC, ck


STM8S001J3 由于 VCAP 的需要因此少了一支 I/O 引脚,跟另外 2 颗 8 引脚的 STM8 比较起来少了 PB7,而这一支引脚的复用功能是 SPI 的 MISO,因此对于 STM8S001J3 来说 SPI 是没有 MISO 引脚的。



SPI 的 CPOL 与 CPHA 设定决定了四种时序关系:

CPOL         CLOCK POLARITY  时钟极性
        0       SCK空闲状态保持低电位
        1       SCK空闲状态保持高电位
CPHA         CLOCK PHASE     时钟相位
        0       SCK时钟的第一个边缘进行数据采集
        1       SCK时钟的第二个边缘进行数据采集



一般比较常用的似乎是 CPOL = 0 , CPHPA = 0,比如说外接 74HC595 这类的 8 位串行入并行出的移位寄存器就需要做这样的设定,也就是在时钟上升缘时将数据移入寄存器内。



由于后面我打算连接 MAX7219 显示模块,因此先实现一个 SPI 的测试程序来熟悉一下功能,我使用逻辑分析仪采集数据的输出,程序中让 STM8S001J3 由 SPI 引脚输出 0x01、0x02、0x04、0x08、0x10、0x20、0x40、0x80 数据,NSS 引脚由程序控制输出。测试程序中有一个需要注意的地方,由于 MOSI 这支引脚也在 pin8 与烧录使用的 SWIM 同一支脚,因此程序的一开始需要先加上一个 5 秒的延时代码。

SPI 初始化:
  • SPI_Init(SPI_FIRSTBIT_MSB,           // 高位在前
  •          SPI_BAUDRATEPRESCALER_2,    // 传输速率为主时钟 1/2
  •          SPI_MODE_MASTER,            // 主机模式
  •          SPI_CLOCKPOLARITY_LOW,   // CPOL = 0
  •          SPI_CLOCKPHASE_1EDGE,       // CPHA = 0
  •          SPI_DATADIRECTION_2LINES_FULLDUPLEX,   // 全双工模式
  •          SPI_NSS_SOFT,               // 软件管理 NSS
  •          0x07);                      // CRC 校验

[color=rgb(51, 102, 153) !important]复制代码



逻辑分析仪数据采集:



在先前的实验没有留意 STM8S001J3 上电后的系统时钟缺省设定是多少?直觉上一直认为应该是内部 HSI 的 16MHz,而程序中 SPI 的传输速率设定在主时钟的 1/2,因此 SCK 频率应该是 8MHz,但是在逻辑分析仪采集的 SCK 频率却是 1MHz!



查询规格书看到了这样的说明:



原来芯片复位 (RESET) 之后的可编程分频器设定在 8,因此主时钟频率就是 2MHz,所以我所采集到的 SCK 频率就是 1MHz 没错。为了得到比较快速的传输速率,我在 main 回圈的开头增加了对时钟设定的函数,将时钟设定在最高的 16MHz。

CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);  

运行结果也得到了预期的 8MHz:




一个错误的教训!我一开始是将 CLK_HSIPrescalerConfig() 函数放在延时 5 秒代码之前,然而编程烧录过一次之后的再次编程就失败了!难道这颗芯片变砖了?延时 5 秒的代码是官方提供的,这应该是在主频为 2MHz 的条件下计算的,然而目前在延时 5 秒前我就将主频设定在 16MHz,那是否延时的时间就只剩不到 1 秒呢?原本板子在上电后可以有足够的时间按下 IAR 上的编程动作,现在延时时间减少了,我假如按钮编程的动作快一点的话是否可以就救回这一颗芯片,让芯片可以重新再烧录呢?

在试了很多次之后我放弃了,还好我在 ST 天猫也买了芯片,只好换上芯片后继续后续的实验。

main 回圈:

  • void main(void)
  • {
  •   uint8_t Dta[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
  •   uint8_t idx = 0;
  •   /* -------------STM8S001 startup-------------- */
  •   /* delay for SWIM connection: ~5seconds */
  •   STARTUP_SWIM_DELAY_5S;
  •   /* configure unbonded pins */
  •   CONFIG_UNUSED_PINS_STM8S001;
  •   GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST);     // NSS
  •   GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
  •   /* ------------------------------------------- */
  •   /*High speed internal clock prescaler: 1*/
  •   CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  •   /* SPI configuration */
  •   SPI_DeInit();
  •   /* Initialize SPI in Slave mode  */
  •   SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_LOW,
  •            SPI_CLOCKPHASE_1EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,0x07);
  •   /* Enable the SPI*/
  •   SPI_Cmd(ENABLE);
  •   while (1)
  •   {
  •     while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
  •     GPIO_WriteLow(GPIOA, GPIO_PIN_3);   // NSS = 0
  •     SPI_SendData(Dta[idx++]);
  •     if(idx == 8) idx = 0;
  •     GPIO_WriteHigh(GPIOA, GPIO_PIN_3);  // NSS = 1
  •   }
  • }

[color=rgb(51, 102, 153) !important]复制代码


本文转载于【STM8-SO8】05-SPI的使用
http://www.stmcu.org.cn/module/forum/thread-619406-1-1.html



使用特权

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

本版积分规则

个人签名:每天都要开心呀

210

主题

505

帖子

4

粉丝