把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(ByteToSend&0x80)写成了if(ByteToSend&0x80==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; i>0; i--)
{
MCO = 0; //Reset SCL
//tangw MDO = ByteToSend >> 7; //Send data to SDA pin
if(ByteToSend&0x80)
{
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=ByteToSend<<1;
}
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; i>0; 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 = DevAddr<<1 | 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 = DevAddr<<1 | 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 = DevAddr<<1 | I2C_RD;
SendByteI2CMaster(DeviceAddressHeader);
ReadData=ReceiveByteI2CMaster(NACK);
StopI2CMaster();
return(ReadData);
}
2011-11-24
几番努力,通过UART打log,DS1337C通信已经正常了,并且能够正确的送出时间到示波器,
秀一下最终图片,相关关键代码见附件压缩包
用户1666466 2012-4-7 08:24
用户1578823 2012-3-26 17:10