找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1951|回复: 19
收起左侧

简单的单片机ds18b20,但实在调不通程序

[复制链接]
ID:84492 发表于 2019-9-3 21:06 | 显示全部楼层 |阅读模式
各位大佬和努力中朋友,本人制作个数码管时钟,mcu是stc15w408as,之前用的是12T,单独测试时钟,温度都能显示,本来改1T也是轻轻松松的事,但结果耗费我多少个晚上和周末,现在时钟没问题,自动调光也没问题,但温度显示始终是有问题的,现在一直显示-06℃。我也大概知道可能时序问题,但参照很多例程,就是调不好,真是绝望的很。只能求助了。

单片机源程序如下:
ds18b20.c
  1. //===========================================================================
  2. //                包含头文件
  3. //===========================================================================
  4. #include "DS18B20.h"
  5. #include "Delay.h"

  6. //===========================================================================
  7. //                宏定义
  8. //===========================================================================



  9. //===========================================================================
  10. //                函数原型声明
  11. //===========================================================================


  12. //===========================================================================
  13. //                全局变量声明
  14. //===========================================================================
  15. u8 DisplayData[4];
  16. u8 const code smgduan[] = {0x3c};                       // 'c'符号,1100 0110数码管0是亮
  17. u8 const code dis_code_z[] = {                              // 正装共阳数码管
  18.                                                 0xC0,                  // '0'
  19.                                                 0xF9,                  // '1'
  20.                                                 0xA4,                  // '2'
  21.                                                 0xB0,                  // '3'
  22.                                                 0x99,                  // '4'
  23.                                                 0x92,                  // '5'
  24.                                                 0x82,                  // '6'
  25.                                                 0xF8,                  // '7'
  26.                                                 0x80,                  // '8'
  27.                                                 0x90,                  // '9'
  28.                                                 0xFF                   // off
  29.                                                 };                                                      

  30. u8 const code dis_code_d[] = {                            // 倒装共阳数码管
  31.                                                 0xC0,                 // '0'
  32.                                                 0xCF,                 // '1'
  33.                                                 0xA4,                 // '2'
  34.                                                 0x86,                 // '3'
  35.                                                 0x8B,                 // '4'
  36.                                                 0x92,                 // '5'
  37.                                                 0x90,                 // '6'
  38.                                                 0xC7,                 // '7'
  39.                                                 0x80,                 // '8'
  40.                                                 0x82,                 // '9'
  41.                                                 0xFF                  // 'off'
  42.                                                 };                                                               



  43. //===========================================================================
  44. //                外部变量声明
  45. //===========================================================================




  46. /*""FUNC COMMENT""***********************************************************
  47. *----------------------------------------------------------------------------
  48. * 功    能        : 初始化
  49. *----------------------------------------------------------------------------
  50. * 引    数        : 无
  51. *----------------------------------------------------------------------------
  52. * 返 回 值        : 初始化成功返回1,失败返回0
  53. *----------------------------------------------------------------------------
  54. * 注意事项        : 无
  55. *----------------------------------------------------------------------------
  56. *""FUNC COMMENT END""*******************************************************/
  57. bit ds18b20_reset(void)
  58. {
  59.         u8 F_init = 0;        
  60.         
  61.          DQ = 1;                                // 首先将数据线置高
  62.         delay_us(1);                          // 短暂延时 (大约2us)
  63.         DQ = 0;                                // 送出低电平复位信号
  64.         delay_250us();                     // 延时在480~960US之间
  65.         delay_250us();
  66.     delay_250us();
  67.     DQ = 1;                                // 拉高 释放数据线
  68.         delay_70us();                  // 延时等待要求大于60us
  69.         F_init = DQ;                   // DS18B20产生“存在脉冲”                                                                                                                                          
  70.                                         // 检测DQ若低,则复位成功,DS18B20存在
  71.                                       // 若高,则复位失败,DS18B20损坏或不存在
  72.     delay_250us();             // 等待释放数据线,避免影响下一步操作
  73.         delay_250us();
  74.    
  75.         return (F_init);           // 返回复位结果
  76. }

  77. /*""FUNC COMMENT""***********************************************************
  78. *----------------------------------------------------------------------------
  79. * 功    能        : 向18B20写入一个字节
  80. *----------------------------------------------------------------------------
  81. * 引    数        : dat
  82. *----------------------------------------------------------------------------
  83. * 返 回 值        : 无
  84. *----------------------------------------------------------------------------
  85. * 注意事项        : 无
  86. *----------------------------------------------------------------------------
  87. *""FUNC COMMENT END""*******************************************************/
  88. void ds18b20_writeData(u8 byte)
  89. {
  90.         u8 i;
  91.    
  92.         for (i = 0; i < 8; i++)     // 重复直到发送完整个字节
  93.         {
  94.         DQ = 1;
  95.                 delay_us(1);
  96.                 DQ = 0;                      // 数据线首先拉低,开始写
  97.                 delay_us(1);               // 低电平保持1us以上
  98.         DQ = byte & 0x01;             // 送出数据                                 
  99.                 delay_70us();           // 写周期在60us-120us间,等待时间片结束
  100.                 DQ = 1;                  // 释放数据线
  101.                 byte >>= 1;
  102.                 delay_us(1);          // 恢复延时      
  103.         }
  104. }

  105. /*""FUNC COMMENT""***********************************************************
  106. *----------------------------------------------------------------------------
  107. * 功    能        : 读取一个字节
  108. *----------------------------------------------------------------------------
  109. * 引    数        : 无
  110. *----------------------------------------------------------------------------
  111. * 返 回 值        : 读取的数据
  112. *----------------------------------------------------------------------------
  113. * 注意事项        : 无
  114. *----------------------------------------------------------------------------
  115. *""FUNC COMMENT END""*******************************************************/
  116. u8 ds18b20_readData(void)
  117. {
  118.         u8 i;
  119.     u8 byte = 0;
  120.         
  121.         for (i = 0; i < 8; i++)           // 重复接收直到读完整个字节
  122.         {
  123.         
  124.         DQ = 0;                         // 开始时间片,开始一个读过程
  125.                 delay_us(1);         // 保持1us以上
  126.         DQ = 1;                     // 准备接收,开始读取数据线状态        
  127.                 delay_us(1);      // 读时间片开始后15us内主机对数据线进行采集
  128.                 byte >>= 1;
  129.                 if(DQ)
  130.                 {
  131.                         byte |= 0x80;  // 读取数据        
  132.                 }
  133.                 delay_70us();            // 等待时间片结束,读周期60us-120us间
  134.         }
  135.         return (byte);
  136. }

  137. /* void ds1820_setResolution(u8 res)//设置分辨率 默认12wei
  138. {
  139.     while (ds18b20_reset());
  140.     ds18b20_writeByte(0x4E);
  141.     ds18b20_writeByte(0xFF);
  142.     ds18b20_writeByte(0xFF);
  143.     ds18b20_writeByte(0x1F | (res << 5));   //设置分辨率(0 R1 R0 1  1111)   
  144. } */

  145. /*""FUNC COMMENT""***********************************************************
  146. *----------------------------------------------------------------------------
  147. * 功    能        : 读温度
  148. *----------------------------------------------------------------------------
  149. * 引    数        : 无
  150. *----------------------------------------------------------------------------
  151. * 返 回 值        : 读取的温度数据
  152. *----------------------------------------------------------------------------
  153. * 注意事项        : 无
  154. *----------------------------------------------------------------------------
  155. *""FUNC COMMENT END""*******************************************************/
  156. u16 ds18b20_readTemperature(void)
  157. {
  158.         u8 TPL, TPH;

  159.        u16 temp;//@001
  160.         ds18b20_reset();
  161.         ds18b20_writeData(0xCC);                                
  162.         ds18b20_writeData(0x44);                                                     
  163.                                                               
  164.         while(!DQ);                                    
  165.                                                                                                                
  166.         ds18b20_reset();                                 
  167.         ds18b20_writeData(0xCC);  
  168.         ds18b20_writeData(0xBE);  
  169.                
  170.         TPL = ds18b20_readData();   
  171.         TPH = ds18b20_readData();  
  172.         
  173.          temp = TPH;
  174.        temp <<= 8;                                                                                    
  175.         temp |= TPL;                              
  176.    
  177.         return (temp);  
  178. }

  179. /*""FUNC COMMENT""***********************************************************
  180. *----------------------------------------------------------------------------
  181. * 功    能        : 获取温度数据并处理
  182. *----------------------------------------------------------------------------
  183. * 引    数        : temp
  184. *----------------------------------------------------------------------------
  185. * 返 回 值        : 无
  186. *----------------------------------------------------------------------------
  187. * 注意事项        : 无
  188. *----------------------------------------------------------------------------
  189. *""FUNC COMMENT END""*******************************************************/
  190. void ds18b20_dataProcess(u16 temp) //@@1
  191. {
  192.         float tp;
  193. //        if (temp < 0)                                                                              
  194.         if ((temp & 0xF800) != 0)
  195.         {
  196.                 DisplayData[3] = 0xBF; // '-'

  197.                 //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  198.                 temp = temp - 1;
  199.                 temp = ~temp;
  200.                 tp = temp;
  201.                 temp = tp*0.0625*100 + 0.5;
  202.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  203.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  204.                 //算加上0.5,还是在小数点后面。
  205.                 DisplayData[2] = dis_code_z[temp / 10];        // 十位
  206.                 DisplayData[1] = dis_code_d[temp % 10];      // 个位
  207.                 DisplayData[0] = smgduan[0];                       // 显示C符号
  208.         }
  209.         else
  210.         {
  211.                 //DisplayData[0] = 0x00;
  212.                 tp = temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  213.                 //如果温度是正的那么,那么正数的原码就是补码它本身
  214.                 temp = tp*0.0625*100 + 0.5;
  215.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  216.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  217.                 //算加上0.5,还是在小数点后面。
  218.                 if (( temp / 100 ) == 0)
  219.                 {
  220.                         DisplayData[3] = 0xFF;
  221.                 }
  222.                 else
  223.                 {
  224.                         DisplayData[3] = dis_code_z[temp / 100];        // 千位
  225.                         DisplayData[2] = dis_code_z[temp % 100 / 10] & 0x7F;// 十位
  226.                         DisplayData[1] = dis_code_d[temp % 10];      // 个位
  227.                         DisplayData[0] = smgduan[0];                       // 显示C符号        
  228.                 }
  229.         }        
  230. }

复制代码
还有个很莫名的问题也废了很多时间就是定时中断,参照着datasheet改1T,但若不加/12就不是1ms中断。。后来发现后加上能输出1ms。
        #define T1MS    (65536 - FOSC/1000/12)  
Snipaste_2019-09-03_21-00-53.png
回复

使用道具 举报

ID:84492 发表于 2019-9-3 21:09 | 显示全部楼层
期间用到的1us,实测在4us;70us,250us大概差不多
Snipaste_2019-09-03_21-09-25.png
回复

使用道具 举报

ID:84492 发表于 2019-9-4 09:36 | 显示全部楼层
这是上面说的1ms定时,中断配置
Snipaste_2019-09-04_09-32-01.png
回复

使用道具 举报

ID:84492 发表于 2019-9-4 20:56 | 显示全部楼层
温度一直一个数值,难道是转换部分有问题?
回复

使用道具 举报

ID:84492 发表于 2019-9-4 22:03 | 显示全部楼层
防尘            
回复

使用道具 举报

ID:351097 发表于 2019-9-5 09:28 | 显示全部楼层
用逻辑分析仪器看一下单片机和DS18B20的通信过程,看看DS18B20能否正常回应数据。DS18B20对时序要求很严格的。
回复

使用道具 举报

ID:275826 发表于 2019-9-5 09:53 | 显示全部楼层
DS18B20对时序要求比较严格,估计是时序问题
回复

使用道具 举报

ID:101339 发表于 2019-9-5 12:51 | 显示全部楼层
DS18B20对时序要求比较严格,估计是时序问题
回复

使用道具 举报

ID:212177 发表于 2019-9-5 17:17 来自手机 | 显示全部楼层
你先把单片机其他功能都去掉单独调好1820再放到一起
回复

使用道具 举报

ID:84492 发表于 2019-9-5 20:07 | 显示全部楼层
l6931639 发表于 2019-9-5 17:17
你先把单片机其他功能都去掉单独调好1820再放到一起

我之前用12T时也只调试温度,可以显示但温度比实际低个10度左右,现在正和时钟就改1T,但真是崩溃
回复

使用道具 举报

ID:84492 发表于 2019-9-5 20:10 | 显示全部楼层
没有你 发表于 2019-9-5 09:28
用逻辑分析仪器看一下单片机和DS18B20的通信过程,看看DS18B20能否正常回应数据。DS18B20对时序要求很严格 ...

水平也不行,所以调试这个真是太费时间了,你的建议我会试试但估计看不懂
回复

使用道具 举报

ID:607642 发表于 2019-9-5 20:37 | 显示全部楼层
这东西 很扣时序。在读这个时 中断都最好关掉
回复

使用道具 举报

ID:213173 发表于 2019-9-6 09:02 | 显示全部楼层
楼主调不成功主要还是时序问题,给你一个1T单片机的示例程序,是在郭天祥的12T程序基础上改的,经过实物验证无误。
  1. //DS18b20测温程序
  2. #include <STC15F2K60S2.H>
  3. #include <intrins.h>
  4. //#include <reg51.H>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. //通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值
  8. sbit wela = P2^7;  //数码管位选
  9. sbit dula = P2^6;  //数码管段选
  10. sbit ds = P2^2;        //单总线通讯端口
  11. //0-F数码管的编码(共阴极)
  12. uchar code table[]={
  13.                 0x3f,0x06,0x5b,0x4f,
  14.                 0x66,0x6d,0x7d,0x07,
  15.                 0x7f,0x6f,0x77,0x7c,
  16.                 0x39,0x5e,0x79,0x71};
  17. //0-9数码管的编码(共阴极), 带小数点
  18. uchar code tableWidthDot[]={
  19.                 0xbf, 0x86, 0xdb, 0xcf,
  20.                 0xe6, 0xed, 0xfd,
  21.                 0x87, 0xff, 0xef};
  22. //1ms延时函数
  23. void delay()        //@11.0592MHz
  24. {
  25.         unsigned char i, j;
  26.         _nop_();
  27.         _nop_();
  28.         _nop_();
  29.         i = 11;
  30.         j = 190;
  31.         do
  32.         {
  33.                 while (--j);
  34.         } while (--i);
  35. }

  36. void Delay824us()                //@11.0592MHz
  37. {
  38.         unsigned char i, j;

  39.         _nop_();
  40.         i = 9;
  41.         j = 218;
  42.         do
  43.         {
  44.                 while (--j);
  45.         } while (--i);
  46. }
  47. void Delay34us()                //@11.0592MHz
  48. {
  49.         unsigned char i;

  50.         _nop_();
  51.         _nop_();
  52.         i = 91;
  53.         while (--i);
  54. }
  55. void Delay3us()                //@11.0592MHz
  56. {
  57.         unsigned char i;

  58.         _nop_();
  59.         _nop_();
  60.         _nop_();
  61.         i = 5;
  62.         while (--i);
  63. }

  64. //初始化DS18B20
  65. //让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
  66. void dsInit()
  67. {
  68. //一定要使用unsigned int型, 一个i--指令的时间, 作为与DS18B20通信的小时间间隔
  69. //以下都是一样使用unsigned int型
  70. //        uint i;   
  71.         ds = 0;  
  72. //        i = 103;  
  73. //        while(i>0) //824us
  74. //                i--;  
  75.         Delay824us();
  76.         ds = 1;  
  77.         Delay34us();
  78. //        i = 4;      
  79. //        while(i>0) //34us
  80. //                i--;  
  81. }
  82. //向DS18B20读取一位数据   
  83. //读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,   
  84. //之后DS18B20则会输出持续一段时间的一位数据  
  85. bit readBit()  
  86. {   
  87. //        uint i;  
  88.         bit b;  
  89.         ds = 0;  
  90.         Delay3us();
  91. //        i++;   
  92.         ds = 1;   
  93.         Delay3us();
  94.         Delay3us();
  95. //        i++;
  96. //        i++;  
  97.         b = ds;  
  98.         Delay34us();
  99.         Delay34us();
  100. //        i = 8;     
  101. //        while(i>0)
  102. //                i--;  
  103.         return b;  
  104. }

  105. //读取一字节数据, 通过调用readBit()来实现
  106. uchar readByte()  
  107. {
  108.         uint i;  
  109.         uchar j, dat;  
  110.         dat = 0;   
  111.         for(i=0; i<8; i++)  
  112.         {
  113.                 j = readBit();   
  114. //最先读出的是最低位数据  
  115.                 dat = (j << 7) | (dat >> 1);  
  116.         }   
  117.         return dat;  
  118. }  
  119. //向DS18B20写入一字节数据
  120. void writeByte(uchar dat)  
  121. {
  122. //        uint i;  
  123.         uchar j;  
  124.         bit b;   
  125.         for(j = 0; j < 8; j++)  
  126.         {   
  127.                 b = dat & 0x01;  
  128.                 dat >>= 1;   
  129. //写"1", 让低电平持续2个小延时, 高电平持续8个小延时  
  130.                 if(b)
  131.                 {   
  132.                         ds = 0;  
  133.                         Delay3us();
  134.                         Delay3us();
  135. //                        i++;// 3us
  136. //                        i++;  
  137.                         ds = 1; //1us  
  138.                         Delay34us();
  139.                         Delay34us();
  140. //                        i = 8;   //2us   
  141. //                        while(i>0) //66us
  142. //                                i--;
  143.                 }
  144.                 else  //写"0", 让低电平持续8个小延时, 高电平持续2个小延时  
  145.                 {
  146.                         ds = 0;   
  147.                         Delay34us();
  148.                         Delay34us();
  149. //                        i = 8;   
  150. //                        while(i>0)
  151. //                                i--;  
  152.                         ds = 1;  
  153.                         Delay3us();
  154.                         Delay3us();
  155. //                        i++;
  156. //                        i++;  
  157.                 }  
  158.         }  
  159. }
  160. //向DS18B20发送温度转换命令  
  161. void sendChangeCmd()
  162. {  
  163.         dsInit();    //初始化DS18B20
  164.         delay();    //延时1ms  
  165.         writeByte(0xcc); //写入跳过序列号命令字
  166.         writeByte(0x44); //写入温度转换命令字
  167. }
  168. //向DS18B20发送读取数据命令
  169. void sendReadCmd()
  170. {  
  171.         dsInit();     //初始化DS18B20
  172.         delay();      //延时1ms  
  173.         writeByte(0xcc); //写入跳过序列号命令字
  174.         writeByte(0xbe); //写入读取数据令字
  175. }
  176. //获取当前温度值
  177. uint getTmpValue()
  178. {  
  179.         uint value; //存放温度数值
  180.         float t;  
  181.         uchar low, high;
  182.         sendReadCmd();
  183. //连续读取两个字节数据
  184.         low = readByte();  
  185.         high = readByte();  
  186. //将高低两个字节合成一个整形变量
  187.         value = high;
  188.         value <<= 8;
  189.         value |= low;  
  190. //DS18B20的精确度为0.0625度, 即读回数据的最低位代表0.0625度
  191.         t = value * 0.0625;  
  192. //将它放大10倍, 使显示时可显示小数点后一位, 并对小数点后第二2进行4舍5入
  193. //如t=11.0625, 进行计数后, 得到value = 111, 即11.1 度
  194.         value = t * 10 + 0.5;   
  195.         return value;
  196. }
  197. //显示当前温度值, 精确到小数点后一位
  198. void display(uint v)  
  199. {  
  200.         uchar count;
  201.         uchar datas[] = {0, 0, 0};  
  202.         datas[0] = v / 100;
  203.         datas[1] = v % 100 / 10;
  204.         datas[2] = v % 10;  
  205.         for(count = 0; count < 3; count++)
  206.         {  //片选         
  207.                 wela = 0;   
  208.                 P0 = ((0xfe << count) | (0xfe >> (8 - count))); //选择第(count + 1) 个数码管  
  209.                 wela = 1; //打开锁存, 给它一个下降沿量
  210.                 wela = 0;
  211.                 //段选
  212.                 dula = 0;
  213.                 if(count != 1)
  214.                 {  
  215.                         P0 = table[datas[count]];  //显示数字
  216.                 }
  217.                 else
  218.                 {
  219.                         P0 = tableWidthDot[datas[count]]; //显示带小数点数字
  220.                 }  
  221.                 dula = 1;  //打开锁存, 给它一个下降沿量
  222.                 dula = 0;  
  223.                 delay(); //延时1ms, 即亮1ms
  224. //清除段先, 让数码管灭, 去除对下一位的影响, 去掉高位对低位重影
  225. //若想知道影响效果如何, 可自行去掉此段代码
  226. //因为数码管是共阴极的, 所有灭的代码为: 00H
  227.                 dula = 0;  
  228.                 P0 = 0x00;  //显示数字  
  229.                 dula = 1; //打开锁存, 给它一个下降沿量
  230.                 dula = 0;
  231.         }
  232. }
  233. void main()
  234. {  
  235.         uchar i;
  236.         uint value;
  237.         while(1)
  238.         {  //启动温度转换
  239.                 sendChangeCmd();
  240.                 value = getTmpValue();
  241.                 //显示3次  
  242.                 for(i = 0; i < 3; i++)
  243.                 {  
  244.                         display(value);
  245.                 }
  246.         }
  247. }
复制代码
回复

使用道具 举报

ID:84492 发表于 2019-9-9 17:06 | 显示全部楼层
fox_hk 发表于 2019-9-5 20:37
这东西 很扣时序。在读这个时 中断都最好关掉

你是正确的,后来我在电源网上看到说中断会影响,关闭之后就可以正常显示温度了。这个问题真是耗费了我很多精力和时间,要是能早点看到你的回复就好了,也多谢回复!
回复

使用道具 举报

ID:84492 发表于 2019-9-9 17:07 | 显示全部楼层
wulin 发表于 2019-9-6 09:02
楼主调不成功主要还是时序问题,给你一个1T单片机的示例程序,是在郭天祥的12T程序基础上改的,经过实物验 ...

确实是时序问题,是中断引起的。多谢!
回复

使用道具 举报

ID:84492 发表于 2019-9-9 17:10 | 显示全部楼层
谢谢各位的帮助,已经实现了。也谢谢51hei这个平台一直能有网友帮助和学习机会。
回复

使用道具 举报

ID:212177 发表于 2019-9-9 18:23 来自手机 | 显示全部楼层
join22life 发表于 2019-9-5 20:07
我之前用12T时也只调试温度,可以显示但温度比实际低个10度左右,现在正和时钟就改1T,但真是崩溃

我解决1820的办法是使用定时器中断做定时120us把程序写在中断里,使用非阻塞程序设计。
回复

使用道具 举报

ID:212177 发表于 2019-9-9 18:25 来自手机 | 显示全部楼层
使用定时器中断非阻塞程序设计就可以随便移植,基本不用每次重新调试。
回复

使用道具 举报

ID:84492 发表于 2019-9-27 16:49 | 显示全部楼层
l6931639 发表于 2019-9-9 18:25
使用定时器中断非阻塞程序设计就可以随便移植,基本不用每次重新调试。

你好,你的意思是把计时相关的放中断去处理吗?之前我也是想过,但实际操作发现程序写起来不顺手。。。比如:1820需要延迟120us,中断10us一次,那么在中断中只做减减,当12次中断后时间为零,这时在其他函数做判断处理,当时间为0则进行之后程序并重新时间赋值,这样延迟做到了,也没有傻傻的delay。对吗?
回复

使用道具 举报

ID:246783 发表于 2020-3-20 21:48 来自手机 | 显示全部楼层
访问DS18时关断全局中断,读完再开即可
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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