- 打卡等级:初来乍到
- 打卡总天数:5
- 最近打卡:2024-05-13 19:00:29
注册会员
- 积分
- 156
|
本帖最后由 热烈的马 于 2023-3-27 15:57 编辑
我用的是梁工的”04-RTC基本操作-5位液晶显示时间“例程,改rtc和lcd的时钟为内部 32K 振荡器后,lcd表现为每1秒闪烁一次,其他时间熄灭。
硬件连接方式和梁工相同,程序只做了rtc和lcd晶振的选择修改。
我的问题主要是在于单片机进入停机模式后,lcd熄灭了没有继续保持显示之前的内容。
下面是我的部分代码,其他部分见附件
/********************** LCD配置函数 *****************************/
void LCD_config(void)
{
u8 i;
P_SW2 |= 0x80; // SFR enable
// LCDCFG = 0x80 + 7; // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
LCDCFG = 0x00 + 7;
DBLEN = 2; // 设置LCD显示时的死区时间长度, 取值0~7.
COMLENH = 0; // COM时间长度设置 高字节COMLEN[19:16], 一共20bit.
COMLENM = 0; // COM时间长度设置 中字节COMLEN[15:8] LCD刷新率 = LCD时钟频率 / ((DBLEN[2:0]+COMLEN[19:0]+1) *2 * COM数)
COMLENL = 65; // COM时间长度设置 低字节COMLEN[7:0] LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
BLINKRATE = 60; // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE[7:0] Hz
COMON = 0x0f; // COM使能寄存器
SEGON1 = 0x00; // SEG线使能寄存器1, SEG7~SEG0
SEGON2 = 0xff; // SEG线使能寄存器2, SEG15~SEG8
SEGON3 = 0x0f; // SEG线使能寄存器3, SEG23~SEG16
SEGON4 = 0x00; // SEG线使能寄存器4, SEG31~SEG24
SEGON5 = 0x00; // SEG线使能寄存器5, SEG39~SEG32
P5n_pure_input(0x03); //P5.0 P5.1 设置为高阻输入 COM0 COM1
P3n_pure_input(0x60); //P3.5 P3.6 设置为高阻输入 COM2 COM3
LCDCFG2 = 0x0f; // SEG0~3切换到P7.7~7.4
// P7n_pure_input(0xf0); //P7.7~P7.4 设置为高阻输入 SEG0~SEG3 (对应P7.7~7.4)
// P4n_pure_input(0x80); //P4.7 设置为高阻输入 SEG4
// P1n_pure_input(0x03); //P1.1~P1.0 设置为高阻输入 SEG5 SEG6 (对应P1.1 P1.0)
P0n_pure_input(0x60); //P0.7~P0.5 设置为高阻输入 SEG7 SEG8 SEG9 (对应P0.7 P0.6 P0.5)
P5n_pure_input(0x0C); //P5.3 P5.2 设置为高阻输入 SEG10 SEG11 (对应P5.3 P5.2)
P0n_pure_input(0x1f); //P0.4~P0.0 设置为高阻输入 SEG12~SEG16 (对应P0.4 ~ 0.0)
P4n_pure_input(0x60); //P4.6 P4.5 设置为高阻输入 SEG17 SEG18
P2n_pure_input(0x80); //P2.7~P2.0 设置为高阻输入 SEG19~SEG26 (对应P2.7~2.0)
// P4n_pure_input(0x1e); //P4.4~P4.1 设置为高阻输入 SEG27~SEG30 (对应P4.4~4.1)
// P3n_pure_input(0x80); //P3.7 设置为高阻输入 SEG31
// P7n_pure_input(0x0f); //P7.3~P7.0 设置为高阻输入 SEG32~SEG35 (对应P7.3~7.0)
// P6n_pure_input(0x0f); //P6.0~P6.3 设置为高阻输入 SEG36~SEG39 (对应P6.3~6.0)
for(i=0; i<8; i++) LCD_buff = 0x00; //清除显示内容
LoadToLcd(); //将显示内容导入显存
LCDCR = (0<<1) + 1; // LCD控制寄存器, 0:普通模式, 1:长暗模式, 2:长亮模式, 3:闪烁模式. +0:禁止LCD模块, +1:允许LCD模块.
}
/********************** 设置RTC时间 *****************************/
u8 SetRTC(void)
{
P_SW2 |= 0x80; //SFR enable
if(year > 99) return 1;
if((month == 0) || (month > 12)) return 2;
if((day == 0) || (day > 31)) return 3;
if(hour > 23) return 4;
if(minute > 59) return 5;
if(second > 59) return 6;
INIYEAR = year;
INIMONTH = month;
INIDAY = day;
INIHOUR = hour;
INIMIN = minute;
INISEC = second;
INISSEC = 0;
// RTCCFG = 0x01 | 0x00; //设置RTC时间, |0x00:选择外部32K时钟, |0x02:选择内部32K时钟.
RTCCFG = 0x01 | 0x02;
while(RTCCFG & 0x01); //等待初始化完成. 设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
//如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
return 0;
}
/********************** RTC配置函数 *****************************/
void RTC_config(void) //RTC初始化函数
{
P_SW2 |= 0x80; //SFR enable
P1n_pure_input(0xc0); //P1.6 P1.7设置为高阻输入
P1IE = ~0xc0; //P1.6 P1.7关闭数字输入功能
// X32KCR = 0x80 + 0x40; //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
IRC32KCR = 0x80; //启动内部 32K 振荡器
while (!(IRC32KCR & 0x01)); //等待时钟稳定
year = 21;
month = 7;
day = 29;
hour = 12;
minute = 0;
second = 0;
RTCCR = 0x01; //使能RTC, 并开始RTC计数
SetRTC(); //设置RTC时间
RTCIF = 0; //中断标志, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
RTCIEN = 0x04; //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
ALAHOUR = 8; //闹钟小时
ALAMIN = 30; //闹钟分钟
ALASEC = 0; //闹钟秒
ALASSEC = 0; //闹钟1/128秒
}
|
|