HCS08的IIC模块读写PCF8563实验
0赞1、实验功能介绍
标准的iic接口的时钟芯片,可以实现iic主从通讯,读取时时的时钟。做本实验时需将拨码开关“SW2”、“SW5”“SW28”的所有位拨到“ON”位置。
2、流程图
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++;
}
}

