c语言编的DS1302怎么读出和写入数据

c语言编的DS1302怎么读出和写入数据,第1张

这是汇编版的dS1302驱动程序,你可以参考此滚一下。

PUBLIC D1302_INIT,SET1302,GET1302,WRITE,READ

CODE_DS1302 SEGMENT CODE

T_CLK BIT P1.0

T_IO BIT P1.1

T_RST BIT P1.2

SECOND EQU 30H

MINUTE EQU 31H

HOUR EQU 32H

DAY EQU 33H

MONTH EQU 34H

WEEK EQU 35H

YEAR EQU 36H

RSEG CODE_DS1302 使用当前段

以下是DS1302初始化子程序

D1302_INIT: CLR T_RST DS1302复位

CLR T_CLK

NOP

NOP

SETB T_RST

MOV R1,#80H

MOV R0,#00H

LCALL WRITE

MOV R1,#90H

MOV R0,#0ABH

LCALL WRITE

RET

以下是 读 日期时间数据子程序

GET1302: MOV R1,#81H

LCALL READ

MOV SECOND,R0

MOV R1,#83H

LCALL READ

MOV MINUTE,R0

MOV R1,#85H

LCALL READ

MOV HOUR,R0

MOV R1,#87H

LCALL READ

MOV DAY,R0

MOV R1,#89H

LCALL READ

MOV MONTH,R0

MOV R1,#8BH

LCALL READ

MOV WEEK,R0

MOV R1,#8DH

LCALL READ

MOV YEAR,R0

RET

以下是时钟日历写 *** 作子程序(单片机向DS1302写入初始时间)

SET1302: MOV R1,#80H 写 秒

LCALL WRITE

MOV SECOND,R0

MOV R1,#82H 写 分

LCALL WRITE

MOV MINUTE,R0

MOV R1,#84H 写 时

LCALL WRITE

MOV HOUR,R0

MOV R1,#86H 写 天

LCALL WRITE

MOV DAY,R0

MOV R1,#88H 写 月

LCALL WRITE

MOV MONTH,R0

MOV R1,#8AH 写 周

LCALL WRITE

MOV WEEK,R0

MOV R1,#8CH 写 年

LCALL WRITE

MOV YEAR,R0

RET

以下是 写 一个字节地址和数据的子程序

WRITE: CLR T_CLK

NOP

NOP

SETB T_RST

NOP

MOV A,R1

MOV R2,#08H

WRI_01: RRC A

NOP

NOP

CLR T_CLK

NOP

NOP

MOV T_IO,C

NOP

NOP

SETB T_CLK

NOP

NOP

DJNZ R2,WRI_01

CLR T_CLK

NOP

NOP

MOV A,R0

MOV R2,#08H

WRI_02: RRC A

NOP

CLR T_CLK

NOP

NOP

MOV T_IO,C

NOP

NOP

SETB T_CLK

NOP

NOP

DJNZ R2,WRI_02

CLR T_CLK

NOP

NOP

CLR T_RST

NOP

NOP

RET

以下局扒肆是从DS1302读取一字节地址中数据子程序桐轿

READ: CLR T_CLK

NOP

NOP

SETB T_RST

NOP

NOP

MOV A,R1

MOV R2,#08H

READ_01: RRC A

NOP

MOV T_IO,C

NOP

NOP

SETB T_CLK

NOP

NOP

CLR T_CLK

NOP

NOP

DJNZ R2,READ_01

NOP

NOP

SETB T_IO

CLR A

CLR C

MOV R2,#08H

READ_02: CLR T_CLK

NOP

NOP

MOV C,T_IO

NOP

NOP

RRC A

NOP

NOP

SETB T_CLK

NOP

NOP

DJNZ R2,READ_02

MOV R0,A

CLR T_RST

RET

END

//首次使用时下载该程序后,调节实验箱最下面的W1液晶对比度调节电位器,使液晶显示最弊颂佳。

#include <reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

/*12864端口定义*/

#define LCD_data P0 //数据口

sbit LCD_RS = P3^5 //寄存器选择输入蠢拆

sbit LCD_RW = P3^6 //液晶读/写控制

sbit LCD_EN = P3^4 //液晶使能控制

sbit LCD_PSB = P3^7 //串/并方式控制

sbit wela= P2^6

sbit dula= P2^7

sbit beep=P2^3

sbit dscs=P1^4

sbit dsas=P1^5

sbit dsrw=P1^6

sbit dsds=P1^7

sbit dsirq=P3^3

bit flag1,flag_ri

uchar count,s1num,flag,t0_num,num,mm

char miao,shi,fen,year,month,day,week,amiao,afen,ashi

void write_ds(uchar,uchar)

void lcd_wdat(uchar)

void set_time()

#define delayNOP(){_nop_()_nop_()_nop_()_nop_()}

//uchar IRDIS[2]

//uchar IRCOM[4]

void delay0(uchar x) //x*0.14MS

//void beep()

void lcm_word(uchar *str)

void write_ds(uchar,uchar)

uchar read_ds(uchar)

void dataconv()

void lcd_pos(uchar X,uchar Y) //确定显示位置

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

/* */

/* 延时函数 */

/* */

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

void delay(int ms)

{

while(ms--)

{

uchar i

for(i=0i<250i++)

{

_nop_()

_nop_()

_nop_()

_nop_()

}

}

}

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

/* */

/*检查LCD忙状态*/

/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */

/* */

/带卜枣*******************************************************************/

bit lcd_busy()

{

bit result

LCD_RS = 0

LCD_RW = 1

LCD_EN = 1

delayNOP()

result = (bit)(P0&0x80)

LCD_EN = 0

return(result)

}

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

/* */

/*写指令数据到LCD */

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */

/* */

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

void lcd_wcmd(uchar cmd)

{

while(lcd_busy())

LCD_RS = 0

LCD_RW = 0

LCD_EN = 0

_nop_()

_nop_()

P0 = cmd

delayNOP()

LCD_EN = 1

delayNOP()

LCD_EN = 0

}

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

/*显示数字*/

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

void write_sfm(uchar add,uchar date)//时,分,秒

{

uchar shi,ge

shi=date/10

ge=date%10

lcd_wcmd(0x98+add)

lcd_wdat(0x30+shi)

lcd_wdat(0x30+ge)

}

void write_nyr(uchar add,uchar date) //年,月,日

{

uchar shi,ge

shi=date/10

ge=date%10

lcd_wcmd(0x89+add)

lcd_wdat(0x30+shi)

lcd_wdat(0x30+ge)

}

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

/*转成汉字显示*/

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

void lcm_word(unsigned char *str)

{

while(*str!='\0')

{

//lcd_wcmd(0x9f)

lcd_wdat(*str++)

}

*str=0

}

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

/*星期处理*/

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

void lcm_xingqi(void)

{

uchar sel

sel=read_ds(6) //将DS12C887星期数赋给sel

lcd_wcmd(0x9f) //星期显示位置

if(sel==7)

{

lcm_word("日")

//lcd_wdat(0xc8) //星期日

//lcd_wdat(0xd5)

}

if(sel==6)

{

lcm_word("六")

//lcd_wdat(0xc1) //星期六

//lcd_wdat(0xf9)

}

if(sel==5)

{

lcm_word("五")

//lcd_wdat(0xce) //星期五

//lcd_wdat(0xc4)

}

if(sel==4)

{

lcm_word("四")

//lcd_wdat(0xcb) //星期四

//lcd_wdat(0xd5)

}

if(sel==3)

{

//lcm_word("三")

lcd_wdat(0xc8) //星期三

lcd_wdat(0xfd)

}

if(sel==2)

{

lcm_word("二")

//lcd_wdat(0xb6) //星期二

//lcd_wdat(0xfe)

}

if(sel==1)

{

lcm_word("一")

//lcd_wdat(0xd2) //星期一

// lcd_wdat(0xbb)

}

}

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

/* */

/*写显示数据到LCD */

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */

/* */

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

void lcd_wdat(uchar dat)

{

while(lcd_busy())

LCD_RS = 1

LCD_RW = 0

LCD_EN = 0

P0 = dat

delayNOP()

LCD_EN = 1

delayNOP()

LCD_EN = 0

}

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

/* */

/* LCD初始化设定 */

/* */

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

void lcd_init()

{

//uchar i

LCD_PSB = 1//并口方式

write_ds(0x0a,0x20)//打开振荡器;

write_ds(0x0b,0x26)

//set_time() //在第一次设置12C887时打开

lcd_wcmd(0x34) //扩充指令 *** 作

delay(5)

lcd_wcmd(0x30) //基本指令 *** 作

delay(5)

lcd_wcmd(0x0C) //显示开,关光标

delay(5)

lcd_wcmd(0x01) //清除LCD的显示内容

delay(5)

/*lcd_wcmd(0x88)

for(i = 0i <10i++)

lcd_wdat(dis3[i])*/

}

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

/* DS12C887时钟芯片写指令*/

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

void write_ds(uchar add,uchar date)

{

dscs=0

dsas=1

dsds=1

dsrw=1

P0=add

dsas=0

dsrw=0

P0=date

dsrw=1

dsas=1

dscs=1

}

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

/* DS12C887读指令*/

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

uchar read_ds(uchar add)

{

uchar ds_date

dsas=1

dsds=1

dsrw=1

dscs=0

P0=add

dsas=0

dsds=0

P0=0xff

ds_date=P0

dsds=1

dsas=1

dscs=1

return ds_date

}

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

/*向DS12c887内写数据*/

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

void set_time()

{

write_ds(0,50)//秒

write_ds(1,0)//秒闹铃

write_ds(2,18)//分

write_ds(3,0)//分闹铃

write_ds(4,7)//时

write_ds(5,0)//时闹铃

write_ds(6,1)//星期

write_ds(7,11)//日

write_ds(8,10)//月

write_ds(9,10)//年

}

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

/* */

/* 主程序 */

/* */

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

main()

{

uchar i

delay(10)//延时

wela=0

dula=0

lcd_init() //初始化LCD

while(1)

{

//xs()

days()

lcd_pos(1,0)//设置显示位置为第二行的第1个字符

i = 0

while(dis2[i] != '\0')

{

lcd_wdat(dis2[i]) //显示字符

i++

}

//lcd_wcmd(0x89)//设置显示位置为第三行的第1个字符

year=read_ds(9)

month=read_ds(8)

day=read_ds(7)

week=read_ds(6)

shi=read_ds(4)

fen=read_ds(2)

miao=read_ds(0)

lcd_wcmd(0x88)

lcd_wdat(0x32)

lcd_wdat(0x30)

write_nyr(0,year)

lcd_wdat(0xc4)

lcd_wdat(0xea)

write_nyr(2,month)

lcd_wdat(0xd4)

lcd_wdat(0xc2)

write_nyr(4,day)

lcd_wdat(0xc8)

lcd_wdat(0xd5)

//lcd_wdat(0xc8)

//lcd_wdat(0xd5)

write_sfm(4,miao)

write_sfm(2,fen)

lcd_wdat(0x3a)

lcd_wdat(0x3a)

write_sfm(0,shi)

lcd_wdat(0x3a)

lcd_wdat(0x3a)

lcd_wcmd(0x9d)

lcd_wdat(0xd0)

lcd_wdat(0xc7)

lcd_wdat(0xc6)

lcd_wdat(0xda)

//write_sfm(7,week)

lcd_wcmd(0x9f)

lcm_xingqi()

}

}

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

/* */

/* 延时x*0.14ms子程序 */

/* */

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

void delay0(uchar x)//x*0.14MS

{

uchar i

while(x--)

{

for (i = 0i<13i++) {}

}

}

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

/* */

/* 设定显示位置 */

/* */

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

void lcd_pos(uchar X,uchar Y)

{

uchar pos

if (X==0)

{X=0x80}

else if (X==1)

{X=0x90}

else if (X==2)

{X=0x88}

else if (X==3)

{X=0x98}

pos = X+Y

lcd_wcmd(pos)//显示地址

}

数字喊毁电位器用的是X9C103

#include<reg51.h>

#include<stdio.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

//郑差备设定四个按键

sbit X9C102=P2^0

sbit X9C202=P2^1

sbit X9C302=P2^2

sbit X9C402=P2^3

sbit X9C103_CS=P1^0

sbit X9C103_INC=P1^1

sbit X9C103_UD=P1^2

void delay_nus(uint i)

{

while(i--)

}

void delay_nms(uchar i)

{

for(ii>0i++)

{

delay_nus(1000)

}

}

void set_x9c103(uchar num,uchar ud,uchar save)

{

X9C103_CS=0

delay_nus(1)

if(ud==1)

{

X9C103_UD=1

}

else

{

X9C103_UD=0

}

delay_nus(4)

for(numnum>0num--)

{

X9C103_INC=1

delay_nus(2)

X9C103_INC=0

delay_nus(2)

}

delay_nus(2)

if(save==1)

{

X9C103_INC=1

delay_nus(2)

X9C103_CS=1

delay_nms(22)

}

X9C103_CS=1

delay_nus(10)

}

void clear_down()

{

set_x9c103(100,0,1)

}

void main_init()

{

X9C103_CS=0

clear_down()

}

void main()

{

main_init()

set_x9c103(70,1,1)

while(1)//扫描按庆拍键,对应不同倍数的输出

{

if (X9C102==0){

clear_down()

set_x9c103(10,1,1)}

if (X9C202==0){

clear_down()

set_x9c103(30,1,1)}

if (X9C302==0){

clear_down()

set_x9c103(60,1,1)}

if (X9C402==0){

clear_down()

set_x9c103(90,1,1)}

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/8268951.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存