搜索
bottom↓
回复: 19

帮忙调试一下 M128外挂16MHz晶振的DS18B20程序……郁闷两个晚上没调出

[复制链接]

出0入0汤圆

发表于 2009-3-27 14:31:51 | 显示全部楼层 |阅读模式
//软件平台:AVR Studio 4
//硬件:Atmega128 +  DS18B20   +  LCD1602
//系统时钟:外部16MHz晶体振荡器
//使用资源:
//                 PA--------LCD1602    //DB0-DB7
//                 PG0-------RS
//                 PG1-------RW
//                 PG2-------EN

//                 PF0---------DS18B20

//程序
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//#include <util/delay.h>
#include "1602.h"

/*------宏定义------*/
#define uchar        unsigned char
#define uint        unsigned int
#define BIT(x)        (1<<(x))
#define NOP()        asm("nop")
#define WDR()         asm("wdr")

#define dat      1               //PF0


//Atmega128   PF0(PIN61)(ADC0)   
#define    CLR_18B20    PORTF&=~BIT(dat)    //数据线强制拉低
#define    SET_18B20    PORTF|=BIT(dat)     //数据线强制拉高
#define    OUT_18B20    DDRF|=BIT(dat)      //主机控制,信号线为输出"1"
#define    IN_18B20     DDRF&=~BIT(dat)     //释放总线,信号线为输入"0"
#define    STU_18B20    PINF&BIT(dat)       //查询总线状态


uchar temp_num[]={"Temperature:"};
//uchar temp_data[2]={0x00,0x00};              //读出温度暂放
float temperature;         //显示温度值


//定时器T0初始化
//T0 的64分频  最大定时周期1024us   单步间隔4us
void timer0_init(void)
{
        TCCR0  = 0x00;//停止定时器
//        TCNT0  = 0x00;//初始值
//        OCR0   = 0xFF;//匹配值
//        TIMSK |= 0x00;//中断允许
//        TCCR0  = 0x03;//启动定时器
}


//端口初始化
void port_init(void)
{
        DDRA=0xff;
        PORTA=0x00;
        DDRG=0xff;
        PORTG=0xff;
        DDRF=0xff;
        PORTF=0x00;
}

void init_devices(void)
{
        cli(); //禁止所有中断
        MCUCR  = 0x00;   //MCU控制寄存器
        MCUCSR = 0x80;//禁止JTAG  //MCU控制和状态寄存器
//        GICR   = 0x00;
        port_init();
        timer0_init();
//        sei();//开全局中断
}


//使用定时器精确定时
void delay_time(uchar time)
{
     TCNT0  = time;//初始值
         TCCR0  = 0x03;//启动定时器
         while((TIFR&(1<<TOV0))==0);  //查询标志位
//     while ((TIFR&0x01));
     TIFR|=(1<<TOV0);   //软件清零标志位
//     TIFR |= 0x01;
     TCCR0  = 0x00;//停止定时器
}


//Initialization the DS18B20
void init_18B20(void)
{
      OUT_18B20;       //设置为输出
          SET_18B20;       //上拉电阻使能
          CLR_18B20;       //强制拉低,并等待480~960us;

          delay_time(0x6A);

          SET_18B20;       //释放总线
          IN_18B20;        //等待18B20响应

          delay_time(0xF1);  //等待15-60us,60us内18B20会将总线拉低

          while(~STU_18B20);      //总线被18B20拉低表示存在

          OUT_18B20;
          SET_18B20;
}


//Write one byte to DS18B20
void write_byte_18B20(uchar val)
{
       uchar j;
           uchar y;
           for(j=0;j<8;j++)
           {
                y=val>>j;      //先写低位
                        y&=0x01;       //查询要写入的位是“0”或者“1”
                        if(y)          //如果要写入的是“1”
                    {
                          NOP();
                                  NOP();
                                  NOP();
                                  SET_18B20;                //写入“1”                  
                    }
                    else  CLR_18B20;                //强制拉低,产生写间隙,写“0”时保持即可
             //输出一位之后,维持时间大于60us,小于120us
                         delay_time(0xF1);
                         SET_18B20;                        //DATA=1,上拉  
                         delay_time(0xFD);         
            }
                SET_18B20;   //8位写完成后置位总线
}



//Read one byte from DS18B20
uchar read_byte_18B20(void)
{
      uchar x;
          uchar retval=0;
          for(x=0;x<8;x++)
          {
                retval>>=1;  //先读取低位字节,右移保存
            OUT_18B20;   //主机控制总线
                        CLR_18B20;   //强制拉低
                        //之后在到读取出数据为止,15us内必须读出数据
                        SET_18B20;   //释放总线,生成读间隙
                        IN_18B20;    //总线设置为输入
                        if(STU_18B20)          retval|=0x80;    //读出为“1”信号
            delay_time(0xF1);
          }
//          SET_18B20;      //读完8位后置位总线
          return(retval); //返回读到的值
}




//Read temperature from DS18B20
void read_temp_18B20(void)
{          
      uint k=0;
          uchar temp_L=0;         //温度低八位
      uchar temp_H=0;         //温度高八位       
          init_18B20();
          write_byte_18B20(0xcc);      //跳过ROM
          write_byte_18B20(0x44);      //启动温度转换
      
          for(;k<750;k++) {delay_time(0x00);}   //??????此处延时是否需要?
            //数据手册提示说要750ms左右,蒙了……温度转换效率那么低还要来干球!!
       
          init_18B20();                  //重新复位
          write_byte_18B20(0xcc);                //跳过ROM
          write_byte_18B20(0xbe);                //发读数据指令

          temp_L=read_byte_18B20();        //温度数据低8位
          temp_H=read_byte_18B20();        //温度数据高8位

          if(temp_H<0xf8)   temperature=((temp_H*256)+temp_L)*0.0625;   //大于0的情况       
          else
          {
              temperature = (((~temp_H)*256)+(~temp_L)+1)*0.0625;    //小于0的情况
                  temperature = -temperature;
           }
}


void display_temp(void)
{
        uint temp_B,temp_S,temp_G,temp_F1;

        if(temperature>=0)
        {
              temp_B  = ((int)temperature)/100;
              temp_S  = ((int)temperature)%100/10;
              temp_G  = ((int)temperature)%100%10;

                  temp_F1 = ((int)(temperature*100))%100/10;
//                  temp_F2 = ((int)(temperature*100))%10;

                  WriteNum(2,1,temp_B+0x30);
                  WriteNum(2,2,temp_S+0x30);
                  WriteNum(2,3,temp_G+0x30);

                  WriteChar(2,4,1,".");        //标志行

                  WriteNum(2,5,temp_F1+0x30);
//              WriteNum(2,6,temp_F2+0x30);
        }
        else
        {
              temp_B  = ((int)(-temperature))/100;
              temp_S  = ((int)(-temperature))%100/10;
              temp_G  = ((int)(-temperature))%100%10;

                  temp_F1 = ((int)((-temperature)*100))%100/10;
//                  temp_F2 = ((int)((-temperature)*100))%10;


              WriteChar(2,1,1,"-");        //标志行

                  WriteNum(2,2,temp_B+0x30);
                  WriteNum(2,3,temp_S+0x30);
                  WriteNum(2,4,temp_G+0x30);

                  WriteChar(2,5,1,".");        //标志行

                  WriteNum(2,6,temp_F1+0x30);
//              WriteNum(2,7,temp_F2+0x30);
        }

}


int main(void)
{   
        init_devices();
        LcdInit();         //初始化
        WriteChar(1,0,12,temp_num);        //标志行

//        init_18B20();

        while(1)
        {
                 read_temp_18B20();
                 display_temp();
//                 for(z=0;z<18;z++)   {s_ms(60000);}
        }

}





/*-----------------------------------------------------------------------------------------
//包含LCD1602的头文件如下
-----------------------------------------------------------------------------------------*/
#define uchar unsigned char
#define uint unsigned int

#define RS 0
#define RW 1
#define EN 2

void s_ms(uint ms)
{
    uint i=0;
        for(i=0;i<1000;i++){for(;ms>1;ms--);}
}       


//查忙
void busy(void)
{
    uchar temp;
        s_ms(500);
        PORTG&=~(1<<RS);    //RS=0
        s_ms(500);
        PORTG|=(1<<RW);     //RW=1
        s_ms(500);
        while(temp)
        {
                PORTG|=(1<<EN); //EN=1
                s_ms(500);
                DDRA=0x00;      //A口变输入
                PORTA=0xff;     //上拉使能
                s_ms(500);
                temp = PINA&0x80;    //读取A口
                s_ms(500);      
                DDRA=0xff;      
                PORTA=0xff;        //A口变输出
                s_ms(500);
                PORTG&=~(1<<EN);   //EN=0
                s_ms(500);
        }
}

//写指令
void writecom(uchar        com)
{
        busy();
        s_ms(500);
        PORTG&=~(1<<RS);   //RS=0
        s_ms(500);
        PORTG&=~(1<<RW);   //RW=0
        s_ms(500);
        PORTG|=(1<<EN);    //EN=1
        s_ms(500);
        PORTA = com;       //输出指令
        s_ms(500);
        PORTG&=~(1<<EN);   //EN=0
        s_ms(500);
}

//1602初始化
void        LcdInit(void)
{
        writecom(0x38);
        s_ms(1000);
        writecom(0x01);
        s_ms(10000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        writecom(0x02);
        s_ms(1000);
        writecom(0x06);
        s_ms(1000);
        writecom(0x0c);
        s_ms(1000);
        writecom(0x38);       
        s_ms(1000);
}       

//写数据
void        writedata(uchar data)
{
        busy();
        s_ms(500);
        PORTG|=(1<<RS);   //RS=1
        s_ms(500);
        PORTG&=~(1<<RW);   //RW=0
        s_ms(500);
        PORTG|=(1<<EN);    //EN=1
        s_ms(500);
        PORTA = data;      //输出数据
        s_ms(500);
        PORTG&=~(1<<EN);   //EN=0
        s_ms(500);
}


//读数据
uchar        readdata(void)
{
        uchar temp;
        busy();
        s_ms(500);
        PORTG|=(1<<RS);  //RS=1
        s_ms(500);
        PORTG|=(1<<RW);  //RW=1
        s_ms(500);
        PORTG|=(1<<EN);  //EN=1
        s_ms(500);
        DDRA=0x00;       //A端口变输入
        s_ms(500);
        temp = PINA;     //读A端口
        s_ms(500);
        DDRA=0xff;       //A端口变输出
        s_ms(500);
        PORTG&=~(1<<EN); //EN=0
        s_ms(500);
        return temp;       
}

//=================================================
// 描述: 写LCD内部CGRAM函数
// 入口: ‘num’要写的数据个数
//        ‘pbuffer’要写的数据的首地址
// 出口: 无
//================================================
void        WriteCGRAM(uint        num, const uint        *pBuffer)
{
        uint        i,t;
        writecom(0x40);
        PORTG|=(1<<RS);
        PORTG&=~(1<<RW);
        for(i=num;i!=0;i--)
        {
                t = *pBuffer;
                PORTG|=(1<<EN);
                PORTA = t;
                PORTG&=~(1<<EN);                               
                pBuffer++;
        }
       
}

//=================================================
//描述:写菜单函数,本程序使用的LCD规格为 16 * 2
//入口:菜单数组首地址
//出口:无
//=================================================
void        WriteMenu(const uchar *pBuffer)
{
        uchar        i,t;
        writecom(0x80);   //数据地址
       
        PORTG|=(1<<RS);
        PORTG&=~(1<<RW);
        s_ms(50);
        for(i=0;i<16;i++)
        {
                t = *pBuffer;
                PORTA = t;
                PORTG|=(1<<EN);
                s_ms(50);
                PORTG&=~(1<<EN);                               
                pBuffer++;
        }
        writecom(0xC0);

        PORTG|=(1<<RS);
        PORTG&=~(1<<RW);
        s_ms(50);       
        for(i=0;i<16;i++)
        {
                t = *pBuffer;
                PORTA = t;
                PORTG|=(1<<EN);
                s_ms(50);
                PORTG&=~(1<<EN);                               
                pBuffer++;
        }
}
//====================================================
// 描述:在任意位置写数字函数
// 入口:’row‘表示要写数字所在的行地址,只能为1或2
//       ’col‘表示要写数字所在的列地址,只能为0--15
//                 ‘num’表示要写的数字,只能为0--9
// 出口:无
//===================================================
void WriteNum(uchar row,uchar col,uchar num)
{
        if (row == 1)        row = 0x80 + col;
        else        row = 0xC0 + col;
        writecom(row);

        PORTG|=(1<<RS);
        s_ms(500);
        PORTG&=~(1<<RW);
        s_ms(500);
        PORTA = num;
        s_ms(500);
        PORTG|=(1<<EN);
        s_ms(500);
        PORTG&=~(1<<EN);       
        s_ms(500);                       
}
//================================================================
// 描述:在任意位置写任意多个字符
// 入口:’row‘要写的字符所在的行,只能为1或2;
//       ‘col’要写的字符所在的列,只能为0---15
//       ‘num’要写字符的个数
//       ‘pbuffer’要写字符的首地址
//==================================================================
void        WriteChar(uchar row,uchar col,uint num,uchar *pBuffer)
{
        uchar i,t;
        if (row == 1)        row = 0x80 + col;
        else        row = 0xC0 + col;
        writecom(row);


        PORTG|=(1<<RS);
        s_ms(500);
        PORTG&=~(1<<RW);
        s_ms(500);
        for(i=num;i!=0;i--)
        {
                t = *pBuffer;
                s_ms(500);
                PORTA = t;
                s_ms(500);
                PORTG|=(1<<EN);
                s_ms(500);
                PORTG&=~(1<<EN);               
                s_ms(500);               
                pBuffer++;
        }
       
}



问题点:
1:定时器用做延时时如何初始化以及如何查询标志位?-----T0为例
   个人想法是初始化其实可以忽略,只要程序一开始关闭定时器即可,这样在以后需要延时的地方再启动它,不过是否需要设置匹配值OCR0,我还是搞不大明白;查询定时器是否溢出的标示位TOV0是否如我编写的那样查询?总感觉有点悬乎……不知道查询方式对没
2:温度转换子程序中发转换命令后是否需要等待那么长时间?太悬了……我看到很多个版本,有的说是必须要,有的说不要也照样跑得过去
3:直接如程序里的方式来判断温度正/负是否妥当?
4:目前读出一个数值:015.9-------------不知是哪里的数值,数值保持不变



也许用内部晶振的话估计能找到好多参考,而且是可以直接移植的参考……M8低速模式下跟C51单片机我都调出过N次的DS18B20
这里我只是提出一个高速晶振时对于精确延时的寻求解决办法,这里用到定时器做延时有点大材小用了!
望高手能指点一二或者有兴趣的同僚多多交流

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

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

出0入0汤圆

 楼主| 发表于 2009-3-27 16:04:07 | 显示全部楼层
没有大虾路过吗?……伤哀

出0入0汤圆

发表于 2009-3-27 16:17:11 | 显示全部楼层
宁万大哥!不用这么拼命吧

出0入0汤圆

 楼主| 发表于 2009-3-27 17:02:30 | 显示全部楼层
……严重的对楼上无语,我的帖都被你翻到~~~~~~~

出0入0汤圆

发表于 2009-3-27 17:12:03 | 显示全部楼层
几十微秒别用定时器了.没必要.中断一下,或者查询一下,时间差不多.

楼主,没谁有兴趣看代码.
不过我给你个我试过了,也是本站某兄弟写的,绝对可用,不过是8M的,需要把延时程序改下.改一下端口定义.
里面什么定时器什么的你都不用管了.


http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=657257&bbs_page_no=1&search_mode=1&search_text=18B20&bbs_id=1000

出0入0汤圆

发表于 2009-3-27 19:57:20 | 显示全部楼层
我搞的时候情况和楼主相反,是高速时钟下没问题,低速时钟下才碰到困难。

不过某人逛这里的时候,看到个帖子,一下子就解决了。

帖上我当时的BLOG,希望对楼主有用。

http://hi.baidu.com/bg4uvr/blog/item/263145335bdbb045ad4b5f8f.html

出0入4汤圆

发表于 2009-3-28 09:57:11 | 显示全部楼层
//Write one byte to DS18B20
void write_byte_18B20(uchar val)
{
       uchar j;
           uchar y;
           for(j=0;j<8;j++)
           {
                    y=val>>j;      //先写低位
                    y&=0x01;       //查询要写入的位是“0”或者“1”
                    if(y)          //如果要写入的是“1”
                    {
                          NOP();
                          NOP();
                          NOP();
                          SET_18B20;                //写入“1”                  
                    }
                    else  CLR_18B20;                //强制拉低,产生写间隙,写“0”时保持即可
             //输出一位之后,维持时间大于60us,小于120us
                         delay_time(0xF1);
                         SET_18B20;                        //DATA=1,上拉  
                         delay_time(0xFD);         
            }
                SET_18B20;   //8位写完成后置位总线
}

写“1”时也要拉低总线20us左右以通知ds18b20,否则它不知道的。

出0入0汤圆

 楼主| 发表于 2009-3-28 10:35:00 | 显示全部楼层
楼上诸位大虾,感激不尽、感激不尽……
四楼的大哥提醒得对,确实很多人不喜欢看别人的代码,包括我自己,也不喜欢看别人的代码,很头大啊!!!
可没办法三……问题就出在延时代码上,只好附上来了
我原先写的程序没用定时器的,可这18B20比较挑,用内嵌的循环写成的延时又不好把握时长,所以……

出0入0汤圆

发表于 2009-6-4 16:53:05 | 显示全部楼层
请教一下:怎样把主机接收的DS18b20数据(二进制补码)转换为10进制数呢?
楼主用了这段代码:
if(temp_H<0xf8)   
  temperature=((temp_H*256)+temp_L)*0.0625;   //大于0的情况         
else
  {
     temperature = (((~temp_H)*256)+(~temp_L)+1)*0.0625;    //小于0的情况
     temperature = -temperature;
  }

出0入0汤圆

发表于 2013-2-1 00:55:05 | 显示全部楼层
lonelynw 发表于 2009-3-28 10:35
楼上诸位大虾,感激不尽、感激不尽……
四楼的大哥提醒得对,确实很多人不喜欢看别人的代码,包括我自己, ...

想问问您这个高速晶振下的18B20问题解决了没... 我最近也碰到这个情况 想向您求助一下

出0入0汤圆

发表于 2013-2-1 00:56:20 | 显示全部楼层
lonelynw 发表于 2009-3-28 10:35
楼上诸位大虾,感激不尽、感激不尽……
四楼的大哥提醒得对,确实很多人不喜欢看别人的代码,包括我自己, ...

感觉您测出的温度不是15.9  而是 I5.9  是英文字母 "i" 的大写

出0入0汤圆

发表于 2013-2-1 21:07:15 | 显示全部楼层
我只学过C51……瞎说说啊……
应该是时钟问题,在对DS18B20进行读写的子程序里面用到的delay一般就是几个至十几个NOP,16MHz相当于51单片机一百多MHz,我在C51下晶振从12Mhz(12T单倍速)换成了20Mhz丫都罩不住……别说您这么快了
贴上一小段C51的代码:
/*

        DQ为输入数据的接口,接ds18b20的中间
        调用方法:
        uint ds18b20_get_temp();
        得到的温度如果最高位=1则温度为负温度,否则正温度

*/



#include<reg52.h>
#include"ds18b20_driver.h"
#include"delay_api.h"

#define jump_ROM   0xCC
#define start      0x44
#define read_EEROM 0xBE



sbit DQ=1^7;
uchar TMPL,TMPH;

unsigned char reset_ds18b20(void)
{
        uchar deceive_ready;
        DQ = 0;
        macdelay(29);
        DQ = 1;
        macdelay(3);
        deceive_ready = DQ;
        macdelay(25);
        return(deceive_ready);
}
uchar ds18b20_read_bit(void)
{
        uchar i;
        DQ = 0;
        DQ = 1;
        for(i=0; i<3; i++);
        return(DQ);
}

void ds18b20_write_bit(uchar bitval)
{
DQ=0;if(bitval==1)
DQ=1;
macdelay(5);
DQ=1;
}

uchar ds18b20_read_byte(void)
{
        uchar i,m,receive_data;
        m = 1;
        receive_data = 0;
        for(i=0; i<8; i++)
        {
                if(ds18b20_read_bit())
                {
                        receive_data = receive_data + (m << i);
                }
                macdelay(6);
        }
        return(receive_data);
}

void ds18b20_write_byte(uchar val)
{
        uchar i,temp;
        for(i=0; i<8; i++)
        {
                temp = val >> i;
                temp = temp & 0x01;
                ds18b20_write_bit(temp);
                macdelay(5);
        }
}
uint ds18b20_get_temp(uchar cf)
{
        uint temp;
        uchar tflag;
        reset_ds18b20();
        ds18b20_write_byte(jump_ROM);
        ds18b20_write_byte(start);
        reset_ds18b20();
        ds18b20_write_byte(jump_ROM);
        ds18b20_write_byte(read_EEROM);
        TMPL = ds18b20_read_byte();
        TMPH = ds18b20_read_byte();
        temp=TMPH;
        temp<<=8;
        temp=temp|TMPL;
        if(temp<0x0fff){
                tflag=0;
        }else{
                tflag=1;
                temp=~temp+1;
        }
       
        if(cf){
                temp=temp*0.1125+32+tflag*0x1000;
        }else{
                temp=temp*0.0625+tflag*0x1000;
        }
        return temp;
}
/*温度模块结束*/
里面使用的macdelay如下:
void macdelay(uint i){
        uint j=0;
        for(j=0;j<i;j++){
        }
}
在20Mhz下,将macdelay的延时扩充为本来的两倍就正常了
所以不妨试试。

出0入0汤圆

发表于 2013-2-2 00:03:29 | 显示全部楼层
以后也要用到

出0入0汤圆

发表于 2013-2-2 00:21:06 | 显示全部楼层
弄时序方面的  示波器不离手    在程序里面丢脉冲到其他引脚   用同步来看时序走到了哪一步    那一步不通   就抓住了再分析

出0入0汤圆

发表于 2013-2-3 11:19:21 | 显示全部楼层
lisun0410 发表于 2013-2-1 00:55
想问问您这个高速晶振下的18B20问题解决了没... 我最近也碰到这个情况 想向您求助一下 ...

应该是延时大多过长了

出0入0汤圆

发表于 2013-2-3 15:38:11 | 显示全部楼层
xqn2012 发表于 2013-2-3 11:19
应该是延时大多过长了

额 晶振从8M变成16M 延时需要适当增加 我先翻倍 然后逐渐减少 现在已经调通了

出0入0汤圆

发表于 2013-2-4 08:05:05 来自手机 | 显示全部楼层
mark以备查,18b20的时序很麻烦

出0入0汤圆

发表于 2013-2-4 09:34:39 | 显示全部楼层
lisun0410 发表于 2013-2-3 15:38
额 晶振从8M变成16M 延时需要适当增加 我先翻倍 然后逐渐减少 现在已经调通了 ...

其实我是想说,延时比较麻烦,如果是avr studio话,还要优化。就是慢慢调的

出0入0汤圆

发表于 2013-2-4 09:45:39 | 显示全部楼层
xqn2012 发表于 2013-2-4 09:34
其实我是想说,延时比较麻烦,如果是avr studio话,还要优化。就是慢慢调的 ...

额 好吧 我用的CVAVR

出0入0汤圆

发表于 2013-3-17 15:13:43 | 显示全部楼层
我也调了两天的ATMEGA128  16MHZ 下的DS18B20  。。 好累啊,不知道哪里错了。求楼主指点哪里要注意的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-24 03:27

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

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