搜索
bottom↓
回复: 4

WIZwiki-W7500学习(2)使用SPI读取DS18B20

[复制链接]

出0入89汤圆

发表于 2015-8-16 20:32:29 | 显示全部楼层 |阅读模式
距离第一次测试,已经很久了,这次带来的是使用SPI读取DS18B20的温度
我们知道ds18b20需要很严格的时序,一般用纯软件的做法,当然效果不是很好,也有用串口的。我支持利用SPI,好处是,读取时不需要关中断。7500带有两个SPI口,支持DMA,FIFO。
因为这个芯片的DMA我不是很熟悉,所以就用了FIFO,为了保证连续发送,所以这个实现需要一个250us秒的定时器,当然,如果你循环周期永远不会大于380,那么在主循环中调用就可以。
直接上代码吧,写起来发现很费劲。
  1. #include "spidrv.h"
  2. #include "W7500x.h"
  3.     /* < SSP_StructInit default values
  4.        SSP_InitStructure.SSP_SerialClockRate   = 0x00;
  5.        SSP_InitStructure.SSP_FrameFormat       = SSP_FrameFormat_MO;
  6.        SSP_InitStructure.SSP_CPHA              = SSP_CPHA_1Edge;   
  7.        SSP_InitStructure.SSP_CPOL              = SSP_CPOL_Low;
  8.        SSP_InitStructure.SSP_DataSize          = SSP_DataSize_8b;
  9.        SSP_InitStructure.SSP_SOD               = SSP_SOD_RESET;
  10.        SSP_InitStructure.SSP_Mode              = SSP_Mode_Master;
  11.        SSP_InitStructure.SSP_NSS               = SSP_NSS_Hard;
  12.        SSP_InitStructure.SSP_LBM               = SSP_LBM_RESET;
  13.        SSP_InitStructure.SSP_SSE               = SSP_SSE_SET;
  14.        SSP_InitStructure.SSP_BaudRatePrescaler = SSP_BaudRatePrescaler_2;
  15.     */
  16. static u32t _fsm = 0;
  17. static struct timer _timer;

  18. static SSP_InitTypeDef SSP1_InitStructure;
  19. void spi_init(void) {
  20.     _fsm = 0;
  21.     /* SSP0 Init -- SSP Master */
  22.     //SSP_StructInit(&SSP0_InitStructure);
  23.     //SSP0_InitStructure.SSP_FrameFormat  = SSP_FrameFormat_MO; // Motorora SPI mode
  24.     //SSP0_InitStructure.SSP_DataSize = SSP_DataSize_16b;
  25.     //SSP_Init(SSP0,&SSP0_InitStructure);

  26.     /* SSP1 Init -- SSP Slave */
  27.     SSP_StructInit(&SSP1_InitStructure);
  28.     SSP1_InitStructure.SSP_DataSize          = SSP_DataSize_16b;
  29.     SSP1_InitStructure.SSP_BaudRatePrescaler = SSP_BaudRatePrescaler_254;// SSP_BaudRatePrescaler_254;
  30.     SSP1_InitStructure.SSP_Mode              = SSP_Mode_Master;
  31.     SSP1_InitStructure.SSP_CPOL              = SSP_CPOL_Low;//SSP_CPOL_High;
  32.    
  33.     SSP1_InitStructure.SSP_FrameFormat       = SSP_FrameFormat_MO;
  34.     SSP1_InitStructure.SSP_CPHA              = SSP_CPHA_2Edge;  
  35.    
  36.     SSP_Init(SSP0,&SSP1_InitStructure);
  37.     //SSP0->DMACR= 0x03;
  38.     //bsp_set_spi1_speed(SPI_SPEED_256);

  39.     //*(u32t *)(0x41003020) = 0x32;
  40.    

  41.     *(u32t *)(0x4100301c) = 0x32;

  42. }
  43. #define ff1  0xffff
  44. #define ff2  ff1, ff1
  45. #define ff3  ff1, ff2
  46. #define ff4  ff1, ff3
  47. #define ff5  ff1, ff4
  48. #define ff6  ff1, ff5
  49. #define ff7  ff1, ff6
  50. #define ff8  ff1, ff7
  51. #define ff9  ff1, ff8
  52. #define ff10  ff1, ff9

  53. #define zz1  0x0
  54. #define zz2  zz1, zz1
  55. #define zz3  zz1, zz2
  56. #define zz4  zz1, zz3
  57. #define zz5  zz1, zz4
  58. #define zz6  zz1, zz5
  59. #define zz7  zz1, zz6
  60. #define zz8  zz1, zz7
  61. #define zz9  zz1, zz8
  62. #define zz10  zz1, zz9
  63. #define zz11  zz1, zz10
  64. //3.5us   
  65. //16 ->56
  66. //rst 500us  -> 9个0x0000;
  67. //rst wait 15-60us ->2个0xffff
  68. //rst read 0xffff  read value
  69. // 9个0xffff;
  70. //, 0xffff
  71. //, 0xffff
  72. #define WRITE1  0x7fff, 0xffff
  73. #define WRITE0  0x0000, 0xffff

  74. //write 1
  75. //0x1fff, 0xffff
  76. //write 0
  77. //0x0000, 0x0fff
  78. //, 0xffff, 0xffff
  79. #define RD1    0x7fff, 0xffff
  80. #define RD2    RD1, RD1
  81. #define RD3    RD1, RD2
  82. #define RD4    RD1, RD3
  83. #define RD5    RD1, RD4
  84. #define RD6    RD1, RD5
  85. #define RD7    RD1, RD6
  86. #define RD8    RD1, RD7

  87. //read 0x7fff, 0xffff
  88. //0x2000 & ,如果== 0,

  89. //16
  90. //CC

  91. #define SKIPADDR WRITE0, WRITE0, WRITE1, WRITE1, WRITE0, WRITE0, WRITE1, WRITE1
  92. //44
  93. #define CONVERT  WRITE0, WRITE0, WRITE1, WRITE0, WRITE0, WRITE0, WRITE1, WRITE0
  94. //BE 1011 1110
  95. #define RCMD     WRITE0, WRITE1, WRITE1, WRITE1, WRITE1, WRITE1, WRITE0, WRITE1
  96. /*
  97. #define SKIPADDR WRITE1, WRITE1, WRITE0, WRITE0, WRITE1, WRITE1, WRITE0, WRITE0
  98. //44
  99. #define CONVERT  WRITE0, WRITE1, WRITE0, WRITE0, WRITE0, WRITE1, WRITE0, WRITE0
  100. //BE 1011 1110
  101. #define RCMD     WRITE1, WRITE0, WRITE1, WRITE1, WRITE1, WRITE1, WRITE1, WRITE0
  102. */
  103. #define BUFLENGTH (36 + 88 + 5 + 88)

  104. #define DSDATA1_LENGTH    (27 + 16 * 2)
  105. #define DSDATA2_LENGTH    (27 + 16 * 2 + 16 * 9)

  106. const u16t dsdata1[DSDATA1_LENGTH] = { ff7, zz11, ff9, SKIPADDR, CONVERT  };
  107. const u16t dsdata2[DSDATA2_LENGTH] = { ff7, zz11, ff9, SKIPADDR, RCMD, RD8, RD8, RD8, RD8,  RD8,  RD8, RD8,  RD8,  RD8};

  108. #define MAXBUFLENGTH  (DSDATA1_LENGTH + DSDATA2_LENGTH + DSDATA3_LENGTH + DSDATA4_LENGTH)
  109. #define DATA_OFFSET    (DSDATA1_LENGTH + DSDATA2_LENGTH)  
  110. static u8t _rbuf[10];
  111. static s32t index, rindex;


  112. //CRC = X8 + X5 + X4 + 1
  113. const u8t Crc8Table [256]={
  114. 0,  94, 188,  226,  97,  63,  221,  131,  194,  156,  126,  32,  163,  253,  31,  65,
  115. 157,  195,  33,  127,  252,  162,  64,  30,  95,  1,  227,  189,  62,  96,  130,  220,
  116. 35,  125,  159,  193,  66,  28,  254,  160,  225,  191,  93,  3,  128,  222,  60,  98,
  117. 190,  224,  2,  92,  223,  129,  99,  61,  124,  34,  192,  158,  29,  67,  161,  255,
  118. 70,  24,  250,  164,  39,  121,  155,  197,  132,  218,  56,  102,  229,  187,  89,  7,
  119. 219,  133, 103,  57,  186,  228,  6,  88,  25,  71,  165,  251,  120,  38,  196,  154,
  120. 101,  59, 217,  135,  4,  90,  184,  230,  167,  249,  27,  69,  198,  152,  122,  36,
  121. 248,  166, 68,  26,  153,  199,  37,  123,  58,  100,  134,  216,  91,  5,  231,  185,
  122. 140,  210, 48,  110,  237,  179,  81,  15,  78,  16,  242,  172,  47,  113,  147,  205,
  123. 17,  79,  173,  243,  112,  46,  204,  146,  211,  141,  111,  49,  178,  236,  14,  80,
  124. 175,  241, 19,  77,  206,  144,  114,  44,  109,  51,  209,  143,  12,  82,  176,  238,
  125. 50,  108,  142,  208,  83,  13,  239,  177,  240,  174,  76,  18,  145,  207,  45,  115,
  126. 202,  148, 118,  40,  171,  245,  23,  73,  8,  86,  180,  234,  105,  55,  213, 139,
  127. 87,  9,  235,  181,  54,  104,  138,  212,  149,  203,  41,  119,  244,  170,  72,  22,
  128. 233,  183,  85,  11,  136,  214,  52,  106,  43,  117,  151,  201,  74,  20,  246,  168,
  129. 116,  42,  200,  150,  21,  75,  169,  247,  182,  232,  10,  84,  215,  137,  107,  53};

  130. u8t GetCRC(u8t *str, u32t length) {
  131.     u8t crc_data=0;
  132.     u32t i;
  133.     for(i=0;i<length;i++) {  //查表校验
  134.         crc_data = Crc8Table[crc_data^str[i]];
  135.     }
  136.     return (crc_data);
  137. }

  138. void spi_recive(void) {
  139.     s32t t, r, i;
  140.     while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RNE) == SET) {
  141.         t = (u16t)SSP_ReceiveData(SSP0);
  142.         if ((rindex >= 0) && ((rindex & 0x01) == 0)) {
  143.             t &= 0x0f00;
  144.             i = rindex / 16;
  145.             r = _rbuf[i];
  146.             r >>= 1;
  147.             r &= 0x7f;
  148.             if (t == 0x0f00) {
  149.                 r |= 0x80;
  150.             }
  151.             _rbuf[i] = r;
  152.         }
  153.         rindex++;
  154.     }
  155. }
  156. s32t wd;
  157. void spi_process(void) {
  158.     u8t temp;
  159.     u8t TL,TH;
  160.     s32t tem;

  161.     TL = _rbuf[0]; // LSB   
  162.     TH = _rbuf[1]; // MSB   
  163.       
  164.     if(TH>7) {
  165.         TH=~TH;
  166.         TL=~TL;
  167.         temp=0;//温度为负  
  168.     }
  169.     else {
  170.         temp=1;//温度为正         
  171.     }
  172.     tem=TH<<8 | TL; //获得不带符号位的11位温度值
  173.     //转换 *0.625
  174.     tem = tem*10000;
  175.     tem = tem>>4;
  176.     if(temp) {
  177.         wd = tem;
  178.     }
  179.     else{
  180.         wd = -tem;
  181.     }
  182. }

  183. s32t spi_temperature(void){
  184.     return wd;
  185. }
  186. #define FSM_INIT             0
  187. #define FSM_READY            1
  188. #define FSM_WAITFREE         2
  189. #define FSM_SEND_DATA1       3
  190. #define FSM_WAIT_DATA1_OK    4
  191. #define FSM_SEND_DATA2       5
  192. #define FSM_WAIT_DATA2_OK    6
  193. #define FSM_WAIT_CONVERT     7

  194. void spi_timerpoll(void) {
  195.     if (_fsm == FSM_SEND_DATA1) {
  196.         while((SSP_GetFlagStatus(SSP0, SSP_FLAG_TNF) == SET) && index < DSDATA1_LENGTH) {
  197.             SSP_SendData(SSP0, dsdata1[index++]);
  198.         }
  199.         if(index >= (DSDATA1_LENGTH)) {
  200.             timer_init(&_timer);
  201.             _fsm = FSM_WAIT_DATA1_OK;
  202.         }
  203.     }
  204.     else if (_fsm == FSM_SEND_DATA2) {
  205.         spi_recive();
  206.         while((SSP_GetFlagStatus(SSP0, SSP_FLAG_TNF) == SET) && index < DSDATA2_LENGTH) {
  207.             SSP_SendData(SSP0, dsdata2[index++]);
  208.         }
  209.         spi_recive();
  210.         if(index >= DSDATA2_LENGTH) {
  211.             _fsm = FSM_WAIT_DATA2_OK;
  212.         }
  213.     }
  214. }
  215. void spi_service(void) {
  216.     u32t temp_interrupt;

  217.     temp_interrupt = (NVIC->ISPR[0]);
  218.     (NVIC->ISPR[0]) = (u32t)0xFFFFFFFF;

  219.     if ((_fsm == FSM_SEND_DATA1) || (_fsm == FSM_SEND_DATA2)) {
  220.         (NVIC->ISPR[0]) = temp_interrupt;
  221.         return;
  222.     }

  223.     (NVIC->ISPR[0]) = temp_interrupt;
  224.     //CTX_EXIT();

  225.     if (_fsm == FSM_READY) {
  226.         if (timer_expired(&_timer, 9000)) {
  227.             while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RNE) == SET) {
  228.                 SSP_ReceiveData(SSP0);
  229.             }
  230.             printf("\r\nGetting Started\r\n");
  231.             index = 0;
  232.             _fsm = FSM_SEND_DATA1;
  233.         }
  234.     }
  235.     else if(_fsm == FSM_WAIT_DATA1_OK) {
  236.         if (timer_expired(&_timer, 1000)) {
  237.             while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RNE) == SET) {
  238.                 SSP_ReceiveData(SSP0);
  239.             }
  240.             index = 0;
  241.             rindex = 16 * 9 - DSDATA2_LENGTH;
  242.             _fsm = FSM_SEND_DATA2;
  243.         }
  244.     }
  245.     else if(_fsm == FSM_WAIT_DATA2_OK) {
  246.         spi_recive();
  247.         if (SSP_GetFlagStatus(SSP0, SSP_FLAG_BSY)) {
  248.             return;
  249.         }
  250.         spi_recive();
  251.         /*
  252.         t = _rbuf[0];
  253.         t <<= 4;
  254.         printf("SET __%d__%d\r\n", index, rindex);
  255.         rindex /= 16;
  256.         for(i = 0; i < rindex; i++){
  257.             printf("%04X ", _rbuf[i]);
  258.         }
  259.         printf("\r\nSET END \r\n");*/
  260.         if (GetCRC(_rbuf, 8) == _rbuf[8]) {
  261.             spi_process();
  262.             printf("Measuring success:%03d.%04d\r\n", wd / 10000, wd %10000);
  263.             //printf("\r\nwd crc ok {%08d} \r\n", wd);
  264.         }
  265.         else {
  266.             printf("Measurement fails\r\n");
  267.         }
  268.         _fsm = FSM_INIT;
  269.     }
  270.     else {
  271.         timer_init(&_timer);
  272.         _fsm = FSM_READY;
  273.     }
  274. }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入89汤圆

 楼主| 发表于 2015-8-16 20:34:32 | 显示全部楼层
其中spi_timerpoll必须保证在380us内调用一次(我测试时放在一个250us的定时器里调用),spi_service放在主循环中调用

出0入0汤圆

发表于 2015-8-20 10:45:36 来自手机 | 显示全部楼层
W7500可以买到了?

出0入89汤圆

 楼主| 发表于 2015-8-20 10:57:18 | 显示全部楼层
liudan 发表于 2015-8-20 10:45
W7500可以买到了?

上次问了下,说可能比stm32f107便宜一点点

出0入89汤圆

 楼主| 发表于 2015-8-20 10:57:51 | 显示全部楼层
liudan 发表于 2015-8-20 10:45
W7500可以买到了?

我这个是在评估板上进行的测试
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 05:38

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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