[方案相关] 【原创】基于HC32L136开发板的RTC电子时钟

[复制链接]
4320|12
 楼主| jinglixixi 发表于 2020-10-31 16:59 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2020-10-31 17:13 编辑

在HC32L136的例程中,只有笔段式液晶屏的测试程序,却没有提供一个可供用户直接调用的数值显示函数。
为此在了解液晶屏的工作原理后,在原例程的基础上完成了它的数值显示函数。
1. 液晶屏工作原理及显示编码
在HC32L136开发板上,所配置的液晶屏为4位数字式显示屏并配有小数点和时间分隔符,其布局如图1所示。

1.jpg
图1 液晶屏笔段布局显示
尽管笔段式液晶屏在显示显示上与数码管十分相近,但在工作原理和机制上却差别很大。
以数码管为例,它是通过段码和位码来控制显示的,编写好段码表后,只需把段码送到位码控制的位置即可显示出相应的内容。
例如“1”的显示码为0x06,即0000 0110对应CB被点亮。
而对于液晶屏就不同了,它是按节拍来完成代码的输出,按显示位置的不同,是将显示笔段分成4组,每组占2位,共8位。而每组内,相同位置所控制的笔段名称相同,故只需定义一组编码即可,然后按显示的位置进行移位处理即可(例如第一组需移动6位,第二组需移动4位第三组需移动2位)。
若每组显示码占2个字节,则可到如下的显示码表:
z.jpg
2.显示程序
1)定义显示数组
#define     LCD_POINT      0X0008
const uint16_t  lcd_tab[16] =
{
  0x0F05, 0x0600, 0x0B06, 0x0F02,0x0603, 0x0D03, 0x0D07, 0x0700, 0x0F07, 0x0F03,
  0x0707, 0x0C07, 0x0905, 0x0E05,0x0907, 0x0107,
};

2)寄存器设置函数
  1. en_result_t Lcd_WriteRam(uint8_t u8Row,uint32_t u32Data)
  2. {
  3. en_result_t  enRet = Error;
  4. volatile uint32_t *ram = NULL;
  5. ram = (volatile uint32_t*)&M0P_LCD->RAM0;
  6. if (u8Row > 15)
  7. {
  8. enRet = ErrorInvalidParameter;
  9. return enRet;
  10. }
  11. ram += u8Row;
  12. *ram = u32Data;
  13. enRet = Ok;
  14. return  enRet;
  15. }


3)清屏函数
  1. void Lcd_ClearDisp(void)
  2. {
  3. uint8_t tmp;
  4. volatile uint32_t *ram = NULL;
  5. ram = &M0P_LCD->RAM0;
  6. for(tmp=0;tmp<16;tmp++)
  7. {
  8. *ram = 0;
  9. ram++;
  10. }
  11. }

4)显示函数
  1. void LCD_Display(uint16_t * str)
  2. {
  3. uint32_t   n;
  4. n   = str[1];
  5. n <<= 16;
  6. n  += str[0];
  7. M0P_LCD->RAM0 = n;
  8. n   = str[3];
  9. n <<= 16;
  10. n  += str[2];
  11. M0P_LCD->RAM1 = n;   
  12. }

3. RTC电子时钟
在HC32L136内部配置了RTC计时器,将它与SLCD液晶屏配合即可实现一个RTC电子时钟。
实现电子时钟的主程序为:
  1. int32_t main(void)
  2. {
  3. uint32_t       i;
  4. uint16_t       str[4];
  5. Sysctrl_ClkSourceEnable(SysctrlClkRCL,TRUE);
  6. Sysctrl_SetRCLTrim(SysctrlRclFreq32768);
  7. Sysctrl_SetPeripheralGate(SysctrlPeripheralLcd,TRUE);
  8. Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
  9. App_PortCfg();
  10. App_LcdCfg();
  11. Lcd_ClearDisp();
  12. stc_rtc_time_t readtime;
  13. Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
  14. Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc,TRUE);
  15. Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
  16. RTC_Cfg();
  17. EnableNvic(RTC_IRQn, IrqLevel3, TRUE);
  18. Rtc_Cmd(TRUE);
  19. while (1)
  20. {
  21. M0P_GPIO->PDOUT ^= (1U << 5);
  22. if(flag == 1)
  23. {
  24. flag = 0;
  25. Rtc_ReadDateTime(&readtime);
  26. second = readtime.u8Second;
  27. minute = readtime.u8Minute;
  28. hour   = readtime.u8Hour;
  29. str[0] = lcd_tab[minute>>4];
  30. str[1] = lcd_tab[minute&0x0f]|LCD_POINT;
  31. str[2] = lcd_tab[second>>4];
  32. str[3] = lcd_tab[second&0x0f];
  33. LCD_Display(str);
  34. }
  35. delay1ms(500);
  36. }
  37. }

有了显示程序固然可喜,但下载工具的作用也是必不可少的,本人使用的第三方的下载工具,并通过虚拟串口来完成下载,见图2和图3所示。

2.jpg
图2 下载工具

3.jpg

图3 下载过程

在下载程序后,其显示效果如图4和图5所示。

4.jpg
图4 运行效果1

5.jpg

图5 运行效果2

工程文件:

lcd_mode.rar

3.56 KB, 下载次数: 66

zeshoufx 发表于 2020-11-2 08:54 | 显示全部楼层
谢谢分享【RTC电子时钟】
 楼主| jinglixixi 发表于 2020-11-2 10:15 | 显示全部楼层
zeshoufx 发表于 2020-11-2 08:54
谢谢分享【RTC电子时钟】

感谢支持!!!
LG_qiuzhi 发表于 2020-11-7 10:14 | 显示全部楼层
楼主,你的下载附件只是一个Hex文件。是否可以将整个工程贡献出来呢
fjhcpu 发表于 2020-11-8 16:29 | 显示全部楼层
可以用ST_LINk 下载程序吗?
 楼主| jinglixixi 发表于 2020-11-8 20:01 | 显示全部楼层
fjhcpu 发表于 2020-11-8 16:29
可以用ST_LINk 下载程序吗?

没有,在试过的调试器中似乎只是图示的能使。
rickluo 发表于 2020-11-12 10:58 | 显示全部楼层
多谢楼主分享
晓伍 发表于 2020-11-13 12:45 | 显示全部楼层
需要多长时间校准一次
磨砂 发表于 2020-11-13 12:46 | 显示全部楼层
可以联网进行校正吗
 楼主| jinglixixi 发表于 2020-11-13 13:06 | 显示全部楼层
磨砂 发表于 2020-11-13 12:46
可以联网进行校正吗

不进行功能扩展的情况下没戏!
 楼主| jinglixixi 发表于 2020-11-13 13:08 | 显示全部楼层
晓伍 发表于 2020-11-13 12:45
需要多长时间校准一次

依个人的条件无法给出精确的结论,我估计也就是常规RTC模块之类的水准。
czjdxs 发表于 2021-11-10 16:58 | 显示全部楼层
有做低功耗吗?
gududedianzi 发表于 2021-11-12 09:52 | 显示全部楼层
谢谢分享 拿来学习学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则

521

主题

2949

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部