📄 8563.lst
字号:
(0003) //#define F_CPU 8000000
(0004) //#define F_CPU 7372800
(0005) //#define F_CPU 4000000
(0006) /*************************************************************************
(0007) 通用延时头文件:
(0008) delay_nus(n)延时n微秒
(0009) delay_nms(n)延时n毫秒
(0010) *************************************************************************/
(0011) #if F_CPU == 12000000
(0012) void delay_nus(unsigned int time)
(0013) {
(0014) while (time!=0)
(0015) {
(0016) NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();
(0017) time--;
(0018) }
(0019) }
(0020) void delay_nms(unsigned int time)
(0021) {
(0022) unsigned int i;
(0023) while (time!=0)
(0024) {
(0025) for(i=0;i<1740;i++);
(0026) time--;
(0027) }
(0028) }
(0029) #endif
(0030)
(0031) #if F_CPU == 11059200
(0032) void delay_nus(unsigned int time)
(0033) {
_delay_nus:
time --> R16
0150 C009 RJMP 0x015A
(0034) while (time!=0)
(0035) {
(0036) NOP();NOP();NOP();NOP();NOP();NOP();NOP();
0151 0000 NOP
0152 0000 NOP
0153 0000 NOP
0154 0000 NOP
0155 0000 NOP
0156 0000 NOP
0157 0000 NOP
(0037) time--;
0158 5001 SUBI R16,1
0159 4010 SBCI R17,0
015A 3000 CPI R16,0
015B 0701 CPC R16,R17
015C F7A1 BNE 0x0151
015D 9508 RET
_delay_nms:
i --> R20
time --> R16
015E 940E037C CALL push_gset1
(0038) }
(0039) }
(0040) void delay_nms(unsigned int time)
(0041) {
0160 C00B RJMP 0x016C
(0042) unsigned int i;
(0043) while (time!=0)
(0044) {
(0045) for(i=0;i<1580;i++);
0161 2744 CLR R20
0162 2755 CLR R21
0163 C002 RJMP 0x0166
0164 5F4F SUBI R20,0xFF
0165 4F5F SBCI R21,0xFF
0166 324C CPI R20,0x2C
0167 E0E6 LDI R30,6
0168 075E CPC R21,R30
0169 F3D0 BCS 0x0164
(0046) time--;
016A 5001 SUBI R16,1
016B 4010 SBCI R17,0
016C 3000 CPI R16,0
016D 0701 CPC R16,R17
016E F791 BNE 0x0161
016F 940E037F CALL pop_gset1
0171 9508 RET
FILE: H:\bbi项目源程序\8563时钟芯片\8563.c
(0001) /////////////////////////////////////////////////////////////
(0002) // 文件:RT_PCF8563.C //
(0003) // 环境:编译为ICC AVR6.31A,仿真为AVR Studio4.12sp4 //
(0004) // 硬件:ATMEGA16芯片 //
(0005) // 日期:2007年5月28日 //
(0006) // 功能:在LCD12864液晶屏显示时间 //
(0007) // 备注: //
(0008) /////////////////////////////////////////////////////////////
(0009) #include <iom16v.h> //包含单片机型号头文件
(0010) #include <macros.h> //包含"位"操作头文件
(0011) //#include "AVR_XQV12.h"
(0012) #include "lcd.h"
(0013) #include "delay.h" //包含延时头文件
(0014)
(0015) #define rd_device_add 0xa3 //定义器件读地址
(0016) #define wr_device_add 0xa2 //定义器件写地址
(0017) #define START 0x08
(0018) #define MT_SLA_ACK 0x18
(0019) #define MT_DATA_ACK 0x28
(0020) #define RE_START 0x10
(0021) #define MR_SLA_ACK 0x40
(0022) #define MR_DATA_NOACK 0x58
(0023) #define MR_DATA_ACK 0x50
(0024) #define START 0x08
(0025) #define MT_SLA_ACK 0x18
(0026) #define MT_DATA_ACK 0x28
(0027) #define RE_START 0x10
(0028) #define MR_SLA_ACK 0x40
(0029) #define MR_DATA_NOACK 0x58
(0030)
(0031) unsigned char read_shijian[7]={0x02,0x21,0x16,0x24,0x00,0x12,0x27};
(0032) unsigned char write_shijian[7]={0x00,0x48,0x10,0x10,0x00,0x06,0x07};
(0033)
(0034) unsigned char temp[3];
(0035)
(0036)
(0037) /*******************************************************/
(0038) /****** TWI总线操作函数 ******/
(0039) /****** Start(): 总线起始命令 ******/
(0040) /****** Wait(): 等待命令 ******/
(0041) /****** TestAck(): 测试应答 ******/
(0042) /****** Write8Bit():写8位数据 ******/
(0043) /****** Stop(): 总线结束命令 ******/
(0044) /****** Ack(): 应答信号 ******/
(0045) /****** Twi(): 总线使能 ******/
(0046) /*******************************************************/
(0047) void Start(void)
(0048) {TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);}
_Start:
0172 EA84 LDI R24,0xA4
0173 BF86 OUT 0x36,R24
0174 9508 RET
(0049) void Wait(void)
(0050) {while((TWCR&0x80)!=0x80);}
_Wait:
0175 B786 IN R24,0x36
0176 7880 ANDI R24,0x80
0177 3880 CPI R24,0x80
0178 F7E1 BNE 0x0175
0179 9508 RET
(0051) unsigned char TestAck(void)
(0052) {unsigned char twsr;twsr=TWSR&0xf8;return twsr;}
_TestAck:
twsr --> R16
017A B101 IN R16,0x01
017B 7F08 ANDI R16,0xF8
017C 9508 RET
(0053) void Write8Bit(unsigned char data)
(0054) {TWDR=data;TWCR=(1<<TWINT)|(1<<TWEN);}
_Write8Bit:
data --> R16
017D B903 OUT 0x03,R16
017E E884 LDI R24,0x84
017F BF86 OUT 0x36,R24
0180 9508 RET
(0055) void Stop(void)
(0056) {TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);}
_Stop:
0181 E984 LDI R24,0x94
0182 BF86 OUT 0x36,R24
0183 9508 RET
(0057) void Ack(void)
(0058) {TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);}
_Ack:
0184 EC84 LDI R24,0xC4
0185 BF86 OUT 0x36,R24
0186 9508 RET
(0059) void Twi(void)
(0060) {TWCR=(1<<TWINT)|(1<<TWEN);}
_Twi:
0187 E884 LDI R24,0x84
0188 BF86 OUT 0x36,R24
0189 9508 RET
_i2c_Write:
RomAddress --> R22
command --> R20
018A 940E037A CALL push_gset2
018C 2F62 MOV R22,R18
018D 2F40 MOV R20,R16
(0061) /*#####################################################*/
(0062) /*******************************************************/
(0063) /****** 函数名称: i2c_Write() ******/
(0064) /****** 功 能: 向I2C总线写数据 ******/
(0065) /****** 参 数: command--数据内容 ******/
(0066) /****** RomAddress--目标地址 ******/
(0067) /****** 返回值 : 无 ******/
(0068) /*******************************************************/
(0069) unsigned char i2c_Write(unsigned char command,unsigned char RomAddress)
(0070) {
(0071) Start(); //发总线起始命令
018E DFE3 RCALL _Start
(0072) Wait(); //等待应答
018F DFE5 RCALL _Wait
(0073) if(TestAck()!=START)return 1; //测试应答
0190 DFE9 RCALL _TestAck
0191 3008 CPI R16,0x8
0192 F011 BEQ 0x0195
0193 E001 LDI R16,1
0194 C01D RJMP 0x01B2
(0074) Write8Bit(wr_device_add); //写器件地址
0195 EA02 LDI R16,0xA2
0196 DFE6 RCALL _Write8Bit
(0075) Wait(); //等待应答
0197 DFDD RCALL _Wait
(0076) if(TestAck()!=MT_SLA_ACK)return 2; //测试应答
0198 DFE1 RCALL _TestAck
0199 3108 CPI R16,0x18
019A F011 BEQ 0x019D
019B E002 LDI R16,2
019C C015 RJMP 0x01B2
(0077) Write8Bit(RomAddress); //写器件内的寄存器地址
019D 2F06 MOV R16,R22
019E DFDE RCALL _Write8Bit
(0078) Wait(); //等待应答
019F DFD5 RCALL _Wait
(0079) if(TestAck()!=MT_DATA_ACK)return 3; //测试应答
01A0 DFD9 RCALL _TestAck
01A1 3208 CPI R16,0x28
01A2 F011 BEQ 0x01A5
01A3 E003 LDI R16,3
01A4 C00D RJMP 0x01B2
(0080) Write8Bit(command); //写命令
01A5 2F04 MOV R16,R20
01A6 DFD6 RCALL _Write8Bit
(0081) Wait(); //等待应答
01A7 DFCD RCALL _Wait
(0082) if(TestAck()!=MT_DATA_ACK)return 4; //测试应答
01A8 DFD1 RCALL _TestAck
01A9 3208 CPI R16,0x28
01AA F011 BEQ 0x01AD
01AB E004 LDI R16,4
01AC C005 RJMP 0x01B2
(0083) Stop(); //停止总线
01AD DFD3 RCALL _Stop
(0084) delay_nms(10); //延时
01AE E00A LDI R16,0xA
01AF E010 LDI R17,0
01B0 DFAD RCALL _delay_nms
(0085) return 0;
01B1 2700 CLR R16
01B2 940E036E CALL pop_gset2
01B4 9508 RET
_i2c_WriteData:
i --> R20
RomAddress --> R20
01B5 940E037C CALL push_gset1
01B7 2F40 MOV R20,R16
(0086) }
(0087) /*******************************************************/
(0088) /****** 函数名称: i2c_WriteData() ******/
(0089) /****** 功 能: 向I2C总线连续写入7个数据 ******/
(0090) /****** 参 数: RomAddress--目标起始寄存器 ******/
(0091) /****** 返回值 : 无 ******/
(0092) /*******************************************************/
(0093) unsigned char i2c_WriteData(unsigned char RomAddress)
(0094) {
(0095) unsigned char i;
(0096) Start(); //发总线起始命令
01B8 DFB9 RCALL _Start
(0097) Wait(); //等待应答
01B9 DFBB RCALL _Wait
(0098) if(TestAck()!=START)return 1; //测试应答
01BA DFBF RCALL _TestAck
01BB 3008 CPI R16,0x8
01BC F011 BEQ 0x01BF
01BD E001 LDI R16,1
01BE C028 RJMP 0x01E7
(0099) Write8Bit(wr_device_add); //写器件地址
01BF EA02 LDI R16,0xA2
01C0 DFBC RCALL _Write8Bit
(0100) Wait(); //等待应答
01C1 DFB3 RCALL _Wait
(0101) if(TestAck()!=MT_SLA_ACK)return 2; //测试应答
01C2 DFB7 RCALL _TestAck
01C3 3108 CPI R16,0x18
01C4 F011 BEQ 0x01C7
01C5 E002 LDI R16,2
01C6 C020 RJMP 0x01E7
(0102) Write8Bit(RomAddress); //写器件内的寄存器地址
01C7 2F04 MOV R16,R20
01C8 DFB4 RCALL _Write8Bit
(0103) Wait(); //等待应答
01C9 DFAB RCALL _Wait
(0104) if(TestAck()!=MT_DATA_ACK)return 3; //测试应答
01CA DFAF RCALL _TestAck
01CB 3208 CPI R16,0x28
01CC F011 BEQ 0x01CF
01CD E003 LDI R16,3
01CE C018 RJMP 0x01E7
(0105) for(i=0;i<7;i++) //循环7次
01CF 2744 CLR R20
01D0 C00F RJMP 0x01E0
(0106) {
(0107) Write8Bit(write_shijian[i]); //写数据
01D1 E687 LDI R24,0x67
01D2 E090 LDI R25,0
01D3 2FE4 MOV R30,R20
01D4 27FF CLR R31
01D5 0FE8 ADD R30,R24
01D6 1FF9 ADC R31,R25
01D7 8100 LDD R16,Z+0
01D8 DFA4 RCALL _Write8Bit
(0108) Wait(); //等待应答
01D9 DF9B RCALL _Wait
(0109) if(TestAck()!=MT_DATA_ACK)return 4; //测试应答
01DA DF9F RCALL _TestAck
01DB 3208 CPI R16,0x28
01DC F011 BEQ 0x01DF
01DD E004 LDI R16,4
01DE C008 RJMP 0x01E7
01DF 9543 INC R20
01E0 3047 CPI R20,7
01E1 F378 BCS 0x01D1
(0110) }
(0111) Stop(); //停止总线
01E2 DF9E RCALL _Stop
(0112) delay_nms(10); //延时
01E3 E00A LDI R16,0xA
01E4 E010 LDI R17,0
01E5 DF78 RCALL _delay_nms
(0113) return 0;
01E6 2700 CLR R16
01E7 940E037F CALL pop_gset1
01E9 9508 RET
_i2c_Read:
i --> R20
RomAddress --> R20
01EA 940E037C CALL push_gset1
01EC 2F40 MOV R20,R16
(0114) }
(0115) /*******************************************************/
(0116) /****** 函数名称: i2c_Read() ******/
(0117) /****** 功 能: 连续读取I2C总线 ******/
(0118) /****** 参 数: RomAddress--目标寄存器 ******/
(0119) /****** 返回值 : 读出的数据 ******/
(0120) /*******************************************************/
(0121) unsigned char i2c_Read(unsigned char RomAddress)
(0122) {
(0123) unsigned char i;
(0124) Start(); //发总线起始命令
01ED DF84 RCALL _Start
(0125) Wait(); //等待应答
01EE DF86 RCALL _Wait
(0126) if(TestAck()!=START)return 1; //测试应答
01EF DF8A RCALL _TestAck
01F0 3008 CPI R16,0x8
01F1 F011 BEQ 0x01F4
01F2 E001 LDI R16,1
01F3 C035 RJMP 0x0229
(0127) Write8Bit(wr_device_add); //写器件地址
01F4 EA02 LDI R16,0xA2
01F5 DF87 RCALL _Write8Bit
(0128) Wait(); //等待应答
01F6 DF7E RCALL _Wait
(0129) if(TestAck()!=MT_SLA_ACK)return 2; //测试应答
01F7 DF82 RCALL _TestAck
01F8 3108 CPI R16,0x18
01F9 F011 BEQ 0x01FC
01FA E002 LDI R16,2
01FB C02D RJMP 0x0229
(0130) Write8Bit(RomAddress); //写器件内的寄存器地址
01FC 2F04 MOV R16,R20
01FD DF7F RCALL _Write8Bit
(0131) Wait(); //等待应答
01FE DF76 RCALL _Wait
(0132) if(TestAck()!=MT_DATA_ACK)return 3; //测试应答
01FF DF7A RCALL _TestAck
0200 3208 CPI R16,0x28
0201 F011 BEQ 0x0204
0202 E003 LDI R16,3
0203 C025 RJMP 0x0229
(0133) Start(); //重新发总线起始命令
0204 DF6D RCALL _Start
(0134) Wait(); //等待应答
0205 DF6F RCALL _Wait
(0135) if(TestAck()!=RE_START)return 4; //测试应答
0206 DF73 RCALL _TestAck
0207 3100 CPI R16,0x10
0208 F011 BEQ 0x020B
0209 E004 LDI R16,4
020A C01E RJMP 0x0229
(0136) Write8Bit(rd_device_add); //写器件地址
020B EA03 LDI R16,0xA3
020C DF70 RCALL _Write8Bit
(0137) Wait(); //等待应答
020D DF67 RCALL _Wait
(0138) if(TestAck()!=MR_SLA_ACK)return 5; //测试应答
020E DF6B RCALL _TestAck
020F 3400 CPI R16,0x40
0210 F011 BEQ 0x0213
0211 E005 LDI R16,5
0212 C016 RJMP 0x0229
(0139) for(i=0;i<7;i++)
0213 2744 CLR R20
0214 C010 RJMP 0x0225
(0140) {
(0141) Ack(); //发送应答信号
0215 DF6E RCALL _Ack
(0142) Wait(); //等待应答
0216 DF5E RCALL _Wait
(0143) if(TestAck()!=MR_DATA_ACK)return 6; //测试应答
0217 DF62 RCALL _TestAck
0218 3500 CPI R16,0x50
0219 F011 BEQ 0x021C
021A E006 LDI R16,6
021B C00D RJMP 0x0229
(0144) read_shijian[i]=TWDR; //将读取的数据放入数组中
021C E680 LDI R24,0x60
021D E090 LDI R25,0
021E 2FE4 MOV R30,R20
021F 27FF CLR R31
0220 0FE8 ADD R30,R24
0221 1FF9 ADC R31,R25
0222 B023 IN R2,0x03
0223 8220 STD Z+0,R2
0224 9543 INC R20
0225 3047 CPI R20,7
0226 F370 BCS 0x0215
(0145) }
(0146) Stop(); //停止总线
0227 DF59 RCALL _Stop
(0147) return 0;
0228 2700 CLR R16
0229 940E037F CALL pop_gset1
022B 9508 RET
(0148) }
(0149) /*******************************************************/
(0150) /****** 函数名称: ToStr() ******/
(0151) /****** 功 能: 整数转换成字符串 ******/
(0152) /****** 参 数: c--要转换的数据 ******/
(0153) /****** 返回值 : 无 ******/
(0154) /*******************************************************/
(0155) void ToStr(unsigned char c)
(0156) {
(0157) temp[2]=0;
_ToStr:
c --> R16
022C 2422 CLR R2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -