📄 13.3(8583).c
字号:
/****************************************************************
** 功能描述:该程序实现对I2C总线日历时钟芯片PCF8583的读写操作**
****************************************************************/
//GPIOF1 SCL ,GPIOF3 SDA
#include "DSP28_Device.h"
#define TDATA_H 0x0002 //FLOATS DATA LINE (IOPF1=1)
#define TSHIFTNUM 5
#define TNUMBER 6 //读写PCF8583的参数字个数
unsigned int time[4]; //time[0]年(XXXX XXXX XXXX XXXX)
//time[1]月(XXXX XXXX)日(XXXX XXXX)、
//time[2]星期(0000 XXXX)时(XXXX XXXX)
//time[3]分(XXXX XXXX)秒(XXXX XXXX)
unsigned int year_base=0x2004; //PCF8583的年份时基
unsigned int chtime[4]; //写日历时钟
unsigned int pcf_data[6],flag;
/*****************************************************************
** 函数名:prom_transmit()
** 功能描述:I2C发送一字节子程序
****************************************************************/
void prom_transmit(unsigned int promdata)
{
unsigned long int i = 0;
unsigned int k = 0;
EALLOW; /*SDA output*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
EDIS;
for(k=0;k<8;k++)
{
GpioDataRegs.GPFDAT.bit.GPIOF1=0; /*SCL=0*/
for (i=0;i<100;i++){}
if(promdata&0x0080)
GpioDataRegs.GPFDAT.bit.GPIOF3=1; /*SDA=1*/
else
GpioDataRegs.GPFDAT.bit.GPIOF3=0; /*SDA=0*/
for (i=0;i<100;i++){};
GpioDataRegs.GPFDAT.bit.GPIOF1=1; /*SCL=1*/
for (i=0;i<200;i++){};
promdata=promdata<<1;
}
}
/*****************************************************************
** 函数名:prom_receive()
** 功能描述:I2C接收一字节子程序
****************************************************************/
unsigned int prom_receive()
{
unsigned long int i = 0;
unsigned int k = 0 ;
unsigned int promdata=0x0000;
EALLOW; /*SDA input*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=0;
EDIS;
for(k=0;k<8;k++)
{
promdata=promdata<<1;
GpioDataRegs.GPFDAT.bit.GPIOF1=0; /*SCL=0*/
for (i=0;i<200;i++){};
GpioDataRegs.GPFDAT.bit.GPIOF1=1; /*SCL=1*/
for (i=0;i<100;i++){};
if(GpioDataRegs.GPFDAT.bit.GPIOF3==0)
promdata=promdata&0xFFFE; /*如果数据位为0,则R_DATA最低位清零*/
else
promdata=promdata|0x0001;
for (i=0;i<100;i++){};
}
return(promdata);
}
/*****************************************************************
** 函数名:prom_start()
** 功能描述:I2C 启动子程序
****************************************************************/
void prom_start()
{
unsigned long int i = 0;
EALLOW; /*SDA output*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
EDIS;
GpioDataRegs.GPFDAT.bit.GPIOF1=0; //SCL=0
for (i=0;i<100;i++){}
GpioDataRegs.GPFDAT.bit.GPIOF3=1; //SDA=1
for (i=0;i<100;i++){};
GpioDataRegs.GPFDAT.bit.GPIOF1=1; //SCL=1
for (i=0;i<100;i++){};
GpioDataRegs.GPFDAT.bit.GPIOF3=0; //SDA=0
for (i=0;i<100;i++){};
}
/*****************************************************************
** 函数名:prom_stop()
** 功能描述:I2C 结束子程序
****************************************************************/
void prom_stop()
{
unsigned long int i = 0;
EALLOW; /*SDA output*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
EDIS;
GpioDataRegs.GPFDAT.bit.GPIOF1=0; //SCL=0
for (i=0;i<100;i++){}
GpioDataRegs.GPFDAT.bit.GPIOF3=0; //SDA=0
for (i=0;i<100;i++){}
GpioDataRegs.GPFDAT.bit.GPIOF1=1; //SCL=1
for (i=0;i<100;i++){}
GpioDataRegs.GPFDAT.bit.GPIOF3=1; //SDA=1
for (i=0;i<100;i++){}
}
/*****************************************************************
** 函数名:prom_slave_ack()
** 功能描述:I2C 从机应答子程序
****************************************************************/
unsigned int prom_slave_ack()
{
unsigned long int i = 0;
unsigned int k = 0 ;
EALLOW; /*SDA input*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=0;
EDIS;
GpioDataRegs.GPFDAT.bit.GPIOF1=0; /*SCL=0*/
for (i=0;i<200;i++){};
GpioDataRegs.GPFDAT.bit.GPIOF1=1; /*SCL=1*/
for (i=0;i<100;i++){};
if(GpioDataRegs.GPFDAT.bit.GPIOF3==0)
k=0;
else
k=1; //失败
for (i=0;i<100;i++){};
return(k);
}
/*****************************************************************
** 函数名:prom_no_ack()
** 功能描述:I2C 主机不发应答子程序
****************************************************************/
void prom_no_ack()
{
unsigned long int i = 0;
EALLOW; /*SDA output*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
EDIS;
GpioDataRegs.GPFDAT.bit.GPIOF1=0; //SCL=0
GpioDataRegs.GPFDAT.bit.GPIOF3=1; //SDA=1
for (i=0;i<200;i++){}
GpioDataRegs.GPFDAT.bit.GPIOF1=1; //SCL=1
for (i=0;i<200;i++){}
}
/*****************************************************************
** 函数名:prom_master_ack()
** 功能描述:I2C 主机应答子程序
****************************************************************/
void prom_master_ack()
{
unsigned long int i = 0;
EALLOW; /*SDA output*/
GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
EDIS;
GpioDataRegs.GPFDAT.bit.GPIOF1=0; //SCL=0
GpioDataRegs.GPFDAT.bit.GPIOF3=0; //SDA=0
for (i=0;i<200;i++){}
GpioDataRegs.GPFDAT.bit.GPIOF1=1; //SCL=1
for (i=0;i<200;i++){}
}
/*****************************************************************
** 函数名:write()
** 功能描述:写数据子程序(单字节)
****************************************************************/
int write(unsigned int *array,unsigned int num)
{
unsigned int j = 0;
unsigned int k = 0 ;
for(j=0;j<num;j++)
{
prom_transmit(*array&0xff); //送低8位
k=prom_slave_ack();
if(k==1)break;
array++;
}
return(k);
}
/*****************************************************************
** 函数名:read()
** 功能描述:读数据子程序(单字节)
****************************************************************/
Uint16 read(unsigned int *array,unsigned int num)
{
unsigned int j = 0;
unsigned int k = 0;
Uint16 temp=0x00;
prom_start();
prom_transmit(0x00a3);
k=prom_slave_ack();
if(k==0)
{
for(j=0;j<(num-1);j++)
{
temp=prom_receive();
prom_master_ack();
*array=temp&0x00ff;
array++;
}
temp=prom_receive();
prom_no_ack();
*array=temp&0x00ff;
prom_stop();
k=0;
}
return(k);
}
/*****************************************************************
** 函数名:prom_wr()
** 功能描述:连续页读写子程序
**入口:要写数据的数组首址ARRAY,要写的起始地址ADDR,读写控制字,
要写的字数num
**出口:返回0或1。为0表示操作成功;为1表示操作失败
****************************************************************/
unsigned int prom_wr(unsigned int *array,unsigned int addr,Uint16 control,unsigned int num)
{
unsigned long int i = 0;
unsigned int k = 0 ;
unsigned int addr_l; //addr_h,addr_l;
//addr_h=(addr>>8)&0x00ff;
addr_l=addr&0x00ff;
prom_start();
k=control&0xFFFE; //清除控制字节第0位
prom_transmit(k); //送写控制字
k=prom_slave_ack();
if(k==0)
{
prom_transmit(addr_l); //送地址低位
k=prom_slave_ack();
}
if(k==0)
{
i=control&0x0001;
if(i==0x0000)
k=write(array,num);
else
k=read(array,num);
}
prom_stop();
return(k);
}
void time_write()
{
//year_base=0x2004; //PCF8583的年份时基
chtime[0]=0x0001; //2005年
chtime[1]=0x0522; //05月22日
chtime[2]=0x0017; //星期0 17点
chtime[3]=0x1030; //10分30秒
pcf_data[0]=0x0;
pcf_data[1]=chtime[3]&0x00ff; //second
pcf_data[2]=(chtime[3]&0xff00)>>8; //minute
pcf_data[3]=chtime[2]&0x00ff; //hour;
pcf_data[4]=((chtime[0]&0x03)<<6)|(chtime[1]&0x003f); //year/date
pcf_data[5]=((chtime[2]&0x0700)>>3)|((chtime[1]&0x1f00)>>8);//week/month
prom_wr(&pcf_data[0],0x0001,0xa2,TNUMBER);
}
void IOinit()
{
//定义GPIOF1,F3为一般I/O口, GPIOF1为输出
EALLOW;
GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1=0;
GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3=0;
GpioMuxRegs.GPFDIR.bit.GPIOF1=1;
EDIS;
}
main(void)
{
unsigned long int i = 0;
InitSysCtrl(); // 系统初始化程序,该子程序在DSP28_sysctrl.c中
DINT; // 关闭总中断
IER = 0x0000; // 关闭外围中断
IFR = 0x0000; // 请中断标志
IOinit(); // I/O初始化子程序
time_write(); // 写PCF8583的参数
for (i=0;i<1000000;i++){};
//读PCF8583的参数
while (1)
{
flag=prom_wr(&pcf_data[0],0x0001,0xa3,TNUMBER); //flag=0x00;则读数成功
if (flag==0)
{
time[0]=year_base+(pcf_data[4]>>6);//year
time[1]=((pcf_data[5]&0x001f)<<8)|(pcf_data[4]&0x003f); //month,date
time[2]=((pcf_data[5]&0x00e0)<<3)|(pcf_data[3]); //week.hour
time[3]=(pcf_data[2]<<8)|pcf_data[1]; //minute,second
for (i=0;i<1000000;i++){};
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -