📄 time_1302.lst
字号:
__text_start:
__start:
004A E5CF LDI R28,0x5F
004B E0D2 LDI R29,2
004C BFCD OUT 0x3D,R28
004D BFDE OUT 0x3E,R29
004E 51C0 SUBI R28,0x10
004F 40D0 SBCI R29,0
0050 EA0A LDI R16,0xAA
0051 8308 STD Y+0,R16
0052 2400 CLR R0
0053 E8E9 LDI R30,0x89
0054 E0F0 LDI R31,0
0055 E010 LDI R17,0
0056 39E1 CPI R30,0x91
0057 07F1 CPC R31,R17
0058 F011 BEQ 0x005B
0059 9201 ST R0,Z+
005A CFFB RJMP 0x0056
005B 8300 STD Z+0,R16
005C E6EB LDI R30,0x6B
005D E0F0 LDI R31,0
005E E6A0 LDI R26,0x60
005F E0B0 LDI R27,0
0060 E010 LDI R17,0
0061 39E4 CPI R30,0x94
0062 07F1 CPC R31,R17
0063 F021 BEQ 0x0068
0064 95C8 LPM
0065 9631 ADIW R30,1
0066 920D ST R0,X+
0067 CFF9 RJMP 0x0061
0068 D19F RCALL _main
_exit:
0069 CFFF RJMP _exit
_DelaymS:
j --> R20
k --> R22
i --> R16
006A D1EA RCALL push_gset2
FILE: E:\iccavr代码\实验6_实时时钟DS1302\time-1302.c
(0001) //******************************************************************************
(0002) // *
(0003) // FileName : 实验板time_1302.c ICCAVR V6.31A编译 *
(0004) // Function : 实时时钟DS1302的读写操作应用 *
(0005) // Date : 2007-01-16 *
(0006) // Version : 1.0 *
(0007) // *
(0008) // Author : 开关电源 hongtusy@163.com *
(0009) // Company : 电子信息技术咨询网 http://www.itsn.cn *
(0010) // *
(0011) //***************************描述与记事*****************************************
(0012) //实验板的AVR程序,实时时钟DS1302应用,将实时时间通过串口打印到PC机上,并通过1602LCD
(0013) //显示出来。只要不在主电源掉电下拆除电池,LCD将可以一直显示当前的实时时间。
(0014) //接线定义:串口PD0(SW6-7)-RXD PD1(SW6-8)-TXD ,SW3-8为系统复位端。
(0015) // SW5-1=PA3时钟CLK,SW5-2=PA4数据DAT,SW5-3=PA5复位RET。
(0016) //PC(SW1-1~8)为LCD数据端,PD4(SW2-1),5(SW2-2),6(SW2-3) 为RS,R/W,EA脚 SW2-5为背光开关。
(0017) //记事:本程序旨在对1302驱动的理解与演示,程序适合初学者使用.
(0018) // 打开串口调试器(可能不能显示汉字)或windows自带的超级终端,调整波特率为9600bps,
(0019) // 即可用PC观察到当前的时间和日期。
(0020) //本例子使用片外8MHz晶体(注意熔丝位的设置)。默认使用ATmega8535作处理器。
(0021) //秒寄存器的最高位在开机时默认是1,代表时钟振荡器停止,必须将其改为0后方可启动时钟。
(0022) //******************************************************************************
(0023)
(0024) #include <iom8535v.h> //头文件,ATmega8535单片机的寄存器定义
(0025) #include <macros.h> //包含有SEI()、CLI()、NOP()、WDR()、等宏定义.
(0026)
(0027) typedef unsigned char uchar; //数据类型说明
(0028) typedef unsigned int uint; //数据类型说明
(0029)
(0030) uchar buf_time[]=" Day:2007-01-16 Time: 00:00:00 "; //LCD显示用的数组
(0031)
(0032) uchar buf_read[8]; //从DS1302读出的时间数据,数据格式为:秒 分 时 日 月 星期 年 写保护字节
(0033) uchar buf_write[8]={0x01,0x20,0x01,0x16,0x01,0x02,0x07,0x00}; //往DS1302写入的时间数据
(0034) // 数据格式为:01秒 20分 01时 16日 01月 02星期 07年 00写保护字节
(0035)
(0036) /************************************************
(0037) 函 数 名: DelaymS()
(0038) 功 能: 毫秒级延时函数
(0039) 输入参数: 延迟时间/系统晶体
(0040) 输出参数: 做相应的延迟处理
(0041) 描 述: /
(0042) ***********************************************/
(0043) void DelaymS (uint i) //延时函数,参数i为延时时间
(0044) {
(0045) uint j,k; //双重延时
(0046) for (j=0;j<i;j++)
006B 2744 CLR R20
006C 2755 CLR R21
006D C00C RJMP 0x007A
(0047) {
(0048) for (k=0;k<=500;k++);
006E 2766 CLR R22
006F 2777 CLR R23
0070 C002 RJMP 0x0073
0071 5F6F SUBI R22,0xFF
0072 4F7F SBCI R23,0xFF
0073 EF84 LDI R24,0xF4
0074 E091 LDI R25,1
0075 1786 CP R24,R22
0076 0797 CPC R25,R23
0077 F7C8 BCC 0x0071
0078 5F4F SUBI R20,0xFF
0079 4F5F SBCI R21,0xFF
007A 1740 CP R20,R16
007B 0751 CPC R21,R17
007C F388 BCS 0x006E
007D D1CF RCALL pop_gset2
007E 9508 RET
_write_data:
h --> R20
007F D1D7 RCALL push_gset1
0080 2F40 MOV R20,R16
(0049) }
(0050) }
(0051) /********************************************************
(0052) 子程序名: write_data()
(0053) 功 能: 写入一字节LCD数据
(0054) 输入参数: /
(0055) 输出参数: /
(0056) 描 述: /
(0057) ********************************************************/
(0058) void write_data(uchar h)
(0059) {
(0060) PORTC = h; //先将数据送出
0081 BB45 OUT 0x15,R20
(0061) PORTD |= (1<<PD4); //RS=1,数据
0082 9A94 SBI 0x12,4
(0062) PORTD &= ~(1<<PD5); //R/W=0,写
0083 9895 CBI 0x12,5
(0063) PORTD &= ~(1<<PD6); //EN=0 ,使能,产生一个下降沿。
0084 9896 CBI 0x12,6
(0064) DelaymS (1);
0085 E001 LDI R16,1
0086 E010 LDI R17,0
0087 DFE2 RCALL _DelaymS
(0065) PORTD |= (1<<PD6); //EN=1 ,除能
0088 9A96 SBI 0x12,6
0089 D1D0 RCALL pop_gset1
008A 9508 RET
_write_code:
h --> R20
008B D1CB RCALL push_gset1
008C 2F40 MOV R20,R16
(0066) }
(0067) /********************************************************
(0068) 子程序名: write_code()
(0069) 功 能: 写入一字节LCD指令/地址
(0070) 输入参数: /
(0071) 输出参数: /
(0072) 描 述: /
(0073) ********************************************************/
(0074) void write_code(uchar h)
(0075) {
(0076) PORTC = h; //先将地址送出
008D BB45 OUT 0x15,R20
(0077) PORTD &= ~(1<<PD4); //RS=0,命令或数据
008E 9894 CBI 0x12,4
(0078) PORTD &= ~(1<<PD5); //R/W=0,写
008F 9895 CBI 0x12,5
(0079) PORTD &= ~(1<<PD6); //EN=0 ,使能,产生一个下降沿。
0090 9896 CBI 0x12,6
(0080) DelaymS (1);
0091 E001 LDI R16,1
0092 E010 LDI R17,0
0093 DFD6 RCALL _DelaymS
(0081) PORTD |= (1<<PD6); //EN=1 ,除能
0094 9A96 SBI 0x12,6
0095 D1C4 RCALL pop_gset1
0096 9508 RET
(0082) }
(0083) /********************************************************
(0084) 子程序名: init_lcd()
(0085) 功 能: 初始化LCD
(0086) 输入参数: /
(0087) 输出参数: /
(0088) 描 述: /
(0089) ********************************************************/
(0090) void init_lcd(void)
(0091) {
(0092) write_code(0x01); //清除屏幕
_init_lcd:
0097 E001 LDI R16,1
0098 DFF2 RCALL _write_code
(0093) write_code(0x38); //功能设定,8位数据口/2行/5*7的点阵
0099 E308 LDI R16,0x38
009A DFF0 RCALL _write_code
(0094) write_code(0b00001111); //显示幕ON,光标ON,闪烁ON
009B E00F LDI R16,0xF
009C DFEE RCALL _write_code
(0095) write_code(0x06); //模式,加1,显示幕ON。
009D E006 LDI R16,6
009E DFEC RCALL _write_code
(0096) write_code(0b00000011); //光标回到原点
009F E003 LDI R16,3
00A0 DFEA RCALL _write_code
00A1 9508 RET
_display_lcd:
i --> R20
p --> R22
00A2 D1B2 RCALL push_gset2
00A3 01B8 MOVW R22,R16
(0097) }
(0098) /********************************************************
(0099) 子程序名: display_lcd()
(0100) 功 能: 刷新显示一屏数据,独立的LCD显示程序,用户将显存内容更新后,只要调用此程序即可更新显示。
(0101) 输入参数: /
(0102) 输出参数: /
(0103) 描 述: 在写一个字符前,先设定显示的位置地址,然后再写数据。系统可以自动地址加一。
(0104) ********************************************************/
(0105) void display_lcd(uchar *p)
(0106) {
(0107) uchar i;
(0108) write_code(0x80); //第一行起始地址,0b10000000B=0x80.
00A4 E800 LDI R16,0x80
00A5 DFE5 RCALL _write_code
(0109) for(i=0;i<16;i++)
00A6 2744 CLR R20
00A7 C007 RJMP 0x00AF
(0110) {
(0111) write_data(p[i]);
00A8 2FE4 MOV R30,R20
00A9 27FF CLR R31
00AA 0FE6 ADD R30,R22
00AB 1FF7 ADC R31,R23
00AC 8100 LDD R16,Z+0
00AD DFD1 RCALL _write_data
00AE 9543 INC R20
00AF 3140 CPI R20,0x10
00B0 F3B8 BCS 0x00A8
(0112) }
(0113) write_code(0xc0); //第二行起始地址,0b11000000B=0xc0.
00B1 EC00 LDI R16,0xC0
00B2 DFD8 RCALL _write_code
(0114) for(i=16;i<32;i++)
00B3 E140 LDI R20,0x10
00B4 C007 RJMP 0x00BC
(0115) {
(0116) write_data(p[i]);
00B5 2FE4 MOV R30,R20
00B6 27FF CLR R31
00B7 0FE6 ADD R30,R22
00B8 1FF7 ADC R31,R23
00B9 8100 LDD R16,Z+0
00BA DFC4 RCALL _write_data
00BB 9543 INC R20
00BC 3240 CPI R20,0x20
00BD F3B8 BCS 0x00B5
00BE D18E RCALL pop_gset2
00BF 9508 RET
_InputByte:
i --> R20
CD --> R22
00C0 D194 RCALL push_gset2
00C1 2F60 MOV R22,R16
(0117) }
(0118) }
(0119) /************************************************
(0120) 函 数 名: InputByte()
(0121) 功 能: 串行写入1字节的数据函数
(0122) 输入参数: /
(0123) 输出参数: /
(0124) 描 述: PA4为数据端,PA3为时钟端,bit0在先,时钟上升沿写入。
(0125) ***********************************************/
(0126) void InputByte (uchar CD)
(0127) {
(0128) uchar i;
(0129) for(i=0;i<8;i++)
00C2 2744 CLR R20
00C3 C00C RJMP 0x00D0
(0130) {
(0131) if((CD & (1<<i))==0)
00C4 E001 LDI R16,1
00C5 2F14 MOV R17,R20
00C6 D1A7 RCALL lsl8
00C7 2E26 MOV R2,R22
00C8 2220 AND R2,R16
00C9 F411 BNE 0x00CC
(0132) PORTA &= ~(1<<PA4); //数据端输出0
00CA 98DC CBI 0x1B,4
00CB C001 RJMP 0x00CD
(0133) else
(0134) PORTA |= (1<<PA4); //否则输出1
00CC 9ADC SBI 0x1B,4
(0135) PORTA |= (1<<PA3); //时钟置高,产生上升沿。
00CD 9ADB SBI 0x1B,3
(0136) PORTA &= ~(1<<PA3); //时钟置低
00CE 98DB CBI 0x1B,3
00CF 9543 INC R20
00D0 3048 CPI R20,0x8
00D1 F390 BCS 0x00C4
00D2 D17A RCALL pop_gset2
00D3 9508 RET
_OutputByte:
mid --> R20
i --> R22
00D4 D180 RCALL push_gset2
(0137) }
(0138) }
(0139) /************************************************
(0140) 函 数 名: OutputByte
(0141) 功 能: 从DS1302串行读出1字节的数据函数
(0142) 输入参数: /
(0143) 输出参数: /
(0144) 描 述: PA4为数据端,PA3为时钟端,bit0在先,时钟下降沿读出。
(0145) ***********************************************/
(0146) uchar OutputByte (void)
(0147) {
(0148) uchar i,mid=0;
00D5 2744 CLR R20
(0149) for(i=0;i<8;i++)
00D6 2766 CLR R22
00D7 C010 RJMP 0x00E8
(0150) {
(0151) if((PINA & 0x10)==0) //操作的是PA4
00D8 99CC SBIC 0x19,4
00D9 C007 RJMP 0x00E1
(0152) {
(0153) mid &= ~(1<<i); //读取0
00DA E001 LDI R16,1
00DB 2F16 MOV R17,R22
00DC D191 RCALL lsl8
00DD 2E20 MOV R2,R16
00DE 9420 COM R2
00DF 2142 AND R20,R2
(0154) }
00E0 C004 RJMP 0x00E5
(0155) else
(0156) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -