小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

[51單片機] 初學者自制的時鐘:每行代碼都有備注,進來不虧

 一瓢若水 2013-04-13
[51單片機] 初學者自制的時鐘:每行代碼都有備注,進來不虧
郭天祥老師實驗板做的時鐘,代碼每一行都有備注;非常適合初學者!因為我也是初學者,可以一起交流啊。
所用技術:定時器,矩陣鍵盤,1602液晶,51單片機,中斷,I2C保存時間,串口通信,串口緩沖區(qū)(核心),串口協(xié)議頭(核心),時間緩沖區(qū)(核心),定時器復用技術(核心),狀態(tài)機編程思想(核心),多文件編程技術,預處理技術等等,非常適合初學者。先看大概的,然后你決定要不要下載整個代碼。
/*********************************************************
文件名稱:shizhong.C  主控芯片STC89C52RC     晶振11.0592MHz
功能描述:時鐘(1602,IIC,按鍵,串行接口)
作者日期:田衛(wèi)衛(wèi) / 2013222
    本:V1.1
*********************************************************/
#include"define.H"        //公共頭文件,可替代reg52.h
#include"dulikey.h"              //按鍵頭文件:按鍵掃描、按鍵服務
#include"LCD1602.h"           //1602液晶頭文件
#include"clock.h"          //時鐘頭文件:初始化時鐘、及時鐘走時分秒,每秒寫I2C保存時間
#include"time.h"           //定時器、延時函數等
#include"sio.h"             //串口初始化、接收、串口服務函數等。
void main()
{     
       sio_init();       //串口初始化函數
       InitTimer0();  //定時器0初始化函數
       ClockInit();    //時鐘顯示界面初始化
       while(1)
       {
              KeyService(clock);        //調用鍵盤服務函數
              sio_service();         //調用串口服務函數
              WRclock ();    //調用時鐘計時函數
       }            
}
#include"define.H"
#include"clock.h"
#include"time.h"
#include"LCD1602.h"
#include"I2C.h"
#include"dulikey.h"
uchar code clock1[]="I Like Clock";    //液晶第一排
uchar clock[]={23,59,50};    //時間緩沖區(qū)
void ClockInit()
{
//    Write(clock,1,3);    //////////////////////////調試初始化用的,把“時:分:秒”寫入I2C      
       Delayms(1000);            //上電后等電壓穩(wěn)定
       Read(1,3,clock);     /*I2C器件第1個存儲區(qū)開始,連續(xù)讀取3個字節(jié),放入時間緩沖區(qū)中*/
       Lcd_init();                           /*LCD1602液晶初始化函數*/
      
       WRLCD();     //把時間緩沖區(qū)“時:分:秒”,寫在液晶屏上。
       TaskCount[1] = 500;             // TO進中斷的次數:500
       TaskMark[1]  = 0;        // 啟動此任務的定時器
}
void WRclock ()    //時鐘計時程序
{
       if (TaskMark[1] == 1)  //1秒標記,定時器中斷2ms*500次;
       {
              clock[2]++;           //+1
              TaskMark[1] = 0;          //1秒標記 清零
              if (clock[2]==60)   // = 60?
              {
                     clock[2]=0;            //=60!秒=0;
                     clock[1]++;           //+1
                     if (clock[1]==60)   // = 60?
                     {
                            clock[1]=0;            //=60!分=0
                            clock[0]++;           //+1
                            if (clock[0]==24)   //= 24?
                                   clock[0]=0;            //=24!時=0                 
                     }
              }
              Write(&clock[0],1,3);    //I2C
              WRLCD();     //把時間緩沖區(qū)“時:分:秒”,寫在液晶屏上。
       }
}
/*********************************************************
文件名稱:sio.c           主控芯片:STC89C52RC            晶振11.0592MHz
功能描述:串口程序
函數名稱:含串口中斷函數!其余函數詳見頭文件sio.h
作者日期:田衛(wèi)衛(wèi) / 2013221
    本:V1.0
*********************************************************/
#include"define.h"
#include"sio.h"
#include"time.h"
#include"lcd1602.h"
#define T1MS_1200bps   0xe8;     /* (e8,-24,SMOD=0) @1200bps  pcon&=0x7f @11.0592MHz*/
#define T1MS_2400bps   0xf4;     /* (f4,-12,SMOD=0) @2400bps  pcon&=0x7f */
#define T1MS_4800bps   0xfa;     /* (fa, -6,SMOD=0) @4800bps  pcon&=0x7f */
#define T1MS_9600bps   0xfd;     /* (fd, -3,SMOD=0) @9600bps  pcon&=0x7f */
#define T1MS_19k2bps   0xfd;     /* (fd, -3,SMOD=1) @19.2kbps pcon|=0x80 */
#define SIOADDNUM  3     //協(xié)議頭數;設置為0,可以關閉協(xié)議頭。
uchar code SIOADD[SIOADDNUM]={0xeb,0x00,0xaa};  //定義串口協(xié)議頭
uchar inbuf[BUFS];              //串口接收緩沖區(qū)
uchar buf = 0;               //統(tǒng)計串口接收到本次數據包的總數量。
/*********************************************************
函數名稱:sio_service();
功能描述:串口服務程序,處理串口接收緩沖區(qū)inbuf[]的數據。
輸入參數:全局變量 buf,TaskMark[0]
包含函數:send(uchar dat);
作者日期:田衛(wèi)衛(wèi) / 2013221
*********************************************************/
void sio_service()
{
       if(TaskMark[0] != 0)     //如果為真,說明收到了數據,而且本次數據包接收已經結束。
       {
              uchar i=0,buf_temp=0;         //串口緩沖區(qū)服務程序當前指向位置。
              while (buf_temp < SIOADDNUM)      //協(xié)議頭處理核心:循環(huán)SIOADDNUM次,判斷協(xié)議頭。
              {
                     if (inbuf[buf_temp] == SIOADD)           //協(xié)議頭處理核心:協(xié)議頭相同
                     {
                            i++;               //協(xié)議頭處理核心:指向下一個要判斷的協(xié)議頭
                            buf_temp++;   //協(xié)議頭處理核心:指向下一個要判斷的協(xié)議頭
                     }
                     else                       //協(xié)議頭處理核心:協(xié)議頭錯誤
                     {
                            buf_temp = 0; //協(xié)議頭處理核心:清零
                            buf = 0;          //協(xié)議頭處理核心:清零
                            break;            //協(xié)議頭處理核心:退出本次循環(huán)
                     }                  
              }
              if (buf_temp < buf)
              {
                     if (inbuf[buf_temp]==0 | inbuf[buf_temp]==1)          //判斷第4字節(jié)是0,還是1;用戶可以自定義。
                     {
                            lcdflag = inbuf[buf_temp];    //把串口接收到得第4個字節(jié)給LCD顯示標記
                            buf_temp++;   //指向下一個串口接收到得元素
                            WRLCD();     //寫液晶屏。
                     }
              }
              ES = 0;   //先關中斷     
              while (buf_temp < buf)  //協(xié)議頭,如果相等,才會跑到這兒
              {
                     send(inbuf[buf_temp]);  //調用串口發(fā)送函數,把協(xié)議頭以后所接收到的數據原封不動發(fā)給上位機
                     buf_temp++;          //指向下一個要發(fā)送的數據
              }
              ES = 1;          //剛才關了中斷,現在要打開,以備下次接收。
              TaskMark[0]  = 0;        // 此任務的定時標志清零
              buf = 0;                 //關鍵:統(tǒng)計串口接收到本次數據包的總數量--清零。
       }
}
/*********************************
函數名:sio_int(sio interrupt)
功能:中斷+緩沖區(qū)方式接收串口數據,把收到的一個字節(jié)放在inbuf[bufnum].
*********************************/
void  sio_int() interrupt 4
{
       ES=0;
       if(RI)        /* RI==1 */
       {  
              if (buf < BUFS)            //小于緩沖區(qū)溢出上限,為真可以接收
              {
                     inbuf[buf] = SBUF;       //讀串口數據,放入緩沖區(qū)中
                     buf++;           //緩沖區(qū)指向下一個存放位置。
                     TaskCount[0] = 5;         // 啟動一個定時器中斷延時
                     TaskMark[0]  = 0;        // 啟動此任務的定時器
              }
              else                       //大于或等于緩沖區(qū)上限,說明本次接收的數據可能被截掉了:錯誤!
              {
                     beep = 0;        // 蜂鳴器響;切勿刪除:可作為串口穩(wěn)定性的參考。
              }            
              RI=0;
       }
       ES=1;
}
/*********************************
函數名:send(uchar dat)
功能:向串口發(fā)送數據
*********************************/
void send(uchar dat)
{
       SBUF=dat;
       while(!TI);
       TI=0;
}
/*********************************
函數名:sel_bps(select bps)
功能:設置串口波特率
sel為選擇通訊速率:
  0=1200,1=2400,2=4800,3=9600,4=19.2k
*********************************/
void sel_bps(uchar sel)
{
     switch(sel)
     {
        case 0:PCON&=0x7f;
               TH1=T1MS_1200bps;   /* T1 use sio */
               TL1=T1MS_1200bps;
               break;
        case 1:PCON&=0x7f;
               TH1=T1MS_2400bps;   /* T1 use sio */
               TL1=T1MS_2400bps;
               break;
        case 2:PCON&=0x7f;
               TH1=T1MS_4800bps;   /* T1 use sio */
               TL1=T1MS_4800bps;
               break;
        case 3:PCON&=0x7f;
               TH1=T1MS_9600bps;   /* T1 use sio */
               TL1=T1MS_9600bps;
               break;
        case 4:PCON|=0x80;
               TH1=T1MS_19k2bps;   /* T1 use sio */
               TL1=T1MS_19k2bps;
               break;
     }
}
/*********************************
函數名:tran_init()(tranmit initialize)
功能:串口初始化
     串口通訊參數初始化
包含子函數:sel_bps
*********************************/
void sio_init()        /* 通訊有關參數初始化 */
{
/* 定時器初始化 */
       TMOD=0x21;  /* T1=MODE2,sio; T0=MODE1,16bit,use time */
       sel_bps(3); /* 選擇通訊速率:0=1200,1=2400,2=4800,3=9600,4=19.2k */
/* SCON寄存器設置 */
       SM0=0;
       SM1=1; /* SM0=0 SM1=1,mode1,10bit          */
       SM2=0; /* data int,無校驗(TB8=bit_duble) */
       REN=1; /* 允許串口接收 */
       TI=0;  /* 清空發(fā)送中斷標志位 */
       RI=0;  /* 清空接收中斷標志位 */
/* IEIP寄存器設置 */
     PS=1;  /* SIO int high  優(yōu)先級 */
       ET1=0; /*  定時器1串口中斷 */
       ES=1;  /*  串口中斷 */
       EA=1;  /*  全局中斷 */
       TR1=1; /* 啟動 定時器1 */      
}
/*********************************
文件名稱:time.C        主控芯片:STC89C52RC
功能描述:延時函數
作者日期:田衛(wèi)衛(wèi) / 2013215
    本:V1.0
*********************************************************/
#include"define.H"
#include"time.h"
#include"dulikey.h"
#include<intrins.h>
uint TaskCount[TASK_NUM];             //定義變量:為定時任務存放定時值;
uchar  TaskMark[TASK_NUM];         //標志位,0表示時間沒到,1表示定時的時間到。
/*///////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
       InitTimer0();
}
/////////////////////////////////////////////////////////////////////////////////////////
TaskCount[0] = 20;        // TO進中斷的次數:20
TaskMark[0]  = 0;        // 啟動此任務的定時器
///////////////////////////////////////////////////////////////////////////////////////*/
void InitTimer0()
{
       TMOD = 0x21;
       TH0 = 0xF8;
       TL0 = 0xcc;
       EA = 1;
       ET0 = 1;
       TR0 = 1;
}
////////////////////////////////////////////////////////////////////////////////////////
void Timer0Int(void) interrupt 1
{
       uchar i;
       TH0 = 0xF8;   //定義為2ms中斷一次;中斷太頻繁效率低,中斷太久實時性差。
       TL0 = 0xcc;
       for (i=0; i<TASK_NUM; i++)     //循環(huán)檢查TASK_NUM的任務。任務定義見頭文件。這里是核心知識:定時器復用技術。
       {
              if (TaskCount)
              {
                     TaskCount--;
                     if (TaskCount == 0)          //只有被定時器減的TaskCount,才置標志位!
                     {
                            TaskMark = 0x01;
                     }
              }
       }
       KeyScan();
}
////////////////////////////////////////////////////////////////////////////////////////
void Delayms(uint xms)
{
       uint i,j;
       for(i=0;i<xms;i++)
              for(j=0;j<110;j++);
}
////////////////////////////////////////////////////////////////////////////////////////
/*NOP延時函數,單位 微秒*/
void delay()
{
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
}

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多