久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 1413|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

48單片機(jī)鬧鐘設(shè)計(jì) 內(nèi)部時(shí)鐘源無(wú)法高精度校準(zhǔn),每20分鐘較標(biāo)準(zhǔn)時(shí)鐘快1秒

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:489155 發(fā)表于 2019-3-12 13:09 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
/*
*內(nèi)部時(shí)鐘源無(wú)法高精度校準(zhǔn),每20分鐘較標(biāo)準(zhǔn)時(shí)鐘快1秒,可通過(guò)代碼修正
*/
#include <iom48v.h>
#define BUTTON_REPEAT_TIME 19 //按鍵重復(fù)速度,N個(gè)數(shù)值(N+1)*4ms
void clockInit(void);
void IOInit(void);
void timerInit(void);
void TIM0_COMPA(void);
void TIMER1_OVF(void);
void ringTheBell(void);
void canaelTheBell(void);
const unsigned char tubeData[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};//0-9
typedef struct{
    unsigned char hours;
    unsigned char minutes;
    unsigned char isAlarmEnable;
}Clock;
struct{
    unsigned char data[4];
    unsigned char dot[4];
}s;
Clock baseClock={12,30,0},alarmClock={0};
unsigned char buttonRepeatTime=0;
unsigned char second=0;
unsigned timerInterruptTimes=0;
unsigned char setAlarm=0;
unsigned char alarming=0;
unsigned char currentTube=0;
unsigned short ringToneCursor=10;
unsigned char cursorDirection=1;
void main(void)
{
    s.data[0]=baseClock.hours/10;
    s.data[1]=baseClock.hours%10;
    s.data[2]=baseClock.minutes/10;
    s.data[3]=baseClock.minutes%10;
    clockInit();
    IOInit();
    timerInit();
    SREG|=0X80;
while(1);
}

void IOInit(void){
/*
*PB1為蜂鳴器,2-5為按鍵輸入,4設(shè)置鬧鐘和確認(rèn),5取消鬧鐘功能,2,3改變時(shí)和分
*PC0-3為數(shù)碼管位選
*PD為數(shù)碼管段選
*/
  MCUCR&=0xEF;//清零PUD,使能上拉
  DDRB=0XC2;//0-3輸入
  PORTB|=0X3C;//2-5輸出高電平
  DDRC|=0X0F;//0-3為輸出
  PORTC|=0X0E;//0-3輸出高,數(shù)碼管關(guān)閉
  DDRD=0XFF;//全部為輸出
  PORTD=0XFF;//關(guān)閉數(shù)碼管
}
void timerInit(void)
{
    /*
    *定時(shí)器0用于定時(shí)刷新數(shù)碼管,62Hz左右;定時(shí)檢測(cè)按鍵
    *定時(shí)器1用于輸出音頻
    */
  TCCR0A=0X02;//CTC模式,匹配即清零計(jì)數(shù)
  TIMSK0=0X02;//使能A匹配中斷
  OCR0A=249;//時(shí)鐘產(chǎn)生250Hz的中斷
  TCCR0B=0X02;//選擇時(shí)鐘為64分頻,計(jì)數(shù)器開(kāi)始計(jì)數(shù)
}
#pragma interrupt_handler TIM0_COMPA:15
void TIM0_COMPA(void)
{
    //處理按鍵事件
  if(~(PINB|0XC3))
  {
        buttonRepeatTime++;
        if(buttonRepeatTime>BUTTON_REPEAT_TIME)
  {
            buttonRepeatTime=0;
            if(~(PINB|0XDF))
   {//判斷取消鬧鈴按鍵是否按下,優(yōu)先級(jí)最高
                //顯示回當(dāng)前時(shí)間
                s.data[0]=baseClock.hours/10;
                s.data[1]=baseClock.hours%10;
                s.data[2]=baseClock.minutes/10;
                s.data[3]=baseClock.minutes%10;
                alarmClock.isAlarmEnable=0;//關(guān)閉鬧鐘
                s.dot[3]=0;//熄滅鬧鐘指示點(diǎn)
                setAlarm=0;//狀態(tài)切換
                if(alarming)//關(guān)閉鬧鐘
    {
                    alarming=0;
                    canaelTheBell();
                }
            }
   else if(~(PINB|0XEF)) //判斷設(shè)置確定按鍵
   {
                if(setAlarm)
    {
                    //保存設(shè)置
                    alarmClock.isAlarmEnable=1;
                    s.dot[3]=1;
                    //顯示回當(dāng)前時(shí)間
                    s.data[0]=baseClock.hours/10;
                    s.data[1]=baseClock.hours%10;
                    s.data[2]=baseClock.minutes/10;
                    s.data[3]=baseClock.minutes%10;
                }
    else
    {
                    //顯示上次保存的鬧鐘時(shí)間
                    s.data[0]=alarmClock.hours/10;
                    s.data[1]=alarmClock.hours%10;
                    s.data[2]=alarmClock.minutes/10;
                    s.data[3]=alarmClock.minutes%10;
                    s.dot[1]=0;//熄滅秒顯示點(diǎn)
                }
                setAlarm=!setAlarm;
            }
   else
   {
                //設(shè)置當(dāng)前顯示的時(shí)間數(shù)值
                if(setAlarm)
    {
                    if(~(PINB|0XFB)) alarmClock.hours=alarmClock.hours<23?alarmClock.hours+1:0;
                    if(~(PINB|0XF7)) alarmClock.minutes=alarmClock.minutes<59?alarmClock.minutes+1:0;
                    s.data[0]=alarmClock.hours/10;
                    s.data[1]=alarmClock.hours%10;
                    s.data[2]=alarmClock.minutes/10;
                    s.data[3]=alarmClock.minutes%10;
                }
    else
    {
                    //重置秒計(jì)數(shù)和定時(shí)器計(jì)數(shù)
                    timerInterruptTimes=0;
                    second=0;
                    s.dot[1]=0;
                    if(~(PINB|0XFB)) baseClock.hours=baseClock.hours<23?baseClock.hours+1:0;
                    if(~(PINB|0XF7)) baseClock.minutes=baseClock.minutes<59?baseClock.minutes+1:0;
                    s.data[0]=baseClock.hours/10;
                    s.data[1]=baseClock.hours%10;
                    s.data[2]=baseClock.minutes/10;
                    s.data[3]=baseClock.minutes%10;
                }
            }
        }
  }
  else buttonRepeatTime=0;
  //時(shí)間定時(shí)
  if(timerInterruptTimes>=249)  //第250個(gè)中斷
  {
        timerInterruptTimes=0;
        //第二點(diǎn)閃爍,指示秒
        if(!setAlarm) s.dot[1]=!s.dot[1];
        if(second>=59)
  {
            //重新計(jì)算時(shí)間
            second=0;
            if(baseClock.minutes>=59)
   {
                baseClock.minutes=0;
                baseClock.hours=baseClock.hours<23?baseClock.hours+1:0;
            }
   else baseClock.minutes++;
            //刷新數(shù)碼管時(shí)間值
            if(!setAlarm)
   {
                s.data[0]=baseClock.hours/10;
                s.data[1]=baseClock.hours%10;
                s.data[2]=baseClock.minutes/10;
                s.data[3]=baseClock.minutes%10;
            }
        } else second++;
            //判斷鬧鐘是否匹配
            if(alarmClock.isAlarmEnable&&baseClock.hours==alarmClock.hours&&baseClock.minutes==alarmClock.minutes)
   {
                if(!alarming)
    {
                    alarming=1;
                    ringTheBell();
                }
            }
   else if(alarming)
   {
                alarming=0;
                canaelTheBell();
            }
  }
  timerInterruptTimes++;
  //刷新數(shù)碼管
    currentTube=currentTube<3?currentTube+1:0;
    PORTD=0XFF;//熄滅數(shù)碼管
    PORTC=0XFF;//關(guān)閉位控
    PORTC&=~(1<<currentTube);//1左移currentTube位
    PORTD=tubeData[s.data[currentTube]];
    if(s.dot[currentTube]) PORTD&=0X7F;
}
#pragma interrupt_handler TIMER1_OVF:14
void TIMER1_OVF(void)
{
    OCR1AH=ringToneCursor/256;
    OCR1AL=ringToneCursor%256;
    if(cursorDirection)
{
        if(ringToneCursor<1790)
  {
            ringToneCursor++;
        }
  else cursorDirection=0;
    }else
{
        if(ringToneCursor>500)
  {
            ringToneCursor--;
        }
  else cursorDirection=1;
    }
}
void ringTheBell(void)
{
  OCR1AH=0;//修改占空比數(shù)值,有緩存器,會(huì)在BOTTOM修改
  OCR1AL=10;
  TIMSK1=0X01;//開(kāi)啟溢出中斷
  TCNT1H=0;//歸零計(jì)數(shù)器
  TCNT1L=0;
  ICR1H=0X07;//0X01//設(shè)置輸出頻率,稍大于11025
  ICR1L=0X08;//0X69
  TCCR1B=0X19;
  TCCR1A=0X82;//快速PWM模式,在BOTTOM置位,匹配清零,時(shí)鐘無(wú)分頻
}
void canaelTheBell(void)
{
    //關(guān)閉音頻輸出步驟
  TCCR1B=0;//先關(guān)閉時(shí)鐘
  TCCR1A=0X80;//修改模式為匹配時(shí)清零
  TCCR1C=0;//強(qiáng)制輸出為低,關(guān)閉音頻
}



評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩一二区在线观看 | 精品在线观看一区 | 日韩欧美在线视频播放 | 91性高湖久久久久久久久_久久99 | 中文字幕亚洲视频 | 亚洲欧洲日韩精品 中文字幕 | 亚洲 中文 欧美 日韩 在线观看 | 91精品久久久久久久久99蜜臂 | 在线观看中文字幕 | 亚洲电影一区二区三区 | 青青久草 | 色在线看 | 爱爱视频网 | 亚洲成人高清 | 在线视频国产一区 | 国产最新精品视频 | 精品国产一区二区 | 一级毛片免费视频观看 | 黄网站免费在线 | 久热电影 | 国产欧美日韩一区二区三区在线 | 国内av在线 | 亚洲欧美综合精品久久成人 | 麻豆精品一区二区三区在线观看 | 密室大逃脱第六季大神版在线观看 | 国产小视频在线 | 中国av在线免费观看 | 男女免费在线观看视频 | 亚洲精品成人av | 精品综合久久久 | 国产一区二区三区不卡av | 欧洲亚洲精品久久久久 | 国产精品伦理一区 | 狠狠久久综合 | 久久久久亚洲 | 日韩福利 | 91视频在线 | 色婷婷综合在线观看 | 久草免费视 | 亚洲一区二区在线视频 | 国产精品av久久久久久久久久 |