找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 1039|回复: 4
打印 上一主题 下一主题
收起左侧

单片机软件SPI的问题

[复制链接]
跳转到指定楼层
楼主
SPI也就4种模式,csdn扒了个SPI的驱动,改了下在STC15单片机下不能正常使用,读取全是0xFF。目前用到的案例是CPOL不限,CPHA =1。也就是1/3模式,

以下是代码:
spi.h:
  1. #ifndef __SPI_H
  2. #define __SPI_H

  3. #define FOSC        22118400UL
  4. #define BAUD        115200

  5. #include "STC15W4K.H"      
  6. #include<intrins.h>
  7. typedef unsigned char u8;
  8. typedef unsigned int u16;

  9. #define CS_L                                                         P16=0
  10. #define CS_H                                                         P16=1
  11. #define SCK_L                                                  P15=0
  12. #define SCK_H                                                  P15=1
  13. #define MOSI_L                                                P13=0
  14. #define MOSI_H                                                P13=1
  15. #define MISO              P44

  16. u8 SOFT_SPI_RW_MODE(u8 write_dat);

  17. u8 SPI2_ReadWriteByte(u8 TxData);

  18. #endif
复制代码

spi.c:
  1. #include "spi.h"
  2. #define  SPI_Mode 3  //选择SPI的模式

  3. //CPOL:规定了SCK时钟信号空闲状态的电平(0-低电平,1-高电平)
  4. //CPHA:规定了数据是在SCK时钟的上升沿还是下降沿被采样(0-第一个时钟边沿开始采样,1-第二个时钟边沿开始采样)
  5. //模式0:CPOL=0,CPHA =0  SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)
  6. //模式1:CPOL=0,CPHA =1  SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)
  7. //模式2:CPOL=1,CPHA =0  SCK空闲为高电平,数据在SCK的下降沿被采样(提取数据)
  8. //模式3:CPOL=1,CPHA =1  SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)


  9. /*spi延时函数,微秒*/
  10. static void spi_delay(u16 time)
  11. {
  12.     u8 i = 0;
  13.     while(time--)
  14.     {
  15.         i = 10;
  16.         while(i--) ;
  17.     }
  18. }

  19. #if SPI_Mode==0
  20. /* CPOL = 0, CPHA = 0 */
  21. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  22. {
  23.     u8 i, read_dat = 0;
  24.     SCK_L;
  25.     for(i = 0; i < 8; i++)
  26.     {
  27.         if(write_dat & 0x80)
  28.             MOSI_H;
  29.         else
  30.             MOSI_L;
  31.         write_dat <<= 1;
  32.         spi_delay(1);
  33.         SCK_H;
  34.         read_dat <<= 1;

  35.         if(MISO)
  36.             read_dat++;
  37.         spi_delay(1);
  38.         SCK_L;
  39.         _nop_();
  40.     }
  41.     return read_dat;
  42. }
  43. #elif SPI_Mode==1
  44. /* CPOL=0,CPHA=1 */
  45. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  46. {
  47.     u8 i, read_dat = 0;
  48.     SCK_L;
  49.     for(i = 0; i < 8; i++)
  50.     {
  51.         SCK_H;
  52.         if(write_dat & 0x80)
  53.             MOSI_H;
  54.         else
  55.             MOSI_L;
  56.         write_dat <<= 1;
  57.         spi_delay(1);
  58.         SCK_L;
  59.         read_dat <<= 1;

  60.         if(MISO)
  61.             read_dat++;
  62.         spi_delay(1);
  63.     }
  64.     return read_dat;
  65. }
  66. #elif SPI_Mode==2
  67. /* CPOL=1,CPHA=0 */
  68. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  69. {
  70.     u8 i, read_dat = 0;
  71.     SCK_H;
  72.     for(i = 0; i < 8; i++)
  73.     {
  74.         if(write_dat & 0x80)
  75.             MOSI_H;
  76.         else
  77.             MOSI_L;
  78.         write_dat <<= 1;
  79.         spi_delay(1);
  80.         SCK_L;
  81.         read_dat <<= 1;

  82.         if(MISO)
  83.             read_dat++;
  84.         spi_delay(1);
  85.         SCK_H;
  86.     }
  87.     return read_dat;
  88. }
  89. #elif SPI_Mode==3
  90. /* CPOL = 1, CPHA = 1 */
  91. u8 SOFT_SPI_RW_MODE(u8 write_dat)
  92. {
  93.     u8 i, read_dat = 0;
  94.     SCK_H;
  95.     for(i = 0; i < 8; i++)
  96.     {
  97.         SCK_L;
  98.         if(write_dat & 0x80)
  99.             MOSI_H;
  100.         else
  101.             MOSI_L;
  102.         write_dat <<= 1;
  103.         spi_delay(1);
  104.         SCK_H;
  105.         read_dat <<= 1;

  106.         if(MISO)
  107.             read_dat++;
  108.         spi_delay(1);
  109.         _nop_();
  110.     }
  111.     return read_dat;
  112. }
  113. #endif        

  114. //SPI2 读写一个字节
  115. //TxData:要写入的字节
  116. //返回值:读取到的字节
  117. u8 SPI2_ReadWriteByte(u8 TxData)
  118. {
  119.     u8 Rxdata;
  120.           CS_L;
  121.     Rxdata = SOFT_SPI_RW_MODE(TxData);
  122.           CS_H;
  123.     return Rxdata;
  124. }
复制代码






分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

举报

沙发
ID:57657 发表于 2024-7-28 08:36 | 只看该作者
SPI信号有问题的可以用逻辑分析仪检测,寄存器中断配置方法具体见数据手册。
回复

举报

板凳
ID:639106 发表于 2024-7-28 08:42 | 只看该作者
e,把SPI从器件和电路图贴出来看看吧
回复

举报

地板
ID:639106 发表于 2024-7-28 08:43 | 只看该作者
可以先用逻辑分析仪抓下SCLK和MISO的信号
回复

举报

5#
ID:639106 发表于 2024-7-28 09:00 | 只看该作者
还有,要先设置IO口工作模式


  1. #define CS_L                                                         P16=0
  2. #define CS_H                                                         P16=1
  3. #define SCK_L                                                  P15=0
  4. #define SCK_H                                                  P15=1
  5. #define MOSI_L                                                P13=0
  6. #define MOSI_H                                                P13=1
  7. #define MISO              P44
复制代码
有没有可能CS没被拉低
加上这个试试
  1.   P0M0=0x00;
  2.   P1M0=0x00;
  3.   P2M0=0x00;
  4.   P3M0=0x00;
  5.   P4M0=0x00;
  6.   P0M1=0x00;
  7.   P1M1=0x00;
  8.   P2M1=0x00;
  9.   P3M1=0x00;
  10.   P4M1=0x00;
复制代码




回复

举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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