找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1649|回复: 2
收起左侧

中断方式显示DS1302时钟的问题,附单片机程序

[复制链接]
ID:205620 发表于 2021-11-4 22:41 | 显示全部楼层 |阅读模式
51hei图片_20211104224000.jpg
  1. #include<reg52.h>  // 定义头文件
  2. #include<intrins.h>        //定义函数文件

  3. unsigned char Sce,Min,Hour;//Sce秒,Min分,Hour时
  4. unsigned char y = 2; //定时器0中断时间y 设置ms

  5. sbit wei = P2^7; //定义位选
  6. sbit du = P2^6;        //定义段选
  7. sbit TSCLK = P1^0;//DS1302 时钟线  SCLK
  8. sbit TIO = P1^1; //DS1302 数据线   IO
  9. sbit TRST = P1^2;//DS1302 使能端   CE

  10. /*共阴级数码管段选码*/
  11. unsigned char code numdu_data[]= {
  12.                                                                         0x3F,  //"0"
  13.                                                                         0x06,  //"1"
  14.                                                                         0x5B,  //"2"
  15.                                                                         0x4F,  //"3"
  16.                                                                         0x66,  //"4"
  17.                                                                         0x6D,  //"5"
  18.                                                                         0x7D,  //"6"
  19.                                                                         0x07,  //"7"
  20.                                                                         0x7F,  //"8"
  21.                                                                         0x6F,   //"9"
  22.                                                                         0x77,  //"A"
  23.                                                                         0x7C,  //"B"
  24.                                                                         0x39,  //"C"
  25.                                                                         0x5E,  //"D"
  26.                                                                         0x79,  //"E"
  27.                                                                         0x71,  //"F"
  28.                                                                         0x76,  //"H"
  29.                                                                         0x38,  //"L"
  30.                                                                         0x37,  //"n"
  31.                                                                         0x3E,  //"u"
  32.                                                                         0x73,  //"P"
  33.                                                                         0x5C,  //"o"
  34.                                                                         0x40,  //"-"
  35.                                                              };

  36. /*共阴级数码管位选码*/
  37. unsigned char code numwei_data[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

  38. /*共阴级数码管显示函数*/
  39. void display(Sce,Min,Hour)
  40. {
  41.         unsigned char Scege,Sceshi,Minge,Minshi,Hourge,Hourshi;
  42.         static unsigned char i;//静态变量

  43.          Scege = Sce%10;//  12/10=1_2 取余2
  44.          Sceshi = Sce/10;// 12/10=1_2 取商1

  45.          Minge = Min%10;//  12/10=1_2 取余2
  46.          Minshi = Min/10;// 12/10=1_2 取商1

  47.          Hourge = Hour%10;// 12/10=1_2 取余2
  48.          Hourshi = Hour/10;// 12/10=1_2 取商1

  49.          

  50.          P0 = 0XFF;
  51.          wei = 1;//位选码打开
  52.          P0 = numwei_data[i];
  53.          wei = 0;//锁存位选码

  54.          switch(i)
  55.          {
  56.          //        如果是0 段选打开 P0等于数组里面的值 锁存段选 返回
  57.                  case 0: du = 1; P0 = numdu_data[Scege];   du = 0; break;
  58.                 case 1: du = 1; P0 = numdu_data[Sceshi];  du = 0; break;
  59.                 case 2: du = 1; P0 = numdu_data[22];      du = 0; break;
  60.                 case 3: du = 1; P0 = numdu_data[Minge];   du = 0; break;
  61.                 case 4: du = 1; P0 = numdu_data[Minshi];  du = 0; break;
  62.                 case 5: du = 1; P0 = numdu_data[22];      du = 0; break;
  63.                 case 6: du = 1; P0 = numdu_data[Hourge];  du = 0; break;
  64.                 case 7: du = 1; P0 = numdu_data[Hourshi]; du = 0; break;
  65.          }
  66.          i++; //i自加
  67.          if(i == 8)//因为numwei_data[]里面只有8个元素,所以只能加到8
  68.                  i = 0;//清零

  69. }
  70. /*定时器0中断寄存器配置*/
  71. void Timer_0()
  72. {
  73.         TMOD = 0X01;//配置TMOD寄存器 定时器0在16位工作模式下
  74.         TH0 =((65535-921)*y)/256;//1ms 把初值放入高8位
  75.         TL0 =((65535-921)*y)%256;//1ms 把初值放入低8位
  76.         EA = 1;//总中断打开
  77.         ET0 = 1;//TO溢出中断允许位
  78.         TR0 = 1;//允许定时0开始计数        
  79. }
  80. /*定时器0溢出中断函数*/
  81. void Timer0_init() interrupt 1
  82. {
  83.         TH0 =((65535-921)*y)/256;//1ms 把初值放入高8位
  84.         TL0 =((65535-921)*y)%256;//1ms 把初值放入低8位
  85.         display(Sce,Min,Hour);//共阴级数码管显示函数        
  86. }
  87. /*DS1302写数据*/
  88. void DS1302_wirte_dat(unsigned char cmd,unsigned char dat)
  89. {
  90.         unsigned char i; //发送数据次数变量
  91.         
  92.         TRST = 0;//        CE 拉低使能端
  93.         TSCLK = 0;//SCLK 拉低时钟线
  94.         TRST = 1;//CE 拉高使能端 产生上升沿 允许开始写数据
  95.         for(i = 0; i < 8; i++) // 执行8次将8位字节的数据写入
  96.         {
  97.                 TSCLK = 0; //SCLK 拉低时钟线
  98.                 TIO = cmd & 0x01;//写入一位数据 从最低位开始写入
  99.                 TSCLK = 1;// TSCLK产生上升沿时执行写入数据 数据被DS1302读取
  100.                 cmd >>= 1;//右移一位
  101.         }
  102.         for(i = 0; i < 8; i++)//执行8次将8位字节的数据写入
  103.         {
  104.                 TSCLK = 0;//SCLK 拉低时钟线
  105.                 TIO = dat & 0x01;//写入一位数据 从最低位开始写入
  106.                 TSCLK = 1;// TSCLK产生上升沿时执行写入数据 数据被DS1302读取
  107.                 dat >>= 1;//右移一位
  108.         }
  109. }
  110. /*DS1302读数据*/
  111. unsigned char DS1302_Read_dat(unsigned char cmd)
  112. {
  113.         unsigned char i,dat;//i发送数据次数变量 dat存放读取数据的变量

  114.         TRST = 0;//        CE 拉低使能端
  115.         TSCLK = 0;//SCLK 拉低时钟线
  116.         TRST = 1;//CE 拉高使能端 产生上升沿 允许开始写数据
  117.         for(i = 0; i < 8; i++) // 执行8次将8位字节的数据写入
  118.         {
  119.                 TSCLK = 0;        //SCLK 拉低时钟线
  120.                 TIO = cmd & 0x01; //写入一位数据 从最低位开始写入
  121.                 TSCLK = 1;// TSCLK产生上升沿时执行写入数据 数据被DS1302读取
  122.                 cmd >>= 1; //右移一位
  123.         }
  124.         for(i = 0; i < 8; i++)// 执行8次将8位字节的数据写入
  125.         {
  126.                 TSCLK = 0;//SCLK 拉低时钟线
  127.                 dat >>= 1;//读取数据变量dat右移一位
  128.                 if(TIO == 1) //如果TIO是高电平(为1)
  129.                         dat |= 0x80;//那么读取数据变量dat或等于1000 0000
  130.                 TSCLK = 1;//将SCLK时钟线拉高 准备下次通信
  131.         }
  132.         return dat;//得到的值返回
  133. }
  134. /*数据转换成BCD码 十进制转换成BCD码*/
  135. unsigned char Dat_Chg_BCD(unsigned char dat)
  136. {                                                                           //45
  137.         unsigned char dat1,dat2;
  138.         dat1 = dat / 10;// 45/10=4_5 取值4
  139.         dat2 = dat % 10;// 45/10=4_5 取值5
  140.         dat2 = dat2 + dat1 * 16;// 5+4*16=69
  141.         return dat2;//得到的值69返回
  142. }
  143. /*BCD码转换成数据 BCD码转换成十进制*/
  144. unsigned char BCD_Chg_Dat(unsigned char dat)
  145. {                                                                           //69
  146.         unsigned char dat1,dat2;
  147.         dat1 = dat /16;// 69/16 = 4_5取值4
  148.         dat2 = dat %16;// 69/16 = 4_5取值5
  149.         dat2 = dat2 + dat1 *10;//5+4*10=45
  150.         return dat2;//得到的值45返回
  151. }


  152. void main()
  153. {
  154.         Timer_0();//定时器0寄存器配初始化

  155.         DS1302_wirte_dat(0x8e,0);//关闭DS1302的写保护 好方便往里面写数据
  156.         DS1302_wirte_dat(0x80,Dat_Chg_BCD(30));//写秒初始显示时间  往DS1302里面需要转换成BCD码才能写进去
  157.         DS1302_wirte_dat(0x82,Dat_Chg_BCD(15));//写分初始显示时间
  158.         DS1302_wirte_dat(0x84,Dat_Chg_BCD(12));//写分初始显示时间  
  159.         DS1302_wirte_dat(0x8e,0x80);//打开DS1302的写保护 写不进数据
  160.                                                                   
  161.         while(1)
  162.         {         
  163.                 DS1302_wirte_dat(0x8e,0);//关闭DS1302的写保护 好方便往里面写数据
  164.                 Sce = BCD_Chg_Dat(DS1302_Read_dat(81));//读秒
  165.                 Min = BCD_Chg_Dat(DS1302_Read_dat(83));//读分
  166.                 Hour = BCD_Chg_Dat(DS1302_Read_dat(85));//读时
  167.                 DS1302_wirte_dat(0x8e,0x80);//打开DS1302的写保护 写不进数据        
  168.         
  169.                
  170.         }
  171.         
  172. }
复制代码




回复

使用道具 举报

ID:205620 发表于 2021-11-4 22:46 | 显示全部楼层
数码管只显示,几个零,也不走时,不明白,程序哪里出了问题
回复

使用道具 举报

ID:205620 发表于 2021-11-4 23:03 | 显示全部楼层
找到问题了,写读取的函数的时候,写的是十进制,前面忘记加0X了,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表