![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测室 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . | ||
|
||
|
|||||
| 用gcc3.3写的MEGA8 TWI访问实时时钟SD2000的程序 | |||||
作者:61IC录入 文章来源:本站原创 点击数: 更新时间:2006-4-7 ![]() |
|||||
|
/********************************************************************** / 功能描述: 实时时钟SD2K的MEGA8 TWI访问程序 入口参数: SAL 操作指令 data 操作数据指针 nSize 操作数据大小 返 回 值: 0=操作成功 非0=操作失败(错误信息参MEGA8手册TWI模式状态字) 作 者: 程志宏 最后修改: 2003-04-09 / ***********************************************************************/ u08 SD2K_TWI (u08 SLA,u08* data, u08 nSize) { // 关闭显示 // LED_DX_CTL(0x1f); //关闭段显,全部高阻输入(包括PD5-7,PB0_4) LED_WX_CTL(0x04); //关闭位显,全部为高电平输出 // 调整端口设置,设置为上拉输入 // DDRC &= ~(1<<PC5 | 1<<PC4); // 设置TWI波特率 // TWBR = TWBR_SELECT; // 发送START信号,等待TWIT=1 // TWCR = 1<<TWSTA | 1<<TWEN; while (!(TWCR & (1<<TWINT))); // START信号成功发送了吗?不成功返回相应错误信息 // if (TWSR != TW_START) return TW_START; // 发送命令,等待发送完成 // TWDR = SLA; TWCR = 1<<TWINT | 1<<TWEN; while (!(TWCR & (1<<TWINT))); // 命令成功发送(或寻址成功)了吗?不成功返回相应错误信息 // if (SLA & 0x01) // 1=读命令(主控接收器) 0=写命令(主控发送器) { if (TWSR != TW_MR_SLA_ACK) return TW_MR_SLA_ACK; } else { if (TWSR != TW_MT_SLA_ACK) return TW_MT_SLA_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))); // 数据接收成功? // if (nSize ==1) // 最后字节成功接收? 不成功返回相应错误信息 // { if (TWSR != TW_MR_DATA_NACK) return TW_MR_DATA_NACK;} else // 非最后字节成功接收? 不成功返回相应错误信息 // { if (TWSR != TW_MR_DATA_ACK) return TW_MR_DATA_ACK;} // 保存接收数据 // *data = invert(TWDR); data++; }while ( --nSize != 0 ); // 循环发送完 } else //0=主控发送器操作 { do { // 准备送数据,发送,等待发送完成 // TWDR = invert(*data); TWCR = 1<<TWINT | 1<<TWEN; data++; while (!(TWCR & (1<<TWINT))); // 数据发送成功?不成功返回相应错误信息 // if (TWSR != TW_MT_DATA_ACK) return TW_MT_DATA_ACK; }while ( --nSize != 0 ); // 循环发送完 } } // 发送STOP信号// TWCR = 1<<TWINT | 1<<TWSTO | 1<<TWEN; while ( (TWCR & (1<<TWSTO)) !=0 ); TWCR = 0; // 调整端口设置,设置为高电平输出 // DDRC |= 1<<PC5 | 1<<PC4; // 成功发送完毕,返回0 // return 0; } 头文件sd2k.h内容: #ifndef SD2K_H #define SD2K_H /* 实时时钟用全局变量外部申明 */ /*************************************************************************/ extern u08 volatile g_sd2k_stusr; //实时时钟状态寄存器缓存区 extern u08 volatile g_sd2k_return; //实时时钟操作返回信息 extern u08 volatile g_sd2k_read_time [7]; //实时时钟读取时间缓存区 extern u08 volatile g_sd2k_set_time[7]; //实时时钟设置时间缓存区 extern u16 volatile g_sd2k_show_time[4] ; //时间显示缓存区:年,月日,时分,分秒 /* 函数外部申明 */ /*****************************************************/ extern void SD2K_SHOW_TIME(u08* source_time, u08* show_time); extern u08 SD2K_TWI (u08 SLA,u08* data, u08 nSize); /* SD2K常用命令宏定义 */ /*====================================================/ 功能描述: 复位实时时钟SD2K(SD2000AP) 复位时间: 00年, 01月, 01天, 0星期, 00时, 00分, 00秒 返 回 值: 0=复位成功 !0=失败 /====================================================*/ #define SD2K_RESET() g_sd2k_return=SD2K_TWI(CMD_RESET, &g_sd2k_stusr, 0) /*====================================================/ 功能描述: 设置实时时钟SD2K(SD2000AP)新的日期和时间 入口参数: g_sd2k_set_time 返 回 值: 0=设置成功 !0=失败 /====================================================*/ #define SD2K_SET_TIME(x) g_sd2k_return=SD2K_TWI(CMD_TIMEALL_W,(x), 7) /*====================================================/ 功能描述: 读出实时时钟SD2K(SD2000AP)的日期和时间 入口参数: g_sd2k_real_time 返 回 值: 0=设置成功 !0=失败 /====================================================*/ #define SD2K_READ_TIME(x) g_sd2k_return=SD2K_TWI(CMD_TIMEALL_R,(x), 7) /*====================================================/ 功能描述: 读实时时钟SD2K(SD2000AP)的状态寄存器 入口参数: g_sd2k_real_time 返 回 值: 0=设置成功 !0=失败 /====================================================*/ #define SD2K_READ_STUSR() g_sd2k_return=SD2K_TWI (CMD_STUSR_R, &g_sd2k_stusr, 1) /*====================================================/ 功能描述: 写实时时钟SD2K(SD2000AP)的状态寄存器 入口参数: g_sd2k_real_time 返 回 值: 0=设置成功 !0=失败 /====================================================*/ #define SD2K_WRITE_STUSR() g_sd2k_return=SD2K_TWI (CMD_STUSR_W, &g_sd2k_stusr, 1) /* TWI波特率计算 */ /*************************************************************************/ //#define F_CPU 4000000 /* 4MHz processor */ /* 设置 TWPS=0 即与分频系数为1 */ #define F_TWI 100000 /* 100KHz */ #define TWBR_SELECT (((F_CPU/F_TWI)-16)/2) /* 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脚) /*************************************************************************/ #endif 有益的提示: 注意sd200访问时序,和24xx读写有较大不同 1。sd2000的访问时序和常用的IIC设备如24CXX有较大不同,SD2000发完命令(相当于24CXX的器件地址)后,就直接开始连续读写了(复位命令后无数据)。而24XX再发完命令后还要发读写地址,如果是写,还要重发START信号,请注意这些不同! 2。特别还要注意,SD2000的数据是低位在先的(命令还是高位在先的),所以收得的数据或发出的数据要处理一下(字节颠倒),而通常大部分IIC设别从头到尾都是高位在先的。 3。最后还要注意以下时序的周期,SD2000最大速率为100K,也就是CLK信号的周期,周期为10us,所以要注意CLK保持高/低电平的时间要>5us,时间长点或长很多是没有问题的。 如果能搞明白sd2000和24xx的访问时序的不同,那将上面的程序修改作访问24xx,因该很简单吧! |
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 没有相关文章 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|