搜索
bottom↓
回复: 3

sd2000时钟程序共享

[复制链接]

出0入0汤圆

发表于 2005-12-15 14:28:19 | 显示全部楼层 |阅读模式
测试环境 M32L F=7.3728M







#include<iom32v.h>

#include<macros.h>

#include<stdio.h>

typedef unsigned char u08;

typedef unsigned int  u16;

u08 SD2K_TWI (u08 SLA,u08* data, u08 nSize);





/* SD2K常用命令宏定义 */

/*====================================================/

功能描述: 复位实时时钟SD2K(SD2000AP)

复位时间: 00年, 01月, 01天, 0星期, 00时, 00分, 00秒

返 回 值: 0=复位成功 !0=失败

/====================================================*/



/*====================================================/

功能描述: 设置实时时钟SD2K(SD2000AP)新的日期和时间

入口参数:

返 回 值: 0=设置成功 !0=失败

/====================================================*/



/*====================================================/

功能描述: 读出实时时钟SD2K(SD2000AP)的日期和时间

入口参数:

返 回 值: 0=设置成功 !0=失败

/====================================================*/



/*====================================================/

功能描述: 读实时时钟SD2K(SD2000AP)的状态寄存器

入口参数:

返 回 值: 0=设置成功 !0=失败

/====================================================*/



/*====================================================/

功能描述: 写实时时钟SD2K(SD2000AP)的状态寄存器

入口参数:

返 回 值: 0=设置成功 !0=失败

/====================================================*/







/* TWI波特率计算 */

/*************************************************************************/

/* 设置 TWPS=0 即与分频系数为1 */

#define F_TWI             100000               

///* 100KHz */

#define F_CPU  7372800

#define TWBR_SELECT  0x40        



/* SD2K命令定义 */

/*************************************************************************/  

#define CMD_RESET        0x61        // 复位命令,60也可以



#define CMD_STUSR_W        0x62        // 写状态寄存器指令

#define CMD_STUSR_R        0x63        // 读状态寄存器指令



#define CMD_TIMEALL_W    0x64        // 写实时时钟数据指令(年.月.日.星期.时.分.秒)

#define CMD_TIMEALL_R    0x65        // 读实时时钟数据指令(年.月.日.星期.时.分.秒)



#define CMD_TIME_W        0x66        // 写实时时钟数据指令(时.分.秒)

#define CMD_TIME_R        0x67        // 读实时时钟数据指令(时.分.秒)



#define CMD_INT1_W        0x68        // 写频率事件设置指令(INT1脚)

#define CMD_INT1_R        0x69        // 读频率事件设置指令(INT1脚)



#define CMD_INT2_W        0x6A        // 写频率事件设置指令(INT2脚)

#define CMD_INT2_R        0x6B        // 读频率事件设置指令(INT2脚)

/****************************************************************************

  TWI State codes

****************************************************************************/

// General TWI Master staus codes                     

#define TWI_START                  0x08  // START has been transmitted  

#define TWI_REP_START              0x10  // Repeated START has been transmitted

#define TWI_ARB_LOST               0x38  // Arbitration lost



// TWI Master Transmitter staus codes                     

#define TWI_MTX_ADR_ACK            0x18  // SLA+W has been tramsmitted and ACK received

#define TWI_MTX_ADR_NACK           0x20  // SLA+W has been tramsmitted and NACK received

#define TWI_MTX_DATA_ACK           0x28  // Data byte has been tramsmitted and ACK received

#define TWI_MTX_DATA_NACK          0x30  // Data byte has been tramsmitted and NACK received



// TWI Master Receiver staus codes  

#define TWI_MRX_ADR_ACK            0x40  // SLA+R has been tramsmitted and ACK received

#define TWI_MRX_ADR_NACK           0x48  // SLA+R has been tramsmitted and NACK received

#define TWI_MRX_DATA_ACK           0x50  // Data byte has been received and ACK tramsmitted

#define TWI_MRX_DATA_NACK          0x58  // Data byte has been received and NACK tramsmitted



// TWI Slave Transmitter staus codes

#define TWI_STX_ADR_ACK            0xA8  // Own SLA+R has been received; ACK has been returned

#define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0  // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned

#define TWI_STX_DATA_ACK           0xB8  // Data byte in TWDR has been transmitted; ACK has been received

#define TWI_STX_DATA_NACK          0xC0  // Data byte in TWDR has been transmitted; NOT ACK has been received

#define TWI_STX_DATA_ACK_LAST_BYTE 0xC8  // Last data byte in TWDR has been transmitted (TWEA = ??; ACK has been received



// TWI Slave Receiver staus codes

#define TWI_SRX_ADR_ACK            0x60  // Own SLA+W has been received ACK has been returned

#define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68  // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned

#define TWI_SRX_GEN_ACK            0x70  // General call address has been received; ACK has been returned

#define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78  // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned

#define TWI_SRX_ADR_DATA_ACK       0x80  // Previously addressed with own SLA+W; data has been received; ACK has been returned

#define TWI_SRX_ADR_DATA_NACK      0x88  // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned

#define TWI_SRX_GEN_DATA_ACK       0x90  // Previously addressed with general call; data has been received; ACK has been returned

#define TWI_SRX_GEN_DATA_NACK      0x98  // Previously addressed with general call; data has been received; NOT ACK has been returned

#define TWI_SRX_STOP_RESTART       0xA0  // A STOP condition or repeated START condition has been received while still addressed as Slave



// TWI Miscellaneous status codes

#define TWI_NO_STATE               0xF8  // No relevant state information available; TWINT = ??

#define TWI_BUS_ERROR              0x00  // Bus error due to an illegal START or STOP condition

//*************************************************************************/

//#endif



u08 invert(u08 tdata);

/**********************************************************************?/

功能描述: 实时时钟SD2K的MEGA8 TWI访问程序

入口参数:     SAL        操作指令

            data    操作数据指针

            nSize    操作数据大小        

返 回 值: 0=操作成功 非0=操作失败(错误信息参MEGA8手册TWI模式状态字)

作      者:

最后修改: 2005-12-15

/ ***********************************************************************/

u08 SD2K_TWI(u08 SLA,u08* data, u08 nSize)

{   

    u08 dd;

    // 设置TWI波特率 //

    TWBR = TWBR_SELECT;

   

    // 发送START信号,等待TWIT=1 //

    TWCR = (1<<TWSTA) | (1<<TWEN)|(1<<TWINT);            

    while(!(TWCR & (1<<TWINT)));

   

    // START信号成功发送了吗?不成功返回相应错误信息 //

    if ((TWSR&0xf8) != TWI_START)

                {printf("not start
");

                return (TWSR&0xf8);

    }

    // 发送命令,等待发送完成 //

    TWDR = SLA;

    TWCR = (1<<TWINT) | (1<<TWEN);

    while (!(TWCR & (1<<TWINT)));

   

    // 命令成功发送(或寻址成功)了吗?不成功返回相应错误信息 //

    if (SLA & 0x01)        // 1=读命令(主控接收器)  0=写命令(主控发送器)

        {

                        if ((TWSR&0xf8) != TWI_MRX_ADR_ACK)

                           {printf("no  read ack");

                           goto stoptwi;

//                        return TWI_MRX_ADR_ACK;

                                   }

                        }

    else

        {

                        if ((TWSR&0xf8) != TWI_MTX_ADR_ACK)

                        {

                        printf("no write ack");

                        goto stoptwi;

                        //return TWI_MTX_ADR_ACK;

                        }

                        }

        

    // 传送字节数!=0 ?//

    if (nSize !=0)

    {

        if (SLA & 0x01)        // 1=主控接收器操作  

            {   

            do    {

                // 若准备接收最后一个字节发送则发NACK,否则发送ACK //

                if (nSize ==1)

                    { TWCR = (1<<TWINT) |( 1<<TWEN); } //准备发送NACK

                else

                    { TWCR = (1<<TWINT) | (1<<TWEA) |( 1<<TWEN); } //准备发送ACK

               

                // 等待接收完成 //

                while (!(TWCR & (1<<TWINT)));  

                                          

                *data = invert(TWDR);

                                       

                // 数据接收成功  //

                if (nSize ==1)

                    // 最后字节成功接收  不成功返回相应错误信息 //

                    { if ((TWSR&0xf8 )!= TWI_MRX_DATA_NACK)//TWI_MRX_ADR_ACK )//TWI_MRX_DATA_ACK)

                                                           {                         //return TWI_MRX_DATA_ACK;

                         printf("no ack1");

                                                                                 goto stoptwi;

                                                         }

                                                 }

                else

                    // 非最后字节成功接收  不成功返回相应错误信息 //

                    { if ((TWSR&0xf8) != TWI_MRX_DATA_ACK)

                                                                                     {//return TWI_MRX_DATA_ACK;

                                                                                  printf("no ack2");

                                                                                 goto stoptwi;

                                                                                  }

                                                }  



                // 保存接收数据 //

               // *data = TWDR;//invert(TWDR);

                data++;

                    

                }while ( --nSize != 0 );    // 循环发送完

            }                        

            

        else                //0=主控发送器操作

            {        

            do    {

                // 准备送数据,发送,等待发送完成 //

                TWDR = invert(*data);

                TWCR = (1<<TWINT )| (1<<TWEN);

                data++;

                while (!(TWCR & (1<<TWINT)));

   

                // 数据发送成功?不成功返回相应错误信息 //

                if ((TWSR&0xf8) != TWI_MTX_DATA_ACK)

                                        { //return TWI_MTX_DATA_ACK;

                                                                                                     printf("no send ack");

                                                                                 goto stoptwi;

                                        }

                    

                }while ( --nSize != 0 ); // 循环发送完

            }

    }

stoptwi:

        

    // 发送STOP信号//

    TWCR = (1<<TWINT )|( 1<<TWSTO) |( 1<<TWEN);

        

    while ( (TWCR & (1<<TWSTO)) !=0 );   

    TWCR = 0;        

   

    // 调整端口设置,设置为高电平输出 //

    DDRC |= 3;

   

    // 成功发送完毕,返回0 //

    return 0;

}



u08 invert(u08 tdata)

{

u08 k,p,l,m=0;

p=0x01;

l=0x01;



for(k=0;k<=7;k++)

{

if(p&tdata){m=m|l;}



if(k!=7)m=m<<1;

p=p<<1;

}

m&=0x7f;

return m;



}



void BCD2HEX(u08 *buf)

{



u08 t,m;

m=*buf;

t=(m&0x0f)+((m&0xf0)>>4)*10;

*buf=t;



}













void Port_init(void)

{

PORTA = 0x00;

DDRA  = 0xFF;



PORTB = 0x00;

DDRB  = 0xFF;



PORTC = 0xff;

DDRC  = 0xFF;



PORTD = 0x04;

DDRD  = 0xF0;



//在16L中也试过类试的现象,后来把INT0置为输入口,用上升沿时设输入为高阻,

//外部加对地下拉,用下降沿时设输入上拉,问题解决。

}

void USART_init(void)

{

                 //UBRRH=0;

                 //UBRRL=38;

                 //UCSRC=0x18;

                 

UCSRB = 0x00; //disable while setting baud rate

UCSRA = 0x00;

UCSRC = BIT(URSEL) | 0x06;

UBRRL = 0x0b; //set baud rate lo 0x2F FOR 9600/0x11 for 38400

UBRRH = 0x00; //set baud rate hi

UCSRB = 0x18;



}

void ExtPort_init(void)

{



// DDRA= 0xFF;

// PORTA = 0x00;

                                               // ' put zero's on relays-port

//Latch_H;

//Latch_L;

return;

}

//uchar          7  6  5    4    3   2    1    0

//             – – – WDTOE WDE WDP2 WDP1 WDP0          WDTCR

//Read/Write   R  R  R   R/W   R/W  R/W R/W R/W

//Initial Value 0 0 0 0 0 0 0 0

void WDT_init(void)

{

//

/* reset WDT */

_WDR();

/* Write logical one to WDTOE and WDE */

//WDTCR |= (1<<WDTOE) | (1<<WDE);

WDTCR=0X18;   //现在把WDTCH给关掉了

/* Turn off WDT */

WDTCR = 0x00;

//WDTCR=0X17;



}





/*********延时子程序*********/



void delay_us(unsigned int dt)

    {

        while(dt)

      dt--;

        asm("nop");

        }



void delay_1ms(void)      //1ms

  {

    unsigned int i;

    for(i=1;i<1142;i++)

    ;

  }

void delay_ms(unsigned int n)

  {

    unsigned int i=0;

    while(i<n)

    {

    delay_1ms();

    i++;

        }

  }

  





/****************************************************************************

Call this function to set up the TWI master to its initial standby state.

Remember to enable interrupts from the main application after initializing the TWI.

****************************************************************************/

void TWI_Master_Initialise(void)

{

  TWBR = TWBR_SELECT  ;                                 // Set bit rate register (Baudrate). Defined in header file.

// TWSR = TWI_TWPS;                                  // Not used. Driver presumes prescaler to be 00.

  TWDR = 0xFF;                                      // Default content = SDA released.

  TWCR = (1<<TWEN)|                                 // Enable TWI-interface and release TWI pins.

         (0<<TWIE)|(0<<TWINT)|                      // Disable Interupt.

         (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|           // No Signal requests.

         (0<<TWWC);                                 //

                         

}   



void main(void)

{

u08 a1[11],d,s;

    WDT_init();

        Port_init();

        USART_init();

        ExtPort_init();

                GICR=0X00;//Enable Int0

                MCUCR=0X00;//int0 rising edge

                //Int0flag=0x00;

         SREG|=0X80; //2005

                TWI_Master_Initialise();

               

                printf("----------------------------
");

       

               

while(1)

{

s= SD2K_TWI(CMD_STUSR_R, &d, 1);//0x62

printf("=%d   ",s);



SD2K_TWI(CMD_TIME_R, &a1[0], 3);

for(s=0;s<3;s++)BCD2HEX(&a1);



printf("hh:mm:ss=%d:%d:%d   
",a1[0],a1[1],a1[2]);



SD2K_TWI(CMD_TIMEALL_R, &a1[0], 7);

for(s=0;s<7;s++)BCD2HEX(&a1);



printf("yy:mm:dd: -d-  hh:mm:ss=%d:%d:%d  -%d- %d:%d:%d   
",a1[0],a1[1],a1[2],a1[3],a1[4],a1[5],a1[6]);



delay_ms(800);











printf("----------------------------
");

}









}

出0入0汤圆

 楼主| 发表于 2005-12-15 15:48:30 | 显示全部楼层

出0入0汤圆

发表于 2007-8-23 15:22:46 | 显示全部楼层
谢谢。看看。

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-8 03:34

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

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