热度 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通信已经正常了,并且能够正确的送出时间到示波器, 秀一下最终图片,相关关键代码见附件压缩包