tag 标签: 示波器显示字符

相关博文
  • 热度 9
    2012-3-14 14:19
    2795 次阅读|
    2 个评论
    把ADI征文的一起汇聚到这边,就示波器显示时钟做个完结   Aduc841+DS1337C实现示波器显示时钟 tziang@hotmail.com 题记: 上季征文写过一个AD7528+Android示波器显示任意ASCII字符和时钟,当时手头正好在做高通7227的Andriod手机,加上linux加ADB shell调试起来比较方便,所以就用这套超级豪华的硬件平台来做了这个简单的应用。 之前其实也只做好了示波器显示ASCII字符部分,时钟模块并没有做进去,现在改用ADI的ADUC841+DS1337C来做显示时钟,顺便了解下ADI 51核的单片机。   2011-11-14 今天收到ADI的ADUC841(8051核)和MAX的RTC芯片DS1307(DS1337C的功能与DS1307类似,并且供电是3.3V的,DS1307需要5V,暂时用DS1337C来调),还是改用51来继续做完这个项目,之前想用ADI的ADUC7024(ARM7核),但它不提供UART调试,问过ADI官方技术支持,他们也没有相关的文档支持,51可以支持UART调试,另外ADUC841有丰富的片上资源,比如双路12-bit的DAC,可以支持同时更新输出,可以配置成8位输出,这样就不需要额外增加DAC芯片了   2011-11-15 开始焊接一个最小系统,试验UART调试是否可用,晶体目前只找到个12MHz的,从一个废旧的U盘上卸下。最小系统完成后,上电,晶体振荡不了,更换手机项目上的一个13MHz晶体后,能够振荡起来了,使用ADI的WSD下载模式通信不上,调换RX,TX后还是不行 最小系统如下(背上驮的是美信的DS1337C和DS1307时钟模块)   2011-11-16 确认RX,TX的连接后,WSD可以连上,下载一个官方DAC烧进去后,连接串口调试工具,能够看到输出乱码了,根据841规格书,结合DAC源码示例,更改UART的波特率为57600后,可以看到正常输出。修改之后DAC,可以在XY模式下显示圆,修改PLL,使fclk为13MHz,输出的sine周期没有改变,屏蔽掉printf之后,周期大概是1mS,基本可以接受了,后面成熟之后再使用19.2MHz看是否有改善。UART基本调通了。 另外,折腾了半天发现ADUC841的复位竟然是高电平复位,难怪之前下载时怪怪的,其实规格书中reset没有使用reset_n或者reset#,就应该看出来了,经验主义要不得。   2011-11-17 根据ADI官方的I2C参考代码,已经把DS1337C加进去了,I2C还需要测试下功能,根据ADI官方的UART调试文档,Keil下没有连接成功,UART都已经通了,就不折腾了,直接烧代码用UART打log吧。   关于DS1337C的I2C读写,看规格书结合代码 写: 先写设备地址+写位,然后是寄存器地址,后跟0个或若干个DATA, 不跟DATA就是单独设置寄存器指针,每个DATA后寄存器指针会自动加1 读分两种: 一种是直接读,直接从当前的寄存器指针开始 一种是先指定寄存器指针(就是用到上面只写寄存器地址,不写DATA),然后读 写时,每个byte之后,slave都会给一个应答 读时,最后一个byte之后,Master不会给应答,标准的I2C设备应该都是这样的吧   读写分别对应的图示如下   2011-11-21 I2C的控制DS1337C的全部代码周末已经完成,使用定时器0做延时的程序需要一并确认, I2C有问题,没有调通,片上资源DA显示没有问题了,能够在XY模式下显示圆和指定的字符,试验显示字符"a"没有问题,圆有点变形,应该是使用VDD做基准导致,明天更改成使用片上2.5V基准看是否有改善。     2011-11-22 I2C部分,试验已经能够发送正确的设备地址,寄存器地址和设置的数据,但是设备没有正确的应答,待调试;   2011-11-23 I2C部分,通过示波器发现SCL信号正常,有9个时钟,SDA只变化一次,仔细看代码,关键是发送和接受这两个函数,屏蔽蓝色部分的参考代码,增加红色部分的代码,之前SDA只变化一次,原来是if(ByteToSend0x80)写成了if(ByteToSend0x80==1),更改后一切正常了,其实这就是GPIO模拟I2C的代码,其它平台都可以参照此实现GPIO模拟I2C。 参考代码中的发送和接受数据使用了很多条件判断语句,个人觉得实际应用中用途不大,调试这种低速,小数据量的代码,完全可以借助于示波器来进行,另外参考代码的连续读和写函数没有使用,主要是I2C设备比较简单,连续读写用在存储芯片上可能会比较多一点。再次强调下示波器调试I2C,SPI等绝对是最正确,最便捷的选择。 下一步是使用841的DAC部分来显示表盘等,使用查表方式,表针部分使用数学计算。   BYTE SendByteI2CMaster(BYTE ByteToSend)    {        BYTE i;        BYTE noack;            MDE = 1;    //Enable SDA output        for (i=8; i0; i--)        {            MCO = 0;                //Reset SCL    //tangw        MDO = ByteToSend  7;    //Send data to SDA pin    if(ByteToSend0x80) { MDO=1; } else { MDO=0; }         delay_5uS();            MCO = 1;                //Set SCL            delay_5uS();            MCO = 0;                //Reset SCL            delay_5uS();     //tangw       ByteToSend=1;       //Rotate data        ByteToSend=ByteToSend1;     }        MDE = 0;                //SDA becomes an input for the ACKN        MCO = 0;                //Reset SCL            delay_5uS();        MCO = 1;                //Set SCL        noack = (BYTE)MDI;      //Check SDA for ACKN    //tangw    MDO=0;        delay_5uS();        MCO = 0;        MDE = 1;    //Enable SDA output        return(noack);    }                //---------------------------------    //ReceiveByteI2CMaster();    //---------------------------------    //Function that reads one byte from the I2C port. If we do continuous read,     //then the acknowledgement must be "0" excepted for the last read sequence which    //it must be "1".    //--------------------------------------------------------------------------------    BYTE ReceiveByteI2CMaster(bit ackn)    {        unsigned char i;        BYTE ReceivedByte=0;            MDE = 0;    //Make SDA an input        MCO = 0;    //Reset SCL        for (i=8; i0; i--)        {            MCO = 1;                //Set SCL            delay_5uS();            ReceivedByte = ReceivedByte  1;         if(MDI==1)         {             ReceivedByte |= 0x01;  //get HIGH         }         else         {             ReceivedByte |= 0x00;  //get LOW         }  //tangw       ReceivedByte = 1;       //Rotate data     //tangw       ReceivedByte |= MDI;    //Read SDA - data            delay_5uS();            MCO = 0;                //Reset SCL            delay_5uS();        }        MDE = 1;    //SDA is turned in an output to write the ACK on the data line        MDO = ackn; //SDA = ACK bit        delay_5uS();        MCO = 1;    //Set SCL        delay_5uS();        MCO = 0;    //Reset SCL        delay_5uS();    //  MDE = 0;    //SDA is an input again       return(ReceivedByte);    }      void InitialiseI2CMaster(void)    {    //    ADD0=1;             //Write a "1" to ADD0 so that it becomes an input.    //    CLK=1;              //Write a "1" to CLK so that it becomes an input.            SPICON = 0xDF;     //SPI interface is turned off by clearing the SPE bit.        I2CCON = 0xA8;      //Master mode    }            //---------------------------------    //StartI2CMaster();    //---------------------------------    //Function that implements the start condition of the I2C protocol. The start    //condition consists in a falling edge on SDA when SCL is high.    //--------------------------------------------------------------------------------    void StartI2CMaster(void)    {        MDE = 1;    //SDA output enabled            MCO = 0;    //SCL low        MDO = 0;    //SDA low        MDO = 1;    //SDA high        MCO = 1;    //SCL high        delay_5uS();        MDO = 0;    //SDA goes low before the clock        delay_5uS();        MCO = 0;    //SCL low        delay_5uS();    }            //---------------------------------    //StopI2CMaster();    //---------------------------------    //Function that implements the stop condition of the I2C protocol. The stop    //condition consists in a rising edge on SDA when SCL is high.    //--------------------------------------------------------------------------------    void StopI2CMaster(void)    {        MDE = 1;    //SDA output enabled        MDO = 0;    //SDA low        delay_5uS();   //needs 5uS delay     MCO = 1;    //SCL high        delay_5uS();        MDO = 1;    //SDA goes from low to high when SCL is already high,        delay_5uS();    }      byte I2CWrite(byte DevAddr,byte RegAddr, byte val) //byte I2CRead(byte DevAddr,byte RegAddr); {        BYTE AcknError;        BYTE DeviceAddressHeader;        AcknError=1; //No error on initialisation            //Add the write bit to the device address        DeviceAddressHeader = DevAddr1 | I2C_WR;            //Start the I2C transfer        InitialiseI2CMaster();        StartI2CMaster();        //Send device address      SendByteI2CMaster(DeviceAddressHeader);         SendByteI2CMaster(RegAddr);       SendByteI2CMaster(val);         StopI2CMaster();    return 0; }      byte I2CRead(byte DevAddr,byte RegAddr) {        byte ReadData;        byte DeviceAddressHeader;            ReadData=0xFF; //No error on initialisation                //Add the write bit to the device address        DeviceAddressHeader = DevAddr1 | I2C_WR;          //Start the I2C transfer        InitialiseI2CMaster();        StartI2CMaster();            //Send device address    SendByteI2CMaster(DeviceAddressHeader);         //Send register address        SendByteI2CMaster(RegAddr);      //Send the repeated start        StartI2CMaster();         //Send device address again changing the Rd/Wr bit        DeviceAddressHeader = DevAddr1 | I2C_RD;         SendByteI2CMaster(DeviceAddressHeader);         ReadData=ReceiveByteI2CMaster(NACK);         StopI2CMaster();            return(ReadData);    }      2011-11-24   几番努力,通过UART打log,DS1337C通信已经正常了,并且能够正确的送出时间到示波器, 秀一下最终图片,相关关键代码见附件压缩包