📄 gai610.c
字号:
#include <REG52.h>
#include <intrins.h>
#define PCF8563 0xA2 /*定义器件地址*/
#define WRADDR 0x00
#define RDADDR 0x02
#define uchar unsigned char
#define uint unsigned int
#define _Nop() _nop_() /*定义空指令*/
uchar code tab[18]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x6d,0x77,0x3e,0x79,0x73,0x38,0x6e,0x00 };
/*定义字型码*/ // 0 1 2 3 4 5 6 7 8 9 s10 a11 v12 e13 p14 l15 16y 灭17
uchar td[9]={0x00,0x12,0x00,0x00,0x17,0x01,0x05,0x06,0x07};
/*控制状态寄存器1、 控制状态寄存器2、秒、分、时、日、星期、月/世纪、年*/
uchar rd[7],i; /*定义发送缓冲区*/
// 秒、分、时、日、星期、月/世纪、年
uchar led[15];/*定义存放十进制数的单元*/
//uint rac_address=2;
uint rac_address=1000;
uchar seg_ment=0;
uchar seg_ment1=0;
uchar tag=0;
uchar _segment; /*显示用段*/
uchar segment[4];
uint racaddress[4]={0,0,0,0};
uchar length[4][2]; /*用来存放每段录音的长度*/
uchar playtime[4][7]={0x00,0x12,0,0,0,0,0}; /*定义播放时间存储区*/
sbit SDA=P1^4; /*模拟I2C数据传送位*/
sbit SCL=P1^5; /*模拟I2C数据传送位*/
sbit _cs = P1^0; /*isd4004片选*/
sbit _mosi= P1^1; /*isd4004串行输入*/
sbit _sclk= P1^2; /*isd4004串行时钟*/
sbit _int = P1^6; /*isd4004中断*/
sbit _rac = P3^5; /*isd4004行地址时钟*/
bit ack; /*应答标志位*/
/*************************************************************************************
延时函数1ms延时
*************************************************************************************/
void Delay1ms( uint x)
{
uchar j;
while(x--)
{
for(j=0;j<125;j++)
{;}
}
}
/*************************************************************************************
录音时的显示界面
*************************************************************************************/
void Ledsave()
{
uchar i,j;
led[0]=10; /*s*/
led[1]=11; /*a*/
led[2]=12; /*v*/
led[3]=13; /*e*/
led[4]=17; /*LED灭*/
led[5]=17; /*LED灭*/
led[6]=17; /*LED灭*/
led[7]=17; /*LED灭*/
led[8]=_segment;
led[9]=17; /*0*/
led[10]=17; /*0*/
//分
i=rd[1];
i&=0x7f;
j=i;
i&=0xf0;
i>>=4;
led[11]=i; /*分的十位*/
i=j;
i&=0x0f;
led[12]=i; /*分的个位*/
//秒
i=rd[0];
i&=0x7f;
j=i;
i&=0xf0;
i>>=4;
led[13]=i; /*秒的十位*/
i=j;
i&=0x0f;
led[14]=i; /*秒的个位*/
}
/*******************************************************************************************
放音时的显示界面
*******************************************************************************************/
void Ledplay(uchar segment)
{
uchar i,j;
led[0]=14; /*p*/
led[1]=15; /*l*/
led[2]=11; /*a*/
led[3]=16; /*y*/
//总时间的分
i=length[segment][1];
i&=0x7f;
j=i;
i&=0xf0;
i>>=4;
led[4]=i; /*分的十位*/
i=j;
i&=0x0f;
led[5]=i; /*分的个位*/
//总时间的秒
i=length[segment][0];
i&=0x7f;
j=i;
i&=0xf0;
i>>=4;
led[6]=i; /*秒的十位*/
i=j;
i&=0x0f;
led[7]=i; /*秒的个位*/
led[8]=segment+1;
led[9]=17; /*0*/
led[10]=17; /*0*/
//分
i=rd[1];
i&=0x7f;
j=i;
i&=0xf0;
i>>=4;
led[11]=i; /*分的十位*/
i=j;
i&=0x0f;
led[12]=i; /*分的个位*/
//秒
i=rd[0];
i&=0x7f;
j=i;
i&=0xf0;
i>>=4;
led[13]=i; /*秒的十位*/
i=j;
i&=0x0f;
led[14]=i; /*秒的个位*/
}
/*************************************************************************************
LED全亮3秒
**************************************************************************************/
void Ledcheck()
{
uchar j;
uchar i,k=0;
for(j=0;j<255;j++)
{
P3=0x00;
for(i=0;i<15;i++)
{
P0=0xff;
Delay1ms(1);
P3+=1;
}
}
}
/*************************************************************************************
键盘专用延时
*************************************************************************************/
void dlms(void)
{
uchar i;
for(i=200;i>0;i--)
{ }
}
/*************************************************************************************
键盘扫描(用时408us)
*************************************************************************************/
uchar kbscan(void)
{
uchar sccode,recode;
P2=0xf0; /*p0.0---p0.3发全0,p0.4--p0.7输入*/
if((P2&0xf0)!=0xf0) /*如果p0口高四位不全为1,有键按下*/
{ dlms(); /*延时去抖动*/
if((P2&0xf0)!=0xf0) /*重读输入值*/
{ sccode=0xfe; /*最底位置0*/
while((sccode&0x10)!=0) /*不到最后一行循环*/
{ P2=sccode; /*p0口输出扫描码*/
if((P2&0xf0)!=0xf0) /*如果p0.4--p0.7不全为1,该行有键按下*/
{ recode=P2&0xf0;
sccode=sccode&0x0f; /*保留p0口高四位输入值,低四位变为全1,作为列值*/
return(sccode+recode);
}
else
sccode=(sccode<<1)|0x01; /*如该行无键按下,查下一行,行扫描值左移一位*/
}
}
}
return(0xff);
}
/*************************************************************************************
起动总线函数
*************************************************************************************/
void Start_I2c()
{
SDA=1; /*发送起始条件的数据信号*/
_Nop();
SCL=1;
_Nop(); /*起始条件建立时间大于4.7us,延时*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; /*发送起始信号*/
_Nop(); /* 起始条件锁定时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; /*钳住I2C总线,准备发送或接收数据 */
_Nop();
_Nop();
}
/**************************************************************************************
结束总线函数
***************************************************************************************/
void Stop_I2c()
{
SDA=0; /*发送结束条件的数据信号*/
_Nop(); /*发送结束条件的时钟信号*/
SCL=1; /*结束条件建立时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; /*发送I2C总线结束信号*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*************************************************************************************
字节数据发送函数
*************************************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/
{
if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/
else SDA=0;
_Nop();
SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/
_Nop();
_Nop(); /*保证时钟高电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1; /*8位发送完后释放数据线,准备接收应答位*/
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1; /*判断是否接收到应答信号*/
SCL=0;
_Nop();
_Nop();
}
/*************************************************************************************
字节数据接收函数
*************************************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; /*置数据线为输入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0; /*置时钟线为低,准备接收数据位*/
_Nop();
_Nop(); /*时钟低电平周期大于4.7μs*/
_Nop();
_Nop();
_Nop();
SCL=1; /*置时钟线为高使数据线上数据有效*/
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/*************************************************************************************
应答子函数
*************************************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; /*在此发出应答或非应答信号 */
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); /*时钟低电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/
_Nop();
_Nop();
}
/**************************************************************************************
用户接口函数
**************************************************************************************/
/*************************************************************************************
向无子地址器件发送字节数据函数
函数原型: bit ISendByte(uchar sla,ucahr c);
功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
**************************************************************************************/
bit ISendByte(uchar sla,uchar c)
{
Start_I2c(); /*启动总线*/
SendByte(sla); /*发送器件地址*/
if(ack==0)return(0);
SendByte(c); /*发送数据*/
if(ack==0)return(0);
Stop_I2c(); /*结束总线*/
return(1);
}
/*************************************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
**************************************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*启动总线*/
SendByte(sla); /*发送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*发送器件子地址*/
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s); /*发送数据*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*结束总线*/
return(1);
}
/*************************************************************************************
向无子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址sla,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
*************************************************************************************/
bit ISendStrExt(uchar sla,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*启动总线*/
SendByte(sla); /*发送器件地址*/
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s); /*发送数据*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*结束总线*/
return(1);
}
/*************************************************************************************
向无子地址器件读字节数据函数
函数原型: bit IRcvByte(uchar sla,ucahr *c);
功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地
址sla,返回值在c.
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
**************************************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
Start_I2c(); /*启动总线*/
SendByte(sla+1); /*发送器件地址*/
if(ack==0)return(0);
*c=RcvByte(); /*读取数据*/
Ack_I2c(1); /*发送非就答位*/
Stop_I2c(); /*结束总线*/
return(1);
}
/*************************************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
**************************************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*启动总线*/
SendByte(sla); /*发送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*发送器件子地址*/
if(ack==0)return(0);
Start_I2c(); /*重新启动总线*/
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte(); /*发送数据*/
Ack_I2c(0); /*发送就答位*/
s++;
}
*s=RcvByte();
Ack_I2c(1); /*发送非应位*/
Stop_I2c(); /*结束总线*/
return(1);
}
/*************************************************************************************
向无子地址器件读取多字节数据函数
函数原型: bit ISendStrExt(uchar sla,ucahr *s,uchar no);
功能: 从启动总线到发送地址,读数据,结束总线的全过程.
从器件地址sla,读出的内容放入s指向的存储区,
读no个字节。如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
*************************************************************************************/
bit IRcvStrExt(uchar sla,uchar *s,uchar no)
{
uchar i;
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte(); /*发送数据*/
Ack_I2c(0); /*发送就答位*/
s++;
}
*s=RcvByte();
Ack_I2c(1); /*发送非应位*/
Stop_I2c(); /*结束总线*/
return(1);
}
/*************************************************************************************
字节拆分
*************************************************************************************/
void Change_Led()
{ uchar i,j;
//年
led[0]=0x02; /*年的千位*/
led[1]=0x00; /*年的百位*/
j=i=rd[6];
i&=0xf0;
i>>=4;
led[2]=i; /*年的十位*/
i=j;
i&=0x0f;
led[3]=i; /*年的个位*/
//月
i=rd[5];
i&=0x1f;
j=i;
i&=0xf0;
i>>=4;
led[4]=i; /*月的十位*/
i=j;
i&=0x0f;
led[5]=i; /*月的个位*/
//星期
rd[4]&=0x07;
led[8]=rd[4];
//日
i=rd[3];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -