freetech

HCS08的IIC模块读写PCF8563实验

0
阅读(2847)

1、实验功能介绍

标准的iic接口的时钟芯片,可以实现iic主从通讯,读取时时的时钟。做本实验时需将拨码开关“SW2”、“SW5”“SW28”的所有位拨到“ON”位置。

2、流程图

clip_image002

3、实验现象

3、1将IIC实验程序下载到学习板中,通过LED数码管显示出来分和秒。

4、程序代码:

//读取8563的时钟,通过LED数码管显示出来
byte buf[8]={0,0,0,0,0,0,0,13};
uchar led_buf[6];
byte time_date[7]={0x00,0x43,0x15,0x10,0x01,0x05,0x10};//{秒,分,时,日,周,月,年,}2010年5月10日,星期1,15:43:00
#define LED_DAT PTBD
#define LED_CS0 PTCD_PTCD3
#define LED_CS1 PTCD_PTCD4
#define LED_CS2 PTCD_PTCD5
#define LED_CS3 PTCD_PTCD6
#define LED_CS4 PTCD_PTCD7
#define CS_ON   1
#define CS_OFF  0

uchar tab[]={
        0x3F,/*0*/
        0x06,/*1*/
        0x5B,/*2*/
        0x4F,/*3*/
        0x66,/*4*/
        0x6D,/*5*/
        0x7D,/*6*/
        0x07,/*7*/
        0x7F,/*8*/
        0x6F/*9*/
};//0-9,-,全灭
//============================
//函数名:Init_io初始化I/O
//作用:初始化I/O
//输入参数:无
//返回参数:无
//=============================
void Init_io(void)

    //io初始值都为0
    PTBD = 0x00;
  PTCD_PTCD3=0;
  PTCD_PTCD4=0;
  PTCD_PTCD5=0;
  PTCD_PTCD6=0;
  PTCD_PTCD7=0;
    //io为输出
    PTBDD = 0xFF;
  PTCDD_PTCDD3=1;
  PTCDD_PTCDD4=1;
  PTCDD_PTCDD5=1;
  PTCDD_PTCDD6=1;
  PTCDD_PTCDD7=1;
    //高驱动强度
    PTBDS = 0xFF;
  PTCDS_PTCDS3=1;
  PTCDS_PTCDS4=1;
  PTCDS_PTCDS5=1;
  PTCDS_PTCDS6=1;
  PTCDS_PTCDS7=1;

}
//===================================================
//函数名:delay()
//作用:延时,该函数浪费CPU时间,在实际工程中酌情使用
//输入参数:无
//输出参数:无
//====================================================
void delay(void)
{
     word i;
     i=0x1fff;
     while(i--)__RESET_WATCHDOG();//喂狗;
}

//===============================================================
//函数名:Init_IIC()
//作者:KLY
//日期:2007-11-8 10:34   
//功能:初始化IIC波特率,主机模式
//输入参数:无
//返回值:无
//修改记录:无
//===============================================================
void Init_IIC(void)
{
    IICF=0x0f;//设置波特率<100kbps;IIC波特率=总线频率/(mul * SCL分频系数);mul=1;
    IICC_IICEN=1;//1:使能IIC;0:禁止IIC
    IICC_TXAK=0;//0:当接收完一字节数据产生确认位;1:不产生确认位
    IICC_IICIE=0;//0:中断禁止;1:中断使能
  IICA=0x38;//MCU中的IIC模块作为从机时的地址
}
//===============================================================
//函数名:set_time_date
//作者:KLY
//日期:2007-11-8 10:34   
//功能:设置时钟芯片的秒,时,分,日,周,月,年   
//输入参数:无
//返回值:无
//修改记录:无
//===============================================================
void set_time_date()
{
    byte temp;
    IICC_IICEN = 0;
  IICC_IICEN = 1;
  temp = IICS;                 
  IICS_IICIF = 1;//清除中断标志
  IICC_MST=0;
  IICS_SRW=0;//mcu作为主设备,向从设备写数据
    IICC_TX=1;//发送模式
    IICC_MST=1;//0->1,产生一个开始信号
    delay();//稳定延时
    IICD=0xA2;//发送芯片地址,写命令
    while(!IICS_IICIF );
    temp = IICS;  
    IICS_IICIF=1;
    IICD=0x02;//发送寄存器地址
  while(!IICS_IICIF);
  temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[0];//设置秒
  while(!IICS_IICIF);
  temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[1];//设置分
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[2];//设置时
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[3];//设置日
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[4];//设置周
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[5];//设置月
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICD=time_date[6];//设置年
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
        IICC_TX=0;
      IICS_SRW=0;
      IICC_MST=0;//1->0产生停止位
}
//===============================================================
//函数名:IIC_read_one_byte
//作者:KLY
//日期:2007-11-8 10:34   
//功能:读取一个字节   
//输入参数:无
//返回值:无
//修改记录:无
//===============================================================
byte IIC_read_one_byte(byte address)
{
    byte temp;
    IICC_RSTA=0;
  IICC_IICEN = 0;
  IICC_IICEN = 1;
  temp = IICS;                  /* Clear any pending interrupt */
  IICS_IICIF = 1;
  IICC_MST=0;
  IICS_SRW=0;
    IICC_TX=1;
    IICC_MST=1;
    delay();
    IICD=0xA2;//发送芯片地址,写命令
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICD=address;//发送寄存器地址
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
     IICC_TXAK=1;
   IICC_RSTA=1;                //重新启动
    IICD=0xA3;//读命令
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    IICC_TX=0;
    temp=IICD;
   while(!IICS_IICIF);
    temp = IICS; 
    IICS_IICIF=1;
    temp=IICD;//读秒
     IICC_MST=0;
     delay();
    return(temp);
}
//===============================================================
//函数名:read_time_date
//作者:KLY
//日期:2007-11-8 10:34   
//功能:读入时间和日期   
//输入参数:无
//返回值:无
//修改记录:无
//===============================================================
void read_time_date(void)
{
   buf[0]=IIC_read_one_byte(0x02)&0x7f;
   buf[1]=IIC_read_one_byte(0x03)&0x7f;
   buf[2]=IIC_read_one_byte(0x04)&0x3f;
   buf[3]=IIC_read_one_byte(0x05)&0x3f;
   buf[4]=IIC_read_one_byte(0x06)&0x07;
   buf[5]=IIC_read_one_byte(0x07)&0x1f;
   buf[6]=IIC_read_one_byte(0x08)&0xff;
}

//=======================================================================================================
//函数名:Init_tpm1_ch1_output
//作用:初始化TPM1;内部时钟工作于自时钟模式,总线频率8M;TPM1溢出中断禁止;通道1中断使能;
//通道引脚状态反转时间间隔=400/(8/1)近似50us
//=======================================================================================================
void Init_tpm1_ch1_output(void)
{
    TPM1MODH=0x0C;
    TPM1MODL=0x80;
    TPM1C1VH=0x06;
    TPM1C1VL=0x40;
    TPM1C1SC=0x64;//通道1中断使能,边沿PWM模式,通道引脚高有效
    TPM1SC=0x08;//TPM1时钟源为总线时钟;分频系数为1;溢出中断禁止
    TPM1CNTH=0;//任意时刻对TPM1CNTH或TPM1CNTL的写操作将计数寄存器的计数值复位(清零)
}
void main(void) {
unsigned int cnt,i;
Init_io();
Init_tpm1_ch1_output();
Init_IIC();
EnableInterrupts; /* enable interrupts */
  /* include your code here */
set_time_date();

  for(;;) {
    //cnt做跑马灯用
    for( cnt =1 ; cnt <= 0x80 ; cnt <<= 1){
      __RESET_WATCHDOG(); /* feeds the dog */

      read_time_date();
      led_buf[4]=tab[buf[1]>>4];
      led_buf[3]=tab[buf[1]&0x0F];
      led_buf[2]=tab[buf[0]>>4];
      led_buf[1]=tab[buf[0]&0x0F];
      led_buf[0]=cnt;
      delay();
    }

  } /* loop forever */
  /* please make sure that you never leave main */
}
//==================计数器1通道1事件中断服务程序===========================
interrupt VectorNumber_Vtpm1ch1 void TPM1_CH2OUT_ISR(void)
{
  static uchar step = 0;
    if((TPM1C1SC & 0x80)==0x80)
        {
            TPM1C1SC_CH1F=0;
      switch(step){
        case 0:
          //LED_DIR = 0xFF;
          //LED_CS1 = CS_OFF;
          //LED_CS2 = CS_OFF;
          //LED_CS3 = CS_OFF;
          LED_CS4 = CS_OFF;
          LED_DAT = led_buf[0];
          LED_CS0 = CS_ON;
          break;
        case 1:
          LED_CS0 = CS_OFF;
          //LED_CS2 = CS_OFF;
          //LED_CS3 = CS_OFF;
          //LED_CS4 = CS_OFF;
          LED_DAT = led_buf[1];
          LED_CS1 = CS_ON;
          break;
        case 2:
          //LED_CS0 = CS_OFF;
          LED_CS1 = CS_OFF;
          //LED_CS3 = CS_OFF;
          //LED_CS4 = CS_OFF;
          LED_DAT = led_buf[2];
          LED_CS2 = CS_ON;
          break;
        case 3:
          //LED_CS0 = CS_OFF;
          //LED_CS1 = CS_OFF;
          LED_CS2 = CS_OFF;
          //LED_CS4 = CS_OFF;
          LED_DAT = led_buf[3];
          LED_CS3 = CS_ON;
          break;
        case 4:
          //LED_CS0 = CS_OFF;
          //LED_CS1 = CS_OFF;
          //LED_CS2 = CS_OFF;
          LED_CS3 = CS_OFF;
          LED_DAT = led_buf[4];
          LED_CS4 = CS_ON;
          step = -1;
          break;
      }
          step++;
        }
}