#include#include"ds1302.h" #include"oled.h" /*实验要求 :开发板上XJ8 PS/2与DS1302,要用跳线帽短接到DS1302_CLK 和 DS1302_IO */ // DDR 数据 方向 寄存器; // ODR 输出 数据 寄存器; // IDR 输入引脚 寄存器; // CR1 控制寄存器1; // CR2 控制寄存器2; #define DS1302_IO_OUT PB_ODR_ODR2 //DS1302输入输出端口(输出) #define DS1302_IO_IN PB_IDR_IDR2 //DS1302输入输出端口(输入) #define DS1302_SCK PB_ODR_ODR3 //DS1302时钟端口 #define DS1302_RST PB_ODR_ODR4 //DS1302复位端口 /***********************用户自定义数据区域***********************/ u8 table1[]="==System init==";//LCD1602显示字符串数组1显示效果用 #define DS1302_sec_add 0x80 //秒 数据地址 #define DS1302_min_add 0x82 //分 数据地址 #define DS1302_hr_add 0x84 //时 数据地址 #define DS1302_date_add 0x86 //日 数据地址 #define DS1302_month_add 0x88 //月 数据地址 #define DS1302_day_add 0x8A //星 期数据地址 #define DS1302_year_add 0x8C //年 数据地址 #define DS1302_control_add 0x8e //控制 数据地址 #define DS1302_charger_add 0x90 #define DS1302_clkburst_add 0xbe // 定义 变量; //初始时间2010年6月1号23点59分55秒 星期二 u8 time_buf[8]={0x20,0x95,0x012,0x31,0x23,0x59,0x55,0x03}; u8 dis_time_buf[16] = {0}; u8 *WEEK[] = {"SUN", "MON", "TUS", "WEN", "THU", "FRI", "SAT"}; void DS1302_Time_Now(void) { DS1302_UPDATA(); OLED_ShowChar(32 , 2 , '/'); OLED_ShowChar(56 , 2 , '/'); OLED_ShowChar(16 , 4 , ':'); OLED_ShowChar(40 , 4 , ':'); // 年 OLED_ShowChar(0 , 2 , dis_time_buf[0] +'0'); OLED_ShowChar(8 , 2 , dis_time_buf[1] +'0'); OLED_ShowChar(16 , 2 , dis_time_buf[2] +'0'); OLED_ShowChar(24 , 2 , dis_time_buf[3] +'0'); // 月 OLED_ShowChar(40 , 2 , dis_time_buf[4] +'0'); // 月 高位; OLED_ShowChar(48 , 2 , dis_time_buf[5] +'0'); // 月 低位; // 日 OLED_ShowChar(64 , 2 , dis_time_buf[6] +'0'); OLED_ShowChar(72 , 2 , dis_time_buf[7] +'0'); // 时 OLED_ShowChar(0 , 4 , dis_time_buf[8] +'0'); OLED_ShowChar(8 , 4 , dis_time_buf[9] +'0'); // 分 OLED_ShowChar(24 , 4 , dis_time_buf[10] +'0'); OLED_ShowChar(32 , 4 , dis_time_buf[11] +'0'); // 秒 OLED_ShowChar(48 , 4 , dis_time_buf[12] +'0'); OLED_ShowChar(56 , 4 , dis_time_buf[13] +'0'); // 周 OLED_ShowString(88 , 2 , WEEK[dis_time_buf[14]]); } /****************************************************************/ //延时函数Delay_Nms(),有形参Count用于控制延时函数执行次数,无返回值 /****************************************************************/ void Delay_Nms(u16 Count)//延时函数 { u8 i,j; while (Count--)//Count形参控制延时次数 { for(i=0; i<50; i++) for(j=0; j<20; j++); } } /****************************************************************/ //DS1302初始化函数DS1302_init(),无形参,无返回值 /****************************************************************/ void DS1302_init(void) { DS1302_RST=0; //DS1302_RST脚置低 DS1302_SCK=0; //DS1302_SCK脚置低 } /**************************************************************** void DS1302_Reset(void) 无形参,无 返回值 ****************************************************************/ void DS1302_Reset(void) { DS1302_SCK=0; //DS1302_SCK脚置 低 DS1302_RST=0; //DS1302_RST脚置 低 DS1302_RST=1; //DS1302_RST脚置 高 } /**************************************************************** //DS1302芯片IO引脚方向性配置函数DS1302_IO_DDR(), 有形参ddr无返回值 ****************************************************************/ void DS1302_IO_DDR(u8 ddr) { if(ddr == 1) //配置为 输出方式 { PB_DDR_DDR2= 1; //配置PC1引脚为输出引脚 PB_CR1_C12 = 1; //配置PC1引脚为推挽输出模式 PB_CR2_C22 = 0; //配置PC1引脚低速率输出模式 } else //配置为 输入方式 { PB_DDR_DDR2= 0; //配置PC1引脚为输入引脚 PB_CR1_C12 = 1; //配置PC1引脚为弱上拉输入模式 PB_CR2_C22 = 0; //禁止PC1引脚外部中断功能 } } /**************************************************************** //向DS1302写入一字节数据函数DS1302_write_byte(u8 addr, u8 data) //有形参addr、data,无返回值 指定地址,写入 1 字节(8位) ****************************************************************/ void DS1302_write_byte(u8 addr, u8 data) { u8 i; DS1302_IO_DDR(1); //配置DS1302_IO引脚为输出方式 DS1302_RST=1; //启动DS1302总线 //写入目标地址:addr addr = addr & 0xFE;//最低位置零,寄存器0位为0时写,为1时读 1111 1110 for(i=0; i<8; i++) { if(addr & 0x01) DS1302_IO_OUT = 1; else DS1302_IO_OUT = 0; DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; addr = addr >> 1; } //写入数据:data for(i=0; i<8; i++) { if(data & 0x01) DS1302_IO_OUT = 1; else DS1302_IO_OUT = 0; DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; data = data >> 1; } DS1302_RST=0; //停止DS1302总线 } /**************************************************************** //从DS1302读出一字节数据函数DS1302_read_byte(u8 addr) //有形参addr,有返回值 指定地址,读出 1 字节(8位) ****************************************************************/ u8 DS1302_read_byte(u8 addr) { u8 i,temp; //i为循环控制变量,temp为读取回单片机的数据 DS1302_IO_DDR(1); //配置DS1302_IO引脚为输出方式 DS1302_RST = 1; //启动DS1302总线 //写入目标地址:addr addr=addr|0x01; //最低位置高,寄存器0位为0时写,为1时读 for(i=0;i<8;i++) { if(addr&0x01) //送出地址 DS1302_IO_OUT=1; else DS1302_IO_OUT=0; DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; addr = addr >> 1; } //输出数据:temp DS1302_IO_DDR(0); //配置DS1302_IO引脚为输入方式 for(i=0;i<8;i++) { temp=temp >> 1; if(DS1302_IO_IN) //取回IO线路状态 temp |= 0x80; //数据位为“1”时 else temp &= 0x7F; //数据位为“0”时 DS1302_SCK = 1; //产生时钟 DS1302_SCK = 0; } DS1302_RST = 0; //停止 DS1302 总线 return temp; //返回读取数据temp } /**************************************************************** //向 DS1302 写入时钟数据函数 DS1302_write_time(), 无形参, 无返回值 ****************************************************************/ void DS1302_write_time(void) { DS1302_write_byte(DS1302_control_add, 0x00); //关闭写保护 DS1302_write_byte(DS1302_sec_add, 0x80); //暂停时钟 //DS1302_write_byte(DS1302_charger_add, 0xa9); //涓流充电 DS1302_write_byte(DS1302_year_add, time_buf[1]); //年 DS1302_write_byte(DS1302_month_add, time_buf[2]); //月 DS1302_write_byte(DS1302_date_add, time_buf[3]); //日 DS1302_write_byte(DS1302_hr_add, time_buf[4]); //时 DS1302_write_byte(DS1302_min_add, time_buf[5]); //分 DS1302_write_byte(DS1302_sec_add, time_buf[6]); //秒 DS1302_write_byte(DS1302_day_add, time_buf[7]); //周 DS1302_write_byte(DS1302_control_add, 0x80); //打开写保护 } /**************************************************************** //从DS302读出时钟数据函数DS1302_read_time(), 无形参, 无返回值 ****************************************************************/ void DS1302_read_time(void) { time_buf[1] = DS1302_read_byte(DS1302_year_add); //年 time_buf[2] = DS1302_read_byte(DS1302_month_add); //月 time_buf[3] = DS1302_read_byte(DS1302_date_add); //日 time_buf[4] = DS1302_read_byte(DS1302_hr_add); //时 time_buf[5] = DS1302_read_byte(DS1302_min_add); //分 time_buf[6] = (DS1302_read_byte(DS1302_sec_add)) & 0x7f; //秒,屏蔽秒的第7位,避免超出 59 time_buf[7] = DS1302_read_byte(DS1302_day_add); //周 } /**************************************************************** //1602液晶显示DS1302时间函数Display(),无形参,无返回值 void Display(void) { //LCD1602第1行显示内容 LCD1602_DIS_CHAR(1,0,dis_time_buf[0]+'0'); LCD1602_DIS_CHAR(1,1,dis_time_buf[1]+'0'); LCD1602_DIS_CHAR(1,2,dis_time_buf[2]+'0'); LCD1602_DIS_CHAR(1,3,dis_time_buf[3]+'0'); LCD1602_DIS_CHAR(1,4,'-'); LCD1602_DIS_CHAR(1,5,dis_time_buf[4]+'0'); LCD1602_DIS_CHAR(1,6,dis_time_buf[5]+'0'); LCD1602_DIS_CHAR(1,7,'-'); LCD1602_DIS_CHAR(1,8,dis_time_buf[6]+'0'); LCD1602_DIS_CHAR(1,9,dis_time_buf[7]+'0'); LCD1602_DIS_CHAR(1,10,'-'); LCD1602_DIS_CHAR(1,11,'W'); LCD1602_DIS_CHAR(1,12,'e'); LCD1602_DIS_CHAR(1,13,'e'); LCD1602_DIS_CHAR(1,14,'k'); LCD1602_DIS_CHAR(1,15,dis_time_buf[14]+'0'); //LCD1602第2行显示内容 LCD1602_DIS_CHAR(2,4,dis_time_buf[8]+'0'); LCD1602_DIS_CHAR(2,5,dis_time_buf[9]+'0'); LCD1602_DIS_CHAR(2,6,':'); LCD1602_DIS_CHAR(2,7,dis_time_buf[10]+'0'); LCD1602_DIS_CHAR(2,8,dis_time_buf[11]+'0'); LCD1602_DIS_CHAR(2,9,':'); LCD1602_DIS_CHAR(2,10,dis_time_buf[12]+'0'); LCD1602_DIS_CHAR(2,11,dis_time_buf[13]+'0'); } ****************************************************************/ /**************************************************************** //DS1302时间更新函数 DS1302_UPDATA(), 无形参, 无返回值 ****************************************************************/ void DS1302_UPDATA(void) { DS1302_read_time(); //读取时间 dis_time_buf[0] = (time_buf[0] >> 4); //年 00-99 dis_time_buf[1] = (time_buf[0] & 0x0F); dis_time_buf[2] = (time_buf[1] >> 4); // 取 高 4 位; dis_time_buf[3] = (time_buf[1] & 0x0F); // 取 低 4 位; /****************************************/ dis_time_buf[4] = (time_buf[2]>>4); //月 dis_time_buf[5] = (time_buf[2]&0x0F); /****************************************/ dis_time_buf[6] = (time_buf[3]>>4); //日 dis_time_buf[7] = (time_buf[3]&0x0F); /****************************************/ dis_time_buf[14] = (time_buf[7] & 0x07); //星期 /****************************************/ dis_time_buf[8] = (time_buf[4] >> 4); //时 dis_time_buf[9] = (time_buf[4] & 0x0F); /****************************************/ dis_time_buf[10] = (time_buf[5] >> 4); //分 dis_time_buf[11] = (time_buf[5] & 0x0F); /****************************************/ dis_time_buf[12] = (time_buf[6] >> 4); //秒 dis_time_buf[13] = (time_buf[6] & 0x0F); }
操作DS1302的大致过程,
将各种数据 写入 DS1302的寄存器,以设置它当前的时间格式;
然后使DS1302开始运作,DS1302时钟会按照设置情况运转;
再用单片机将其寄存器内的数据读出。再用液晶显示,就是我们常说的简易电子钟。
联系人:客服在线
手机:全工:13903011251
电话:李R:13530006400
邮箱:729986191@qq.com
地址: GUANGDONG PROVINCE