天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術熱線: 4007-888-234

技術支持

QLdsPIC3]實時時鐘[C30+dsPIC30F6014A]

更新時間: 2019-03-23

深圳市英銳恩科技有限公司:臺灣麥肯單片機(Micon MDT單片機)亞太地區A級代理商

QLdsPIC3]實時時鐘[C30+dsPIC30F6014A]
//實驗目的:熟悉時鐘芯片PCF8583以及IIC通信
//軟件規劃:
//         1,通過按下按鍵K7往時鐘芯片內寫入預設時間和日期為,包括毫秒、秒、分、時、日、月、年、星期
//         2、通過查詢時鐘芯片觸發的中斷讀取時間(1秒執行一次)
//         3、時間和日期送LCD1602顯示,顯示格式如下:
//                     ------------------------
//                     |      HH:MM:SS      |
//                     |   Y:y M:mm D:dd  W   |
//                     ------------------------
//硬件要求:撥碼開關S13全部置ON
//          撥碼開關S2第2位置ON
//          跳線J18全部接通

#include             //dsPIC30F6014標準頭文件

  _FOSC(CSW_FSCM_OFF & XT_PLL4);  //4倍頻晶振,Failsafe 時鐘關閉
  _FWDT(WDT_OFF);                 //關閉看門狗定時器
  _FBORPOR(PBOR_OFF & MCLR_EN);   //掉電復位禁止,MCLR復位使能。
  _FGS(CODE_PROT_OFF);            //代碼保護禁止


#define i_o   PORTGbits.RG3       //定義DS1302的數據口
#define sclk  PORTGbits.RG2       //定義DS1302的時鐘口
#define intr  PORTAbits.RA12      //定義DS1302的復位口

#define rs LATBbits.LATB4         //定義LCD控制位(注意這里只能用LATB寄存器,不能直接用PORTB寄存器)
#define rw LATBbits.LATB5
#define e  LATBbits.LATB6


// unsigned char time_rx;
  unsigned char __attribute__((address(0x900))) rd_data[6]={0,0,0,0,0,0};       //定義接收寄存器
// LCD顯示數據
  unsigned char __attribute__((address(0x920))) lcd[16]={' ',' ',' ',' ',0,0,':',0,0,':',0,0,' ',' ',' ',' '};
  unsigned char __attribute__((address(0x940))) lcd1[16]={'Y',':',0,' ','M',':',0,0,' ','D',':',0,0,' ',' ',0};

//定義待設置的時間:豪秒、 秒、 分、 時、    日/年、     月/星期
const char table[]={ 0,    88,  88,  18       ,41        ,50};
//                 0豪秒;58秒;58分;12時   0年29日     12月星期1


//****************************延時程序**************************************
void  delay()              //延時程序
    {
     int i;                 //定義整形變量
     for(i=0;i<10;i++);     //延時
    }

//***************************寫PCF8583程序**********************************
void wr_data(unsigned char temp)
{
 I2CTRN=temp;                      //數據送IIC的發送寄存器       
    while(!IFS0bits.MI2CIF);          //等待發送完成
    IFS0bits.MI2CIF=0;
}
 
//**************************等待總線空閑為空程序****************************
void finish()
{
    while(!IFS0bits.MI2CIF);         //等待總線空閑
    IFS0bits.MI2CIF=0; 
}

//*************************寫LCD程序****************************************
//寫一個字節數據函數
//在電平發生改變后需要插入一段延時時間,否則LCD反應不過來。
void write(unsigned int x)
 {
  PORTD=x;                   //待顯示數據送PORTD口
  delay();                  
  rs=1;                      //該字節數據為數據,而不是命令
  delay();
  rw=0;                      //此次操作為寫,而不是讀
  delay();
  e=0;                       //拉低使能信號
  delay();                   //保持使能信號為低一段時間
  e=1;                       //拉高使能信號,建立LCD操作所需要的上升沿
  delay();
 }

//********************LCD顯示設置函數**************************************
//在電平發生改變后需要插入一段延時時間,否則LCD反應不過來。
void lcd_enable()
 {
   delay();
   rs=0;                     //該字節數據為命令,而不是數據
   delay();
   rw=0;                     //此次操作為寫,而不是讀
   delay();
   e=0;                      //拉低使能信號
   delay();                  //保持使能信號為低一段時間
   e=1;                      //拉高使能信號,建立LCD操作所需要的上升沿
   delay();
}

//**********************IIC初始化函數***************************************
void i2c_init()
{
    TRISB=0X0000;              //設置B口為輸出
    TRISD=0X0000;              //設置D口為輸出
    TRISC=0XFFFF;
 TRISG=0XFFFF;
    I2CCON=0;
    I2CSTAT=0;
    I2CBRG=15;                //400K
    I2CCONbits.I2CEN=1;       //使能IIC
}

//*********************LCD初始化函數**************************************
void lcd_init()
 {
    PORTD=0X1;                 //清除顯示
    lcd_enable();
    PORTD=0X38;                //8位2行5*7點陣
    lcd_enable();
    PORTD=0X0e;                //顯示開,光標開,閃爍
    lcd_enable();
    PORTD=0X06;                //文字不動,光標右移
    lcd_enable();
 }

//*******************PCF8583中斷使能函數***********************************
void i2c_interrupt_init()
{
//    IPC4=7;                    //優先級別最高
    IEC1bits.INT1IE=0;           //使用查詢方式
    IFS1bits.INT1IF=0;           //清除中斷標志位
    INTCON2bits.INT1EP=1;        //負邊沿觸發

    I2CCONbits.SEN=1;            //發送起始位
    finish();                    //等待完成

    wr_data(0xa0);               //發送控制命令和寫命令
    wr_data(0);                  //寫8583的第0單元
    wr_data(4);                  //寫入數據4(使能中斷功能)

    I2CCONbits.RSEN=1;           //發重啟動位
    finish();                    //等待完成

    wr_data(0xa0);               //發送控制命令和寫命令
    wr_data(8);                  //寫8583的第8單元
    wr_data(9);                  //寫入數據9(計時中斷功能)
    
    I2CCONbits.PEN=1;            //發停止位
    finish();                    //等待完成
}

//***********************LCD顯示函數************************************
void lcd_display()
 { 
    unsigned char i,j;
    PORTD=0X80;                  /顯示地址
    lcd_enable();
    for(i=0;i<16;i++)            //一共16字節數據
       {
         write(lcd[i]);          //查表獲取數據并調用寫一個字節數據函數送LCD顯示
         for(j=0;j<5;j++)        //延時一段時間(主要是為了控制顯示的速度)
          {delay();}
       }

    PORTD=0X00c0;                //日期時間顯示地址
    lcd_enable();
    for(i=0;i<16;i++)            //一共16字節數據
       {
         write(lcd1[i]);         //查表獲取數據并調用寫一個字節數據函數送LCD顯示
         for(j=0;j<5;j++)        //延時一段時間(主要是為了控制顯示的速度)
          {delay();}
       }
 }

//***********************設置初始時間函數******************************
void i2c_write()
{
    unsigned char i;

 I2CCONbits.SEN=1;            //發送啟動位
    finish();                    //等待完成

    wr_data(0xa0);               //發送控制命令和寫命令
    wr_data(1);                  //待修改的8583起始單元地址(毫秒單元;地址自動+1)
 for(i=0;i<6;i++)             //共修改6個單元(時間跟日期)
      {
      wr_data(table[i]);      //查表寫數據
      }
  
    I2CCONbits.PEN=1;            //發送停止位
    finish();                    //等待完成
}

//************************讀時間函數***********************************
void i2c_read()
{
 unsigned char i;
   
    I2CCONbits.SEN=1;           //發送起始位
    finish();                   //等待完成

    wr_data(0xa0);              //發送控制命令和寫命令
    wr_data(2);                 //讀時間的起始單元
   
    I2CCONbits.RSEN=1;          //發重啟動位
    finish();                   //等待完成
    wr_data(0xa1);              //發送控制命令和讀命令

 for(i=0;i<7;i++)            //讀取時間
      {
         I2CCONbits.RCEN=1;     //使能IIC的讀功能
      rd_data[i]=I2CRCV;     //保存讀取到的時間
      finish();              //等待完成
         I2CCONbits.ACKEN=1;    //使能應答功能
         if(i==6) I2CCONbits.ACKDT=1;   //不是最好一個數據,應答信號為0,繼續讀數據
         else I2CCONbits.ACKDT=0;       //做后一個數據,應答信號為1

         while(!IFS0bits.MI2CIF);
         IFS0bits.MI2CIF=0;  
      }
  
    I2CCONbits.PEN=1;           //發送停止位
    finish();                   //等待完成
}

//*************讀取時間轉換成BCD碼并存儲到LCD顯示緩沖單元*************
void hex2bcd()
{
 lcd[11]=(rd_data[1]&0xf)+0x30;        // 1/10 second
    lcd[10]=(rd_data[1]>>4)+0x30;         // second
   
    lcd[8]=(rd_data[2]&0xf)+0x30;         // 1/10 minute
    lcd[7]=(rd_data[2]>>4)+0x30;          // minute
 
    lcd[5]=(rd_data[3]&0xf)+0x30;         // 1/10 hour
    lcd[4]=(rd_data[3]>>4)+0x30;          // hour


    lcd1[12]=(rd_data[4]&0xf)+0x30;         // 1/10 date
    lcd1[11]=((rd_data[4]>>4)&3)+0x30;      // data
    lcd1[2]=(rd_data[4]>>6)+0x30;          // year

    lcd1[7]=(rd_data[5]&0xf)+0x30;         // 1/10 month
    lcd1[6]=((rd_data[5]>>4)&1)+0x30;     // month
    lcd1[15]=(rd_data[5]>>5)+0x30;         // weekday
}

//***********************主函數**************************************
int main(void)
{
 i2c_init();                 //系統初始化
    lcd_init();                 //LCD初始化
    i2c_interrupt_init();       //芯片中斷使能
    while(1)
    {
     while(!PORTCbits.RC3)   
      {
  i2c_write();            //設置初始時間
        while(!PORTCbits.RC3);
      }
       
    while(IFS1bits.INT1IF)      //等待中斷
       {
       
        IFS1bits.INT1IF=0;     
        i2c_interrupt_init();  //重新初始化中斷,以便清除8583芯片內中斷標志位
        i2c_read();            //讀取時間
        hex2bcd();             /結果轉換成BCD碼
        lcd_display();         /送LCD顯示
       }
     }
}


404
返回首頁 |  返回上一頁
联系我们: 临夏县| 玛纳斯县| 高唐县| 洞头县| 镇宁| 桃园县| 穆棱市| 灵宝市| 冷水江市| 汝城县| 赤峰市| 包头市| 平顶山市| 株洲市| 遵义市| 甘孜县| 泗洪县| 永顺县| 威宁| 库尔勒市| 武平县| 苏尼特右旗| 秦皇岛市| 美姑县| 乌拉特中旗| 南木林县| 余干县| 东源县| 石台县| 桐梓县| 泉州市| 雷山县| 凉城县| 龙南县| 冀州市| 龙里县| 蒲城县| 淳化县| 体育| 贵定县| 贡嘎县|