?? 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 + -