找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于电子日历改良版原理图与单片机源代码

[复制链接]
ID:270088 发表于 2018-1-3 21:01 | 显示全部楼层 |阅读模式
0.png 0.png

单片机源程序如下:

  1. #define MAIN_Fosc                22118400L        //定义主时钟
  2. #include        "STC15Fxxxx.H"
  3. /***********************************************************/
  4. #define DIS_DOT                0x20
  5. #define DIS_BLACK        0x10
  6. #define DIS_                0x11
  7. #define SLAW        0xA2
  8. #define SLAR        0xA3

  9. sbit        SDA        = P1^1;        //定义SDA  PIN5
  10. sbit        SCL        = P1^0;        //定义SCL  PIN6

  11. /****************************** 用户定义宏 ***********************************/

  12. #define        Timer0_Reload        (65536UL -(MAIN_Fosc / 1000))                //Timer 0 中断频率, 1000次/秒

  13. /*************        本地常量声明        **************/
  14. u8 code t_display[]={                                                //标准字库
  15. //         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  16.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  17. //black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
  18.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
  19.         0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};        //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

  20. u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};                //位码


  21. /*************        IO口定义        **************/
  22. sbit        P_HC595_SER   = P4^0;        //pin 14        SER                data input
  23. sbit        P_HC595_RCLK  = P5^4;        //pin 12        RCLk        store (latch) clock
  24. sbit        P_HC595_SRCLK = P4^3;        //pin 11        SRCLK        Shift data clock


  25. /*************        本地变量声明        **************/

  26. u8         LED8[8];                //显示缓冲
  27. u8        display_index;        //显示位索引
  28. bit        B_1ms;                        //1ms标志

  29. u8 IO_KeyState, IO_KeyState1, IO_KeyHoldCnt;        //行列键盘变量
  30. u8        KeyHoldCnt;        //键按下计时
  31. u8        KeyCode;        //给用户使用的键码, 1~16有效
  32. u8        cnt50ms;

  33. u8        hour,minute,second;        //RTC变量
  34. u8        year,month,date;        //Cadendar变量
  35. u16        msecond;

  36. u8 m;
  37. u8 flag=0;
  38. u8 flaging=1;
  39. u16 k=0;

  40. unsigned char tt[2]={0x12,0x17};         
  41. unsigned char tt0[1]={0x13};
  42. unsigned char newtime[3]={0x00,0x00,0x10};


  43. /*************        本地函数声明        **************/
  44. void        CalculateAdcKey(u16 adc);
  45. void        IO_KeyScan(void);        //50ms call
  46. void        WriteNbyte(u8 addr, u8 *p, u8 number);
  47. void        ReadNbyte( u8 addr, u8 *p, u8 number);
  48. void        DisplayRTC(void);
  49. void        DisplayCadendar(void);
  50. void        ReadRTC(void);
  51. void        WriteRTC(void);
  52. void        ReadCadendar(void);
  53. void        WriteCadendar(void);


  54. /****************  外部函数声明和外部变量声明 *****************/

  55. void main(void)
  56. {
  57.         u8        i;


  58.         P0M1 = 0;        P0M0 = 0;        //设置为准双向口
  59.         P1M1 = 0;        P1M0 = 0;        //设置为准双向口
  60.         P2M1 = 0;        P2M0 = 0;        //设置为准双向口
  61.         P3M1 = 0;        P3M0 = 0;        //设置为准双向口
  62.         P4M1 = 0;        P4M0 = 0;        //设置为准双向口
  63.         P5M1 = 0;        P5M0 = 0;        //设置为准双向口
  64.         P6M1 = 0;        P6M0 = 0;        //设置为准双向口
  65.         P7M1 = 0;        P7M0 = 0;        //设置为准双向口
  66.         
  67.         display_index = 0;
  68.         
  69.         AUXR = 0x80;        //Timer0 set as 1T, 16 bits timer auto-reload,
  70.         TH0 = (u8)(Timer0_Reload / 256);
  71.         TL0 = (u8)(Timer0_Reload % 256);
  72.         ET0 = 1;        //Timer0 interrupt enable
  73.         TR0 = 1;        //Tiner0 run

  74.         IE1 = 0;        //外中断1标志位
  75.         IT1 = 1;        //INT1下降沿触发
  76.         EX1 = 1;        //外中断1允许位
  77.         PX1 = 1;   //外部中断1为高优先级
  78.         
  79.         EA = 1;                //打开总中断


  80.         
  81.         for(i=0; i<8; i++)        LED8[i] = 0x10;        //上电消隐

  82.         WriteNbyte(2,newtime,3);
  83.         ReadRTC();

  84.         WriteNbyte(5,tt0,1);
  85.         WriteNbyte(7,tt,2);
  86.         ReadCadendar();

  87.         F0 = 0;
  88.         if(second >= 60)        F0 = 1;        
  89.         if(minute >= 60)        F0 = 1;        
  90.         if(hour   >= 24)        F0 = 1;        
  91.         if(date   >= 31)        F0 = 1;        
  92.         if(month  >= 12)        F0 = 1;        
  93.         if(year   >= 99)        F0 = 1;        

  94.         if(F0)        //有错误, 默认12:30:00         17-12-13
  95.         {
  96.                 second = 0;
  97.                 minute = 30;
  98.                 hour  = 12;
  99.                 WriteRTC();

  100.                 date = 13 ;
  101.                 month= 12 ;
  102.                 year = 17 ;
  103.                 WriteCadendar();
  104.         }


  105.     DisplayRTC();

  106.         KeyHoldCnt = 0;        //键按下计时
  107.         KeyCode = 0;        //给用户使用的键码, 1~16有效

  108.         IO_KeyState = 0;
  109.         IO_KeyState1 = 0;
  110.         IO_KeyHoldCnt = 0;
  111.         cnt50ms = 0;

  112.    
  113.         
  114.         while(1)
  115.         {
  116.          
  117.            while(flag==0)
  118.            {
  119.                                 if(B_1ms)        //1ms到
  120.                                 {
  121.                                         B_1ms = 0;

  122.                                         if(++msecond >= 500)        //1秒到
  123.                                         {
  124.                                                 msecond = 0;
  125.                                                 ReadRTC();
  126.                                                 DisplayRTC();
  127.                                         }

  128.                                         if(++cnt50ms >= 50)                //50ms扫描一次行列键盘
  129.                                         {
  130.                                                 cnt50ms = 0;
  131.                                                 IO_KeyScan();
  132.                                         }
  133.                                         if(KeyCode != 0)                //有键按下
  134.                                         {
  135.                                                 if(KeyCode == 17)        //hour +1
  136.                                                 {
  137.                                                         if(++hour >= 24)        hour = 0;
  138.                                                         WriteRTC();
  139.                                                         DisplayRTC();
  140.                                                 }
  141.                                                 if(KeyCode == 18)        //hour -1
  142.                                                 {
  143.                                                         if(--hour >= 24)        hour = 23;
  144.                                                         WriteRTC();
  145.                                                         DisplayRTC();
  146.                                                 }
  147.                                                 if(KeyCode == 19)        //minute +1
  148.                                                 {
  149.                                                         second = 0;
  150.                                                         if(++minute >= 60)        minute = 0;
  151.                                                         WriteRTC();
  152.                                                         DisplayRTC();
  153.                                                 }
  154.                                                 if(KeyCode == 20)        //minute -1
  155.                                                 {
  156.                                                         second = 0;
  157.                                                         if(--minute >= 60)        minute = 59;
  158.                                                         WriteRTC();
  159.                                                         DisplayRTC();
  160.                                                 }
  161.                                                 if(KeyCode == 21)
  162.                                                 {
  163.                                                         flag=1;
  164.                                                 }

  165.                                                 KeyCode = 0;
  166.                                         }
  167.                                                 
  168.                                 }
  169.             }
  170.                   while(flag ==1)                  
  171.             {
  172.                           if(k>202)
  173.                           {
  174.                                     DisplayCadendar();
  175.                                           k=0;
  176.                
  177.                                     if(++cnt50ms >= 50)               
  178.                                         {
  179.                                                 cnt50ms = 0;
  180.                                                 IO_KeyScan();
  181.                                         }
  182.                                                 
  183.                                         if(KeyCode !=0)               
  184.                                         {
  185.                                                          if(KeyCode == 22)        
  186.                                                          {
  187.                                                                         flag=0;
  188.                                                          }

  189.                                                     if(KeyCode == 25)        //year +1
  190.                                              {
  191.                                                                 KeyCode =0;
  192.                                                                 if(++year >= 99)        year = 0;
  193.                                                                 WriteCadendar();
  194.                                                                 DisplayCadendar();
  195.                                                                 //while(1);
  196.                                              }
  197.                                                   if(KeyCode == 26)        //year -1
  198.                                              {
  199.                                                                 KeyCode =0;
  200.                                                                 if(--year >= 100)        year =99;
  201.                                                                 WriteCadendar();
  202.                                                                 DisplayCadendar();
  203.                                                         
  204.                                              }
  205.                                                     if(KeyCode == 27)        //month +1
  206.                                              {
  207.                                                                 KeyCode =0;
  208.                                                                 if(++month >= 13)        month = 1;
  209.                                                                 WriteCadendar();
  210.                                                                 DisplayCadendar();
  211.                                                         
  212.                                              }
  213.                                                     if(KeyCode == 28)        //month -1
  214.                                              {
  215.                                                                 KeyCode =0;
  216.                                                                 if(--month==0)        month = 12;
  217.                                                                 WriteCadendar();
  218.                                                                 DisplayCadendar();
  219.                                                         
  220.                                              }
  221.                                                     if(KeyCode == 29)        //date +1
  222.                                              {
  223.                                                                 KeyCode =0;
  224.                                                                 if(++date >= 32)        date = 1;
  225.                                                                 WriteCadendar();
  226.                                                                 DisplayCadendar();
  227.                                                         
  228.                                              }               
  229.                                                     if(KeyCode == 30)        //date -1
  230.                                              {
  231.                                                                 KeyCode =0;
  232.                                                                 if(--date == 0)        date = 31;
  233.                                                                 WriteCadendar();
  234.                                                                 DisplayCadendar();
  235.                                                         
  236.                                              }        
  237.                                         }
  238.                     }
  239.                              k++;
  240.                  }
  241.         }
  242. }

  243. /********************** 显示时钟函数 ************************/
  244. void        DisplayRTC(void)
  245. {
  246.         if(hour >= 10)        LED8[0] = hour / 10;
  247.         else                        LED8[0] = DIS_BLACK;
  248.         LED8[1] = hour % 10;
  249.         LED8[2] = DIS_;
  250.         LED8[3] = minute / 10;
  251.         LED8[4] = minute % 10;
  252.         LED8[5] = DIS_;
  253.         LED8[6] = second / 10;
  254.         LED8[7] = second % 10;
  255. }
  256. /********************** 显示日历函数 ************************/

  257. void        DisplayCadendar(void)
  258. {
  259.         LED8[0] = 2;
  260.         LED8[1] = 0;
  261.         if(year >= 10)        LED8[2] = year / 10;
  262.         else                        
  263.         LED8[2] = DIS_BLACK;
  264.         LED8[3] = year % 10;
  265.         
  266.         LED8[4] = month / 10;
  267.         LED8[5] = month % 10;

  268.         LED8[6] = date / 10;
  269.         LED8[7] = date % 10;

  270. }

  271. /**********************读RTC函数************************/
  272. void        ReadRTC(void)
  273. {
  274.         u8        tmp[3];

  275.         ReadNbyte(2, tmp, 3);
  276.         second = ((tmp[0] >> 4) & 0x07) * 10 + (tmp[0] & 0x0f);
  277.         minute = ((tmp[1] >> 4) & 0x07) * 10 + (tmp[1] & 0x0f);
  278.         hour   = ((tmp[2] >> 4) & 0x03) * 10 + (tmp[2] & 0x0f);

  279. //        if(minute==20)                          19-59停止
  280. //        while(1);
  281. }

  282. /**********************写RTC函数************************/
  283. void        WriteRTC(void)
  284. {
  285.         u8        tmp[3];

  286.         tmp[0] = ((second / 10) << 4) + (second % 10);
  287.         tmp[1] = ((minute / 10) << 4) + (minute % 10);
  288.         tmp[2] = ((hour / 10) << 4) + (hour % 10);
  289.         WriteNbyte(2, tmp, 3);
  290. }

  291. /********************** 读Cadendar函数 ************************/
  292. void        ReadCadendar(void)
  293. {
  294.         u8        cad[3];
  295.         ReadNbyte(5, cad, 1);
  296.         ReadNbyte(7, cad+1, 2);
  297.         date = ((cad[0] >> 4) & 0x03) * 10 + (cad[0] & 0x0f);
  298.         month = ((cad[1] >> 4) & 0x01) * 10 + (cad[1] & 0x0f);
  299.         year   = (cad[2] >> 4)  * 10 + (cad[2] & 0x0f);
  300. }

  301. /********************** 写Cadendar函数 ************************/
  302. void        WriteCadendar(void)
  303. {
  304.         u8        cad[3];

  305.         cad[0] = ((date / 10) << 4) + (date % 10);
  306.         cad[1] = ((month / 10) << 4) + (month % 10);
  307.         cad[2] = ((year / 10) << 4) + (year % 10);
  308.         WriteNbyte(5, cad, 1);
  309.     WriteNbyte(7, cad+1, 2);

  310. }



  311. /*****************************************************
  312.         行列键扫描程序
  313.         使用XY查找4x4键的方法,只能单键,速度快

  314.    Y     P04      P05      P06      P07
  315.           |        |        |        |
  316. X         |        |        |        |
  317. P00 ---- K00 ---- K01 ---- K02 ---- K03 ----
  318.           |        |        |        |
  319. P01 ---- K04 ---- K05 ---- K06 ---- K07 ----
  320.           |        |        |        |
  321. P02 ---- K08 ---- K09 ---- K10 ---- K11 ----
  322.           |        |        |        |
  323. P03 ---- K12 ---- K13 ---- K14 ---- K15 ----
  324.           |        |        |        |
  325. ******************************************************/


  326. u8 code T_KeyTable[16] = {0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};

  327. void IO_KeyDelay(void)
  328. {
  329.         u8 i;
  330.         i = 60;
  331.         while(--i)        ;
  332. }

  333. void        IO_KeyScan(void)        //50ms call
  334. {
  335.         u8        j;

  336.         j = IO_KeyState1;        //保存上一次状态

  337.         P0 = 0xf0;        //X低,读Y
  338.         IO_KeyDelay();
  339.         IO_KeyState1 = P0 & 0xf0;

  340.         P0 = 0x0f;        //Y低,读X
  341.         IO_KeyDelay();
  342.         IO_KeyState1 |= (P0 & 0x0f);
  343.         IO_KeyState1 ^= 0xff;        //取反
  344.         
  345.         if(j == IO_KeyState1)        //连续两次读相等
  346.         {
  347.                 j = IO_KeyState;
  348.                 IO_KeyState = IO_KeyState1;
  349.                 if(IO_KeyState != 0)        //有键按下
  350.                 {
  351.                         F0 = 0;
  352.                         if(j == 0)        F0 = 1;        //第一次按下
  353.                         else if(j == IO_KeyState)
  354.                         {
  355.                                 if(++IO_KeyHoldCnt >= 20)        //1秒后重键
  356.                                 {
  357.                                         IO_KeyHoldCnt = 18;
  358.                                         F0 = 1;
  359.                                 }
  360.                         }
  361.                         if(F0)
  362.                         {
  363.                                 j = T_KeyTable[IO_KeyState >> 4];
  364.                                 if((j != 0) && (T_KeyTable[IO_KeyState& 0x0f] != 0))
  365.                                         KeyCode = (j - 1) * 4 + T_KeyTable[IO_KeyState & 0x0f] + 16;        //计算键码,17~32
  366.                         }
  367.                 }
  368.                 else        IO_KeyHoldCnt = 0;
  369.         }
  370.         P0 = 0xff;
  371. }




  372. /**************** 向HC595发送一个字节函数 ******************/
  373. void Send_595(u8 dat)
  374. {               
  375.         u8        i;
  376.         for(i=0; i<8; i++)
  377.         {
  378.                 dat <<= 1;
  379.                 P_HC595_SER   = CY;
  380.                 P_HC595_SRCLK = 1;
  381.                 P_HC595_SRCLK = 0;
  382.         }
  383. }

  384. /********************** 显示扫描函数 ************************/
  385. void DisplayScan(void)
  386. {        
  387.         Send_595(~T_COM[display_index]);                                //输出位码
  388.         Send_595(t_display[LED8[display_index]]);        //输出段码

  389.         P_HC595_RCLK = 1;
  390.         P_HC595_RCLK = 0;                                                        //所存输出数据
  391.         if(++display_index >= 8)        display_index = 0;        //8位结束回0
  392. }


  393. /********************** Timer0 1ms中断函数 ************************/
  394. void timer0 (void) interrupt TIMER0_VECTOR
  395. {
  396.         DisplayScan();        //1ms扫描显示一位
  397.         B_1ms = 1;                //1ms标志
  398. }

  399. /****************************/
  400. void        I2C_Delay(void)        //for normal MCS51,        delay (2 * dly + 4) T, for STC12Cxxxx delay (4 * dly + 10) T
  401. {
  402.         u8        dly;
  403.         dly = MAIN_Fosc / 2000000UL;                //按2us计算
  404.         while(--dly)        ;
  405. }

  406. /****************************/
  407. void I2C_Start(void)               //start the I2C, SDA High-to-low when SCL is high
  408. {
  409.         SDA = 1;
  410.         I2C_Delay();
  411.         SCL = 1;
  412.         I2C_Delay();
  413.         SDA = 0;
  414.         I2C_Delay();
  415.         SCL = 0;
  416.         I2C_Delay();
  417. }               


  418. void I2C_Stop(void)                                        //STOP the I2C, SDA Low-to-high when SCL is high
  419. {
  420.         SDA = 0;
  421.         I2C_Delay();
  422.         SCL = 1;
  423.         I2C_Delay();
  424.         SDA = 1;
  425.         I2C_Delay();
  426. }

  427. void S_ACK(void)              //Send ACK (LOW)
  428. {
  429.         SDA = 0;
  430.         I2C_Delay();
  431.         SCL = 1;
  432.         I2C_Delay();
  433.         SCL = 0;
  434.         I2C_Delay();
  435. }

  436. void S_NoACK(void)           //Send No ACK (High)
  437. {
  438.         SDA = 1;
  439.         I2C_Delay();
  440.         SCL = 1;
  441.         I2C_Delay();
  442.         SCL = 0;
  443.         I2C_Delay();
  444. }
  445.                
  446. void I2C_Check_ACK(void)         //Check ACK, If F0=0, then right, if F0=1, then error
  447. {
  448.         SDA = 1;
  449.         I2C_Delay();
  450.         SCL = 1;
  451.         I2C_Delay();
  452.         F0  = SDA;
  453.         SCL = 0;
  454.         I2C_Delay();
  455. }

  456. /****************************/
  457. void I2C_WriteAbyte(u8 dat)                //write a byte to I2C
  458. {
  459.         u8 i;
  460.         i = 8;
  461.         do
  462.         {
  463.                 if(dat & 0x80)        SDA = 1;
  464.                 else                        SDA        = 0;
  465.                 dat <<= 1;
  466.                 I2C_Delay();
  467.                 SCL = 1;
  468.                 I2C_Delay();
  469.                 SCL = 0;
  470.                 I2C_Delay();
  471.         }
  472.         while(--i);
  473. }

  474. /****************************/
  475. u8 I2C_ReadAbyte(void)                        //read A byte from I2C
  476. {
  477.         u8 i,dat;
  478.         i = 8;
  479.         SDA = 1;
  480.         do
  481.         {
  482.                 SCL = 1;
  483. ……………………

  484. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
电子日历改良版.zip (119.07 KB, 下载次数: 14)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:359571 发表于 2018-6-26 18:23 | 显示全部楼层
楼主发一下文件给我,我急用,救人一命胜造七级浮屠,1540491521@qq.com,拜托您了
回复

使用道具 举报

ID:359571 发表于 2018-6-26 18:26 | 显示全部楼层
楼主里面有电子CAD画的原理图吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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