自学开天斧第22课:
学习内容:RTC详解+无源蜂鸣器(定时器控制IO)+OLED显示
学习简介:本次学习STC8H8K64U内部RTC,在OLED上显示时间,启动闹钟,到点蜂鸣器鸣叫
实验项目:①、通过配置RTC在OLED显示时间 ②、设置闹钟,到点开启Timer0输出时钟给无源蜂鸣器IO口提供振动(P35) ③、开启闹钟中断,到点时蜂鸣器按规律鸣叫(停300ms,叫200ms)
④、开启秒中断,每秒P20口LED翻转一次 ⑤、按下P34按键关闭闹钟蜂鸣
实验重点:RTC中断、定时器&无源蜂鸣器
程序代码:
#include <STC8H.H>
#include "OLED.h"
sbit IO_buzzer = P3^5;
sbit VCC_buzzer = P5^1;
sbit GND_buzzer = P3^6;
bit Buzzer_delay;
bit Key_delay;
bit Alarm;
unsigned int Buzzer_off_count;
unsigned int Buzzer_on_count;
unsigned int Key_count;
unsigned char SEC_past;
unsigned char SEC_now;
void Timer0_Init(void) //时钟40M,定时1ms
{
AUXR |= 0x80;
TMOD &= 0xF0;
//TMOD |= 0x04;
TL0 = 0xbf;
TH0 = 0x63;
TF0 = 0;
TR0 = 1;
ET0 = 1;
INTCLKO &= 0xff;
INTCLKO &= 0xfe;
}
void RTC_Init(void)
{
IRC32KCR = 0x80; //启动内部低速振荡器
while(!(IRC32KCR & 0x01)); //等待时钟稳定
RTCCFG |= 0x02; //选择内部低速IRC
INIYEAR = 24; //设置年(00-99)
INIMONTH = 6; //设置月(1-12)
INIDAY = 12; //设置日(1-31)
INIHOUR = 18; //设置时(0-24) //设置时间:18点23分0秒
INIMIN = 23; //设置分(0-60)
INISEC = 0; //设置秒(0-60)
RTCCFG |= 0x01; //将设置的时间写入RTC
RTCIF = 0; //RTC中断清零
RTCCR = 0x01; //启动RTC
RTCIEN |= 0x88; //使能闹钟中断、秒中断
ALAHOUR = 18; //定闹钟为18点23分3秒
ALAMIN = 23;
ALASEC = 3;
}
void main()
{
P_SW2 |= 0x80;
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x02; P5M1 = 0x00; //P51配置成推挽输出
P6M0 = 0x00; P6M1 = 0x00;
P34 = 1;
VCC_buzzer = 1; GND_buzzer = 0;
OLED_Init();
OLED_ColorTurn(0);//0正常显示,1 反色显示
OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
OLED_Clear();
Timer0_Init();
RTC_Init();
EA = 1;
OLED_ShowString(0,0,"Hello world !",16);
OLED_ShowChar(34,3,':',16);
OLED_ShowChar(60,3,':',16);
while(1)
{
SEC_past = SEC_now;
SEC_now= SEC;
if(SEC_past != SEC_now)
{
OLED_ShowNum(17,3,HOUR,2,16);
OLED_ShowNum(43,3,MIN,2,16);
OLED_ShowNum(69,3,SEC,2,16);
}
if(Alarm == 1)
{
if(Buzzer_delay == 1)
{
Buzzer_delay = 0;
if(~(INTCLKO | 0xfe))
{
Buzzer_off_count++;
if(Buzzer_off_count >= 300) //蜂鸣器关闭__ms
{
Buzzer_off_count = 0;
INTCLKO |= 0x01;
}
}
if(INTCLKO & 0x01)
{
Buzzer_on_count++;
if(Buzzer_on_count >= 200) //蜂鸣器开启__ms
{
Buzzer_on_count = 0;
INTCLKO &= 0xfe;
}
}
}
if(P34==0)
{
if(Key_delay==1)
{
Key_delay = 0;
Key_count++;
if(Key_count >= 20)
{
Key_count=0;
Alarm = 0;
INTCLKO &= 0xfe;
VCC_buzzer = 0;
IO_buzzer = 1;
}
}
}
}
}
}
void Timer0_Routine(void) interrupt 1
{
Buzzer_delay = 1;
Key_delay = 1;
}
void RTC_isp(void) interrupt 13
{
if(RTCIF & 0x80)
{
RTCIF &= ~0x80;
Alarm = 1;
}
if(RTCIF & 0x08)
{
RTCIF &= ~0x08;
P20 = ~P20;
}
}
|