找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1880|回复: 0
收起左侧

STC8H4K64TLCD-45MHz-LQFP64,硬件LCD段码驱动显示程序,硬件实时时钟演示程序

[复制链接]
ID:961114 发表于 2022-10-28 09:52 | 显示全部楼层 |阅读模式
STC8H4K64TLCD-45MHz-LQFP64,硬件LCD段码驱动显示程序,硬件实时时钟演示程序
11.png

单片机源程序如下:
  1. /*********************************************************/
  2. #define MAIN_Fosc                11059200L        //定义主时钟

  3. #include        "STC8H4K64TL.h"


  4. /*************        功能说明        **************

  5. 请先别修改程序, 直接下载"04-RTC基本操作-5位液晶显示时间"里的"rtc.hex"测试, 主频选择11.0592MHZ. 测试正常后再修改移植.

  6. K1切换显示时分和分秒。
  7. K2调整小时+.  按下超过1秒, 则提供1秒10个键码.
  8. K3调整分钟+. 按下超过1秒, 则提供1秒10个键码.
  9. K4调整分钟-. 按下超过1秒, 则提供1秒10个键码.

  10. 特别提醒: 本例子仅仅是一个示范程序, 不同的段码液晶, 其笔段排列不同, 要根据具体的液晶屏来确定显存映射.
  11. MCU电流: 根据LCD面积大约10~25uA.


  12. 硬件连接:
  13. COM0---P5.0                SEG8---P0.6                SEG12--P0.4                SEG16--P0.0
  14. COM1---P5.1                SEG9---P0.5                SEG13--P0.3                SEG17--P4.6
  15. COM2---P3.5                SEG10--P5.3                SEG14--P0.2                SEG18--P4.5
  16. COM3---P3.6                SEG11--P5.2                SEG15--P0.1                SEG19--P2.7

  17. LCD显示内容:  -日.日.日.日.日

  18.                 B7                B6                B5                B4                B3                B2                B1                B0
  19. LCD_buff[0]:        2H                3D                1H                2D                左下        1D                B1                B0                左下为左下角的箭头, B0为电池框, B1为电量1
  20. LCD_buff[1]:        --                --                --                --                4H                5D                3H                4D
  21. LCD_buff[2]:        3C                3E                2C                2E                1C                1E                B2                右上        右上为右上角的箭头, B2为电量2
  22. LCD_buff[3]:        --                --                --                --                5C                5E                4C                4E
  23. LCD_buff[4]:        3B                3G                2B                2G                1B                1G                B3                -                B3为电量3, -为左边符号
  24. LCD_buff[5]:        --                --                --                --                5B                5G                4B                4G
  25. LCD_buff[6]:        3A                3F                2A                2F                1A                1F                B4                左上        左上为左上角的箭头
  26. LCD_buff[7]:        --                --                --                --                5A                5F                4A                4F

  27. ******************************************/

  28. /*************        本地常量声明        **************/

  29. #define K_SWITCH        0x10
  30. #define K_HOUR                0x20
  31. #define K_MIN_UP        0x40
  32. #define K_MIN_DN        0x80


  33. #define DIS_BLACK        0x10
  34. #define DIS_                0x11

  35. #define LCD_SET_BAT0        LCD_buff[0] |=  0x01
  36. #define LCD_CLR_BAT0        LCD_buff[0] &= ~0x01
  37. #define LCD_CPL_BAT0        LCD_buff[0] ^=  0x01

  38. #define LCD_SET_BAT1        LCD_buff[0] |=  0x02
  39. #define LCD_CLR_BAT1        LCD_buff[0] &= ~0x02
  40. #define LCD_CPL_BAT1        LCD_buff[0] ^=  0x02

  41. #define LCD_SET_BAT2        LCD_buff[2] |=  0x02
  42. #define LCD_CLR_BAT2        LCD_buff[2] &= ~0x02
  43. #define LCD_CPL_BAT2        LCD_buff[2] ^=  0x02

  44. #define LCD_SET_BAT3        LCD_buff[4] |=  0x02
  45. #define LCD_CLR_BAT3        LCD_buff[4] &= ~0x02
  46. #define LCD_CPL_BAT3        LCD_buff[4] ^=  0x02

  47. #define LCD_SET_BAT4        LCD_buff[6] |=  0x02
  48. #define LCD_CLR_BAT4        LCD_buff[6] &= ~0x02
  49. #define LCD_CPL_BAT4        LCD_buff[6] ^=  0x02

  50. #define LCD_SET_LEFT_UP                LCD_buff[6] |=  0x01
  51. #define LCD_CLR_LEFT_UP                LCD_buff[6] &= ~0x01
  52. #define LCD_SET_LEFT_DN                LCD_buff[0] |=  0x08
  53. #define LCD_CLR_LEFT_DN                LCD_buff[0] &= ~0x08
  54. #define LCD_SET_RIGHT_UP        LCD_buff[2] |=  0x01
  55. #define LCD_CLR_RIGHT_UP        LCD_buff[2] &= ~0x01


  56. /*************        本地IO定义        **************/


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

  58. u8        year, month, day, week, hour, minute, second;        //RTC实时时间
  59. bit        B_500mS;        // 0.5秒时隙标志
  60. bit        B_20ms;                // 20ms时隙标志
  61. u8        OpTime;                // 此变量非0时, 不睡眠, 连续运行程序(本例串口唤醒后连续运行5秒, 以便正确接收串口数据)

  62. u8        idata        LCD_buff[8];        //LCD显存

  63. u8        DisMode;                //显示模式, 0: 显示时分, 1:显示分秒, 2:显示月日

  64. u8        KeyState;        //键状态
  65. u8        KeyCode;        //键码
  66. u8        KeyHoldCnt;        //重键计数


  67. /*************        本地函数声明        **************/
  68. u8                SetRTC(void);                //设置RTC时间函数
  69. void        RTC_config(void);        //RTC初始化函数
  70. void        RTC_read(void);                //读RTC时间函数
  71. void        RTC_ShowLCD(void);        //显示时间信息
  72. u8                Timer0_Config(u32 reload);        //reload值是主时钟周期数
  73. void        LCD_config(void);
  74. void        LoadToLcd(void);
  75. void        LCD_load(u8 n, u8 dat);                //n为第几个数字,为1~5,dat为要显示的数字
  76. void        ReadKey(void);        //50ms call


  77. //========================================================================
  78. // 函数: void main(void)
  79. // 描述: 主函数
  80. // 参数: none.
  81. // 返回: none.
  82. // 版本: VER1.0
  83. // 日期: 2018-4-2
  84. // 备注:
  85. //========================================================================
  86. void main(void)
  87. {
  88.         P0M1 = 0;        P0M0 = 0;
  89.         P1M1 = 0;        P1M0 = 0;
  90.         P2M1 = 0;        P2M0 = 0;
  91.         P3M1 = 0;        P3M0 = 0;
  92.         P4M1 = 0;        P4M0 = 0;
  93.         P5M1 = 0;        P5M0 = 0;
  94.         P6M1 = 0;        P6M0 = 0;
  95.         P7M1 = 0;        P7M0 = 0;

  96.         Timer0_Config(MAIN_Fosc / 50);        //reload值是主时钟周期数,  (中断频率, 50次/秒)

  97.         EA = 1;

  98.         OpTime  = 0;
  99.         DisMode = 0;
  100.         RTC_config();
  101.         LCD_config();

  102.         while (1)
  103.         {
  104.                 if(B_20ms)
  105.                 {
  106.                         B_20ms = 0;
  107.                         ReadKey();
  108.                 }

  109.                 if(B_500mS)        // 1/2秒中断
  110.                 {
  111.                         B_500mS = 0;
  112.                         if(second  == RTC_SEC)                // RTC的秒计数值, 相等则秒没变化, 0.5秒而已, 闪点
  113.                         {
  114.                                 if(DisMode <= 1)        //显示时分或分秒才闪秒
  115.                                 {
  116.                                         LCD_load(3, DIS_);        //秒闪中间一杠
  117.                                         LoadToLcd();
  118.                                 }
  119.                         }
  120.                         else        //秒有变化
  121.                         {
  122.                                 RTC_read();
  123.                                 if(OpTime != 0)        OpTime--;        //连续操作时间
  124.                                 RTC_ShowLCD();        //显示时间信息
  125.                         }

  126.                 }

  127.                 if(KeyCode != 0)
  128.                 {
  129.                         if(KeyCode == K_SWITCH)                //短按K1键 切换显示
  130.                         {
  131.                                 if(++DisMode >= 3)        DisMode = 0;        //0: 显示时分, 1:显示分秒, 2:显示月日
  132.                                 RTC_ShowLCD();        //显示时间信息
  133.                         }
  134.                         else if(DisMode == 0)        //显示时分时可以调时间
  135.                         {
  136.                                 if(KeyCode == K_HOUR)        //hour键
  137.                                 {
  138.                                         if(++hour >= 24)        hour = 0;
  139.                                         SetRTC();
  140.                                         RTC_ShowLCD();        //显示时间信息
  141.                                 }
  142.                                 else if(KeyCode == K_MIN_UP)        //MINUTE+键
  143.                                 {
  144.                                         if(++minute >= 60)        minute = 0;
  145.                                         second = 0;
  146.                                         SetRTC();
  147.                                         RTC_ShowLCD();        //显示时间信息
  148.                                 }
  149.                                 else if(KeyCode == K_MIN_DN)        //MINUTE-键
  150.                                 {
  151.                                         if(--minute >= 60)        minute = 59;
  152.                                         second = 0;
  153.                                         SetRTC();
  154.                                         RTC_ShowLCD();        //显示时间信息
  155.                                 }
  156.                         }
  157.                         else if(DisMode == 2)        //显示月日时可以调日期
  158.                         {
  159.                                 if(KeyCode == K_HOUR)        //hour键
  160.                                 {
  161.                                         if(++month >= 13)        month = 1;
  162.                                         SetRTC();
  163.                                         RTC_ShowLCD();        //显示时间信息
  164.                                 }
  165.                                 else if(KeyCode == K_MIN_UP)        //MINUTE+键
  166.                                 {
  167.                                         if(++day >= 32)        day = 1;
  168.                                         SetRTC();
  169.                                         RTC_ShowLCD();        //显示时间信息
  170.                                 }
  171.                                 else if(KeyCode == K_MIN_DN)        //MINUTE-键
  172.                                 {
  173.                                         if(--day == 0)        day = 31;
  174.                                         SetRTC();
  175.                                         RTC_ShowLCD();        //显示时间信息
  176.                                 }
  177.                         }
  178.                         KeyCode = 0;
  179.                 }

  180.                 if(OpTime != 0)                // OpTime!=0进入空闲模式
  181.                 {
  182.                         PCON |= 0x01;        //进入空闲模式
  183.                         NOP(5);
  184.                 }
  185.                 else        //if(OpTime == 0)                // OpTime==0才进入掉电模式
  186.                 {
  187.                         IE0 = 0;        //外中断0标志位
  188.                         IT0 = 1;        //下降沿中断
  189.                         EX0 = 1;        //允许中断
  190.                         P32 = 1;        //唤醒脚(也是键扫描脚)
  191.                         P64 = 0;        //按键输入
  192.                         P65 = 0;        //按键输入
  193.                         P66 = 0;        //按键输入
  194.                         P67 = 0;        //按键输入
  195.                         NOP(5);

  196.                         PCON |= 0x02;        //进入睡眠模式
  197.                         NOP(5);
  198.                         EX0 = 0;        //禁止中断
  199.                         P32 = 0;
  200.                         P64 = 1;
  201.                         P65 = 1;
  202.                         P66 = 1;
  203.                         P67 = 1;
  204.                         NOP(5);
  205.                 }
  206.         }
  207. }


  208. /********************* INT0中断函数 *************************/
  209. void Ext_INT0 (void) interrupt 0
  210. {
  211.         OpTime = 6;
  212. }

  213. void        ReadKey(void)        //20ms call
  214. {
  215.         u8        i;
  216.         i = KeyState;        KeyState = ~P6 & 0xf0;
  217.         i = (i ^ KeyState) & KeyState;
  218.         if(i != 0)        KeyCode = i;        //按下
  219.         if(KeyState)
  220.         {
  221.                 OpTime = 6;        //有键按着
  222.                 if(++KeyHoldCnt >= 50)
  223.                 {
  224.                         KeyHoldCnt = 45;
  225.                         KeyCode = KeyState & 0xe0;
  226.                 }
  227.         }
  228.         else        KeyHoldCnt = 0;
  229. }


  230. /********************** 显示时间信息 *****************************/
  231. void        RTC_ShowLCD(void)
  232. {
  233.         if(DisMode == 0)        //0: 显示时分, 1:显示分秒, 2:显示月日
  234.         {
  235.                 if(hour >= 10)        LCD_load(1, hour/10);
  236.                 else                        LCD_load(1, DIS_BLACK);                //消隐
  237.                 LCD_load(2, hour%10);
  238.                 LCD_load(3, DIS_BLACK);
  239.                 LCD_load(4, minute / 10);
  240.                 LCD_load(5, minute % 10);
  241.         }
  242.         else if(DisMode == 1)        //0: 显示时分, 1:显示分秒, 2:显示月日
  243.         {
  244.                 LCD_load(1, minute/10);
  245.                 LCD_load(2, minute%10);
  246.                 LCD_load(3, DIS_BLACK);
  247.                 LCD_load(4, second / 10);
  248.                 LCD_load(5, second % 10);
  249.         }
  250.         else if(DisMode == 2)        //0: 显示时分, 1:显示分秒, 2:显示月日
  251.         {
  252.                 if(month >= 10)        LCD_load(1, month/10);
  253.                 else                        LCD_load(1, DIS_BLACK);
  254.                 LCD_load(2, month%10);
  255.                 LCD_load(3, DIS_BLACK);
  256.                 LCD_load(4, day / 10);
  257.                 LCD_load(5, day % 10);
  258.         }

  259.         LoadToLcd();
  260. }

  261. /****************** 对第1~5数字装载显示函数 ***************************/
  262. u8 code t_display[]={                                                //标准字库
  263. //         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  264.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  265. //black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
  266.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e};

  267. u8        code T_LCD_mask[7]  = {0x00,0x0C,0x30,0xC0,0x03,0x0C};
  268. u8        code T_LCD_mask7[7] = {0x00,0x04,0x10,0x40,0x01,0x04};
  269. u8        code T_SEG_ABC[7]   = {0x00,0x08,0x20,0x80,0x02,0x08};
  270. u8        code T_SEG_DEFG[7]  = {0x00,0x04,0x10,0x40,0x01,0x04};

  271. /********************** 装载显示5个8字 *****************************/
  272. void        LCD_load(u8 n, u8 dat)                //n为第几个数字,为1~5,dat为要显示的数字
  273. {
  274.         u8        i,k;

  275.         if((n == 0) || (n >= 6))        return;        //合法值 1~5

  276.         dat =  t_display[dat];
  277.         k   = ~T_LCD_mask[n];

  278.         if(n <= 3)        //1~3
  279.         {
  280.                 LCD_buff[0] &= ~T_LCD_mask7[n];
  281.                 LCD_buff[2] &= k;
  282.                 LCD_buff[4] &= k;
  283.                 LCD_buff[6] &= k;
  284.                 i = T_SEG_ABC[n];
  285.                 k = T_SEG_DEFG[n];
  286.                 if(dat & 0x01)                LCD_buff[6] |= i;        //T_SEG_ABC[n];                //A
  287.                 if(dat & 0x02)                LCD_buff[4] |= i;        //T_SEG_ABC[n];                //B
  288.                 if(dat & 0x04)                LCD_buff[2] |= i;        //T_SEG_ABC[n];                //C
  289.                 if(dat & 0x08)                LCD_buff[0] |= k;        //T_SEG_DEFG[n];        //D
  290.                 if(dat & 0x10)                LCD_buff[2] |= k;        //T_SEG_DEFG[n];        //E
  291.                 if(dat & 0x20)                LCD_buff[6] |= k;        //T_SEG_DEFG[n];        //F
  292.                 if(dat & 0x40)                LCD_buff[4] |= k;        //T_SEG_DEFG[n];        //G
  293.         }
  294.         else        // n=4 or 5
  295.         {
  296.                 LCD_buff[1] &= ~T_LCD_mask7[n];
  297.                 LCD_buff[3] &= k;
  298.                 LCD_buff[5] &= k;
  299.                 LCD_buff[7] &= k;
  300.                 i = T_SEG_ABC[n];
  301.                 k = T_SEG_DEFG[n];
  302.                 if(dat & 0x01)                LCD_buff[7] |= i;        //T_SEG_ABC[n];                //A
  303.                 if(dat & 0x02)                LCD_buff[5] |= i;        //T_SEG_ABC[n];                //B
  304.                 if(dat & 0x04)                LCD_buff[3] |= i;        //T_SEG_ABC[n];                //C
  305.                 if(dat & 0x08)                LCD_buff[1] |= k;        //T_SEG_DEFG[n];        //D
  306.                 if(dat & 0x10)                LCD_buff[3] |= k;        //T_SEG_DEFG[n];        //E
  307.                 if(dat & 0x20)                LCD_buff[7] |= k;        //T_SEG_DEFG[n];        //F
  308.                 if(dat & 0x40)                LCD_buff[5] |= k;        //T_SEG_DEFG[n];        //G
  309.         }
  310. }


  311. /********************** 将显示内容导入显存 *****************************/
  312. void        LoadToLcd(void)
  313. {
  314.         C0SEGV1 = LCD_buff[0];    // C0SEG 15~8数据寄存器
  315.         C0SEGV2 = LCD_buff[1];    // C0SEG 23~16数据寄存器
  316.         C1SEGV1 = LCD_buff[2];    // C1SEG 15~8数据寄存器
  317.         C1SEGV2 = LCD_buff[3];    // C1SEG 23~16数据寄存器
  318.         C2SEGV1 = LCD_buff[4];    // C2SEG 15~8数据寄存器
  319.         C2SEGV2 = LCD_buff[5];    // C2SEG 23~16数据寄存器
  320.         C3SEGV1 = LCD_buff[6];    // C3SEG 15~8数据寄存器
  321.         C3SEGV2 = LCD_buff[7];    // C3SEG 23~16数据寄存器
  322. }

  323. /********************** LCD配置函数 *****************************/
  324. void        LCD_config(void)
  325. {
  326.         u8        i;

  327.         P_SW2 |= 0x80;                // SFR enable

  328.         LCDCFG  = 0x80 + 7;        // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
  329.         DBLEN   = 2;                // 设置LCD显示时的死区时间长度, 取值0~7.
  330.         COMLENH        = 0;                // COM时间长度设置 高字节COMLEN[19:16],  一共20bit.
  331.         COMLENM        = 0;                // COM时间长度设置 中字节COMLEN[15:8]        LCD刷新率 = LCD时钟频率 / ((DBLEN[2:0]+COMLEN[19:0]+1) *2 * COM数)
  332.         COMLENL        = 65;                // COM时间长度设置 低字节COMLEN[7:0]        LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
  333.         BLINKRATE = 60;                // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE[7:0] Hz

  334.         COMON  = 0x0f;                // COM使能寄存器
  335.         SEGON1 = 0x00;                // SEG线使能寄存器1, SEG7~SEG0
  336.         SEGON2 = 0xff;                // SEG线使能寄存器2, SEG15~SEG8
  337.         SEGON3 = 0x0f;                // SEG线使能寄存器3, SEG23~SEG16
  338.         SEGON4 = 0x00;                // SEG线使能寄存器4, SEG31~SEG24
  339.         SEGON5 = 0x00;                // SEG线使能寄存器5, SEG39~SEG32
  340.         P5n_pure_input(0x03);        //P5.0 P5.1 设置为高阻输入        COM0 COM1
  341.         P3n_pure_input(0x60);        //P3.5 P3.6 设置为高阻输入        COM2 COM3

  342.         LCDCFG2 = 0x0f;                        // SEG0~3切换到P7.7~7.4
  343. //        P7n_pure_input(0xf0);        //P7.7~P7.4 设置为高阻输入        SEG0~SEG3 (对应P7.7~7.4)
  344. //        P4n_pure_input(0x80);        //P4.7      设置为高阻输入        SEG4
  345. //        P1n_pure_input(0x03);        //P1.1~P1.0 设置为高阻输入        SEG5 SEG6       (对应P1.1 P1.0)
  346.         P0n_pure_input(0x60);        //P0.7~P0.5 设置为高阻输入        SEG7 SEG8 SEG9  (对应P0.7 P0.6 P0.5)
  347.         P5n_pure_input(0x0C);        //P5.3 P5.2 设置为高阻输入        SEG10 SEG11     (对应P5.3 P5.2)
  348.         P0n_pure_input(0x1f);        //P0.4~P0.0 设置为高阻输入        SEG12~SEG16  (对应P0.4 ~ 0.0)
  349.         P4n_pure_input(0x60);        //P4.6 P4.5 设置为高阻输入        SEG17 SEG18
  350.         P2n_pure_input(0x80);        //P2.7~P2.0 设置为高阻输入        SEG19~SEG26  (对应P2.7~2.0)
  351. //        P4n_pure_input(0x1e);        //P4.4~P4.1 设置为高阻输入        SEG27~SEG30  (对应P4.4~4.1)
  352. //        P3n_pure_input(0x80);        //P3.7      设置为高阻输入        SEG31
  353. //        P7n_pure_input(0x0f);        //P7.3~P7.0 设置为高阻输入        SEG32~SEG35  (对应P7.3~7.0)
  354. //        P6n_pure_input(0x0f);        //P6.0~P6.3 设置为高阻输入        SEG36~SEG39  (对应P6.3~6.0)

  355.         for(i=0; i<8; i++)        LCD_buff[i] = 0x00;        //清除显示内容
  356.         LoadToLcd();        //将显示内容导入显存

  357.         LCDCR = (0<<1) + 1;        // LCD控制寄存器, 0:普通模式, 1:长暗模式, 2:长亮模式, 3:闪烁模式.  +0:禁止LCD模块,  +1:允许LCD模块.
  358. }

  359. /********************** 设置RTC时间 *****************************/
  360. u8        SetRTC(void)
  361. {
  362.         P_SW2 |= 0x80;                //SFR enable
  363.         if(year > 99)                                                return 1;
  364.         if((month == 0) || (month > 12))        return 2;
  365.         if((day == 0) || (day > 31))                return 3;
  366.         if(hour > 23)                                        return 4;
  367.         if(minute > 59)                                        return 5;
  368.         if(second > 59)                                        return 6;
  369.         INIYEAR  = year;
  370.         INIMONTH = month;
  371.         INIDAY   = day;
  372.         INIHOUR  = hour;
  373.         INIMIN   = minute;
  374.         INISEC   = second;
  375.         INISSEC  = 0;
  376.         RTCCFG   = 0x01 | 0x00;        //设置RTC时间, |0x00:选择外部32K时钟, |0x02:选择内部32K时钟.
  377.         while(RTCCFG & 0x01);        //等待初始化完成. 设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
  378.                                                         //如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
  379.         return 0;
  380. }

  381. /********************** RTC配置函数 *****************************/
  382. void        RTC_config(void)        //RTC初始化函数
  383. {
  384.         P_SW2  |= 0x80;                //SFR enable
  385.         P1n_pure_input(0xc0);                //P1.6 P1.7设置为高阻输入
  386.         P1IE = ~0xc0;                                //P1.6 P1.7关闭数字输入功能
  387.         X32KCR = 0x80 + 0x40;                //启动外部32K晶振, 低增益+0x00, 高增益+0x40.

  388.         year    = 21;
  389.         month   = 7;
  390.         day     = 29;
  391.         hour    = 12;
  392.         minute  = 0;
  393.         second  = 0;

  394.         RTCCR   = 0x01;        //使能RTC, 并开始RTC计数
  395.         SetRTC();                //设置RTC时间
  396.         RTCIF   = 0;        //中断标志, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
  397.         RTCIEN  = 0x04;        //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
  398.         ALAHOUR = 8;        //闹钟小时
  399.         ALAMIN  = 30;        //闹钟分钟
  400.         ALASEC  = 0;        //闹钟秒
  401.         ALASSEC = 0;        //闹钟1/128秒
  402. }

  403. /********************** 读取RTC时间信息 *****************************/
  404. void        RTC_read(void)
  405. {
  406.         P_SW2  |= 0x80;                //SFR enable
  407.         year    = RTC_YEAR;                // RTC的年计数值
  408.         month   = RTC_MONTH;        // RTC的月计数值
  409.         day     = RTC_DAY;                // RTC的日计数值
  410.         hour    = RTC_HOUR;                // RTC的时计数值
  411.         minute  = RTC_MIN;                // RTC的分计数值
  412.         second  = RTC_SEC;                // RTC的秒计数值
  413. //        ssecond = RTC_SSEC;                // RTC的1/128秒计数值
  414. }

  415. //========================================================================
  416. // 函数:u8        Timer0_Config(u32 reload)
  417. // 描述: timer0初始化函数.
  418. // 参数: reload: 重装值.
  419. // 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
  420. // 版本: V1.0, 2018-3-5
  421. //========================================================================
  422. u8        Timer0_Config(u32 reload)        //t=0: reload值是主时钟周期数,  t=1: reload值是时间(单位us)
  423. {
  424.         TR0 = 0;        //停止计数

  425.         if(reload >= (65536UL * 12))        return 1;        //值过大, 返回错误
  426.         if(reload < 65536UL)        AUXR |= 0x80;                //1T mode
  427.         else
  428.         {
  429.                 AUXR &= ~0x80;        //12T mode
  430.                 reload = reload / 12;
  431.         }
  432.         reload = 65536UL - reload;
  433.         TH0 = (u8)(reload >> 8);
  434.         TL0 = (u8)(reload);

  435.         ET0 = 1;        //允许中断
  436.         TMOD = (TMOD & ~0x03) | 0;        //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
  437.         TR0 = 1;                        //开始运行
  438.         return 0;
  439. }

  440. //========================================================================
  441. // 函数: void timer0_int (void) interrupt TIMER0_VECTOR
  442. // 描述:  timer0中断函数.
  443. // 参数: none.
  444. // 返回: none.
  445. // 版本: V1.0, 2016-5-12
  446. //========================================================================
  447. void timer0_ISR (void) interrupt TIMER0_VECTOR
  448. {
  449.    B_20ms = 1;        //20ms时隙标志
  450. }


  451. //========================================================================
  452. // 函数: AUXR_ISR(void) interrupt 13
  453. // 描述: 扩展中断函数(中断号>=32的中断)
  454. // 参数: none.
  455. // 返回: none.
  456. // 版本: VER1.0
  457. // 日期: 2018-4-2
  458. // 备注:
  459. //========================================================================
  460. u8        isr_index;
  461. void        AUXR_ISR(void) interrupt 13
  462. {
  463.         u8        i;
  464.         switch(isr_index)
  465.         {
  466.                 case 32:                //0103H 波形发生器5 中断入口
  467.                                                 //用户中断处理代码
  468.                 break;

  469.                 case 33:                //010BH        波形发生器异常2 中断入口
  470.                                                 //用户中断处理代码
  471.                 break;

  472.                 case 34:                //0113H        波形发生器异常4 中断入口
  473.                                                 //用户中断处理代码
  474.                 break;

  475.                 case 35:                //011BH        触摸按键 中断入口
  476.                                                 //用户中断处理代码
  477.                 break;

  478.                 case 36:                //0123H        RTC 中断入口
  479.                         i = RTCIF;
  480.                         RTCIF = 0;                //中断标志, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
  481.                         if(i & 0x04)        //1/2秒中断
  482.                         {
  483.                                 B_500mS = 1;
  484.                                 P33 = ~P33;        //输出2秒周期方波, 方便测试精度
  485.                         }
  486.                 break;

  487.                 case 37:                //012BH        P0口中断入口
  488.                                                 //用户中断处理代码
  489.                 break;

  490.                 case 38:                //0133H        P1口中断入口
  491.                                                 //用户中断处理代码
  492.                 break;

  493.                 case 39:                //013BH        P2口中断入口
  494.                                                 //用户中断处理代码
  495.                 break;

  496.                 case 40:                //0143H        P3口中断入口
  497.                                                 //用户中断处理代码
  498.                 break;

  499.                 case 41:                //014BH        P4口中断入口
  500.                                                 //用户中断处理代码
  501.                 break;

  502.                 case 42:                //0153H        P5口中断入口
  503.                                                 //用户中断处理代码
  504.                 break;

  505.                 case 43:                //015BH        P6口中断入口
  506.                                                 //用户中断处理代码
  507.                 break;

  508.                 case 44:                //0163H        P7口中断入口
  509.                                                 //用户中断处理代码
  510.                 break;

  511.                 case 45:                //016BH        P8口中断入口
  512.                                                 //用户中断处理代码
  513.                 break;

  514.                 case 46:                //0173H        P9口中断入口
  515.                                                 //用户中断处理代码
  516.                 break;

  517.                 default:
  518.                 break;
  519.         }
  520. }
复制代码
Keil代码下载: STC8H4K64TLCD-LCD-RTC-Demo-20220810.zip (131.77 KB, 下载次数: 36)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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