用电子秤上是led数码管显示ds1302时间数据。用逻辑分析仪了解大概协议之后改写了lcd1602液晶显示的代码。成功运行。数码管最后两位显示秒。
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define Delay(us) {_nop_();_nop_();_nop_();_nop_();}
- #define FOSC 18432000L
- #define uchar unsigned char
- #define uint unsigned int
- uchar dis_time_buf[16]={0};
- //*******1640驱动************
- sbit sda=P1^1; //TM1640数据线
- sbit scl=P3^7; //TM1640时钟线
- unsigned char date[] = {
- 0xb7,0x82,0x9d,0x3d,0x2e,0x3b,0xbb,0x25,0xbf,0x3f,0xaf,0x9e,0x9d,0x82,0x3b,0x8b,0xbc,0x6f,0x2f,0x40,0x00};
- unsigned char bite[16];
- //*****************************
- //DS1302引脚定义
- sbit RST=P1^4;
- sbit IO=P1^5;
- sbit SCK=P1^6;
- //DS1302地址定义
- #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
- //初始时间定义
- uchar time_buf[8] = {0x20,0x20,0x07,0x10,0x00,0x34,0x55,0x05};//初始时间2020年7月10号0点34分55秒 星期二
- //功能:延时1毫秒
- //入口参数:x
- //出口参数:无
- //说明:当晶振为12M时,j<112;当晶振为11.0592M时,j<122
- void Delay_xms(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<112;j++);
- }
- //功能:12us延时
- //STC89C52为1T单片机,即1个时钟/机器周期,速度为AT89C52的12倍
- void Delay_xus(uint t)
- {
- for(;t>0;t--)
- {
- _nop_();
- }
- }
- //*********START***************
- //功能:12us延时
- void start() //1640开始
- {
- //scl=0;
- sda=1;
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_();
- sda=0;
- _nop_();
- _nop_();
- scl=0;
- _nop_();
- _nop_();
- }
- //**************************************************************
- void stop() //1640结束
- {
- scl=0;
- _nop_();
- _nop_();
- sda=0;
- //scl=1;
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_();
- sda=1;
- _nop_();
- _nop_();
- }
- //***********************************************************
- void write(unsigned char date) //1640写字节
- {
- unsigned char i,aa;
- aa=date;
- //sda=0;
- //scl=0;
- for(i=0;i<8;i++)
- {
- scl=0;
- if(aa&0x01)
- {
- sda=1;
- _nop_();
- _nop_();
- }
- else
- {
- sda=0;
- _nop_();
- _nop_();
- }
- scl=1;
- _nop_();
- aa=aa>>1;
- }
- //scl=0;
- //sda=0;
- }
- //**************向TM1640发送显示数据***************************
- void send(unsigned char date1)
- //void send()
- {
- unsigned char ii;
- // unsigned char mask;
- start();
- write(0x40); //设置数据,地址加1模式
- stop();
- start();
- write(0xC0); //起始地址
- for(ii=0;ii<16;ii++) //16个地址
- {
- write(bite[ii]);
- }
- /* for(mask=0x80;mask!=0;mask>>=1)
- {
- if((mask&date1) == 0)
- I2C_SDA = 0;
- else
- I2C_SDA = 1;
- I2CDelay();
- I2C_SCL = 1;
- I2CDelay();
- I2C_SCL = 0;
- }*/
- stop();
- start();
- write(0x8f); //控制显示,开显示,脉冲宽度为14/16
- stop();
- }
- //****** 设置数据
- /* void sttingdate(uchar gg)
- { if (gg==1)
- {start();
- write(0x40);
- stop();}//设置数据,地址加一模式
- else
- {start();
- write(0x44);
- stop();} //设置数据,地址固定模式
- }
- //**************写入一个字节数据********************
- void LED_write_char(unsigned char x,unsigned char z)
- {
-
- //if (x<15)
-
- write(0xc0+x); //表示第一行
-
-
- write(date[z]);
-
- }*/
- //**********************************
- //**********************************
- /*void send1()
- {
- unsigned char i;
- start();
- //write(0x40); //设置数据,地址加1模式
- write(0x44); //固定地址模式
- stop();
- start();
- write(0x00);
- write(0xff);
- stop();
- start();
- write(0x01);
- write(0x01);
- stop();
- start();
- write(0x02);
- write(0x01);
- stop();
- start();
- write(0x03);
- write(0x01);
- stop();
- start();
- write(0x04);
- write(0x01);
- stop();
- start();
- write(0x05);
- write(0x01);
- stop();
- start();
- write(0x06);
- write(0x01);
- stop();
- start();
- write(0x8f); //控制显示,开显示,脉冲宽度为14/16
- stop();
- }*/
- //**********************************************************
- void delay(unsigned int z) //延时子程序
- {
- unsigned int x,y;
- for(x=z;x>0;x--)
- for(y=487;y>0;y--);
- }
- //DS1302初始化函数
- void ds1302_init(void)
- {
- RST=0; //RST脚置低
- SCK=0; //SCK脚置低
- }
- //向DS1302写入一字节数据
- void ds1302_write_byte(uchar addr, uchar d)
- {
- uchar i;
- RST=1; //启动DS1302总线
- //写入目标地址:addr
- addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
- for (i = 0; i < 8; i ++) {
- if (addr & 0x01) {
- IO=1;
- }
- else {
- IO=0;
- }
- SCK=1; //产生时钟
- SCK=0;
- addr = addr >> 1;
- }
- //写入数据:d
- for (i = 0; i < 8; i ++) {
- if (d & 0x01) {
- IO=1;
- }
- else {
- IO=0;
- }
- SCK=1; //产生时钟
- SCK=0;
- d = d >> 1;
- }
- RST=0; //停止DS1302总线
- }
- //从DS1302读出一字节数据
- uchar ds1302_read_byte(uchar addr) {
- uchar i,temp;
- RST=1; //启动DS1302总线
- //写入目标地址:addr
- addr = addr | 0x01; //最低位置高,寄存器0位为0时写,为1时读
- for (i = 0; i < 8; i ++) {
- if (addr & 0x01) {
- IO=1;
- }
- else {
- IO=0;
- }
- SCK=1;
- SCK=0;
- addr = addr >> 1;
- }
- //输出数据:temp
- for (i = 0; i < 8; i ++) {
- temp = temp >> 1;
- if (IO) {
- temp |= 0x80;
- }
- else {
- temp &= 0x7F;
- }
- SCK=1;
- SCK=0;
- }
- RST=0; //停止DS1302总线
- return temp;
- }
- //向DS302写入时钟数据
- 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读出时钟数据
- 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
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
上图Keil代码工程下载:
tm1640ds1302时钟显示.7z
(13.97 KB, 下载次数: 73)
|