- /************* 用户系统配置 **************/
- #define MAIN_Fosc 12000000L //定义主时钟, 模拟串口和红外接收会自动适应。5~36MHZ
- #define D_TIMER0 125 //选择定时器时间, us, 红外接收要求在60us~250us之间
- #define User_code 0xFD02 //定义红外接收用户码
- #define DECVICE_ADD 0x55<<1
- /************* 以下宏定义用户请勿修改 **************/
- #include "reg51.H"
- #include "string.H"
- #define uchar unsigned char
- #define uint unsigned int
- //#define freq_base (MAIN_Fosc / 1200)
- //#define Timer0_Reload (65536 - (D_TIMER0 * freq_base / 10000))
- /************* 本地常量声明 **************/
- /************* 本地变量声明 **************/
- sbit SDA = P3^0; //SDA
- sbit SCL = P3^1; //SCL
- bit PreState;
- bit NowState;
- bit START_flag;
- bit STOP_flag;
- //uchar IR_SampleCnt; //采样计数
- uchar NN;
- uchar DEVICE_ADR; //器件地址
- uchar WORD_ADR; //内存地址
- uchar REC_DATA; //接收到的内容
- unsigned int *send_ptr;//
- code unsigned AA0[9] = {0x70,0x2c,0x6e,0x2a,0x00,0x00,0x00,0xc0}; //
- code unsigned AA8[2] = {0xff,0x2c}; //
- //code unsigned AA0[9] = {0x70,0x2c,0x6e,0x2a,0x00,0x00,0x00,0xc0}; //
- code unsigned A00[33] = {0xed,0xcf,0x48,0xe6,0x89,0xe8,0x0c,0xe8,
- 0x97,0xaf,0xd2,0x40,0x6d,0xc2,0xc4,0x04,
- 0xca,0xd5,0xea,0xa7,0xae,0x43,0x37,0xe2,
- 0x12,0x05,0x3b,0x59,0xb7,0xfb,0x3d,0xa5
- }; //
- code unsigned A20[33] = {0xCB,0x85,0x8b,0x54,0x6d,0x97,0x3c,0x05,
- 0x46,0x0f,0x45,0xb4,0xd1,0x0a,0xb8,0x9b,
- 0xdf,0xa2,0x43,0x8d,0xe6,0x7a,0x6f,0xf8,
- 0x7f,0xaa,0x52,0x37,0xa6,0x8f,0xdc,0x71
-
- }; //
- code unsigned A40[33] = {
- 0x15,0x67,0xc5,0x82,0xfe,0x01,0x87,0x44,
- 0x10,0xcd,0xf8,0xe2,0xd7,0xb1,0x7d,0xb6,
- 0x53,0xc0,0x43,0x39,0x3a,0xb3,0x32,0xba,
- 0x5d,0x84,0xf1,0x03,0x13,0xcd,0x74,0x28
- }; //
- code unsigned A60[33] = {
- 0x34,0x39,0xab,0x32,0x3b,0x32,0x76,0x4b,
- 0xff,0x6f,0x2d,0xd6,0x20,0xab,0x8c,0x73,
- 0x6b,0xd0,0xad,0xa6,0x83,0xdf,0x60,0xe0,
- 0x63,0x51,0xe4,0x76,0x1e,0x58,0x9f,0x52
-
- }; //
- uchar temp;
- /************* 外部函数和变量声明 *****************/
- void init(void);//初如化函数
- void delay_24C02(void); // 延时 5us
- void ACK(void);//应答
- void WaitACK(void);//等待主机回复
- /********************* 主函数 *************************/
- void main(void)
- {
- uchar gg,MM,i,count;
- init();//初如化
- while(1)
- {
- NN=50;
- PreState = SDA;
- while(SCL && NN--)
- {
- NowState = SDA;
- if(PreState && !NowState) //启动
- {
- START_flag = 1;
- //_DINT();
- }
- if(!PreState && NowState) //结束
- {
- STOP_flag = 1;
- //_EINT();
- }
- PreState = NowState;
- if(START_flag) //如果是启动的话
- {
- START_flag=0;
- while(SCL); //START时的SCL高电平状态就等待
- for(gg=8;gg>0;gg--) //接收器件地址
- {
- while(!SCL); //SCL低电平状态就等待
-
- DEVICE_ADR<<=1;
- if(SDA) //数据的第一个CLK高电平来临
- DEVICE_ADR |= 0x01;
-
- while(SCL); //SCL高电平状态就等待
- }
-
- ACK(); //对设备地址ACK应答信
- //-----------以上收到了设备地址,并知晓主机要对从机进行读还是写操作---
- for(gg=8;gg>0;gg--) //接收内存单元地址
- {
- while(!SCL);
-
- WORD_ADR<<=1;
- if(SDA)
- WORD_ADR |= 0x01;
-
- while(SCL);
- }
- //-----------以上就已经接收到内存单元地址------------
- ACK(); //对内存单元ACK应答信号
- //--------------------- 以上就已经接收到内存单元地址 -------------------------
- delay_24C02();//5us
- delay_24C02();
- delay_24C02();//5us
- delay_24C02();
- MM=50;
- PreState = SDA;
- while(SCL && MM--)
- {
- NowState = SDA;
- if(PreState && !NowState) // 如果 SDA 下降沿且 SCL 为高 , 则示开始信号
- {
- START_flag = 1;
- }
- }
- //--------------------START_Flag=1: 表示随即读数据 -------------------------
- if(START_flag==1)
- {
- //--------------------------- 读取器件地址 ---------------------------------
- //while(!SCL);
- START_flag=0; // 清除标志位
- while(SCL); //START 时的 SCL 高电平状态就等待
- for(gg=8;gg>0;gg--) // 接收器件地址
- {
- while(!SCL); //SCL 低电平状态就等待
- DEVICE_ADR<<=1; // 高位在前
- if(SDA) // 数据的第一个 CLK 高电平来临
- DEVICE_ADR |= 0x01; // 上升沿读取数据位
- while(SCL); //SCL 高电平状态就等待
- }
- ACK(); // 对设备地址 ACK 应答信
-
-
- //------------------ 判断地址是否为 0xa1 ,表示读数据指令 -------------------
- if(DEVICE_ADR == 0xab) //( DECVICE_ADD+1)
- {
-
- switch(WORD_ADR)
- {
- case 0xa0: count=8; send_ptr =AA0; // memcpy(temp,AA0,count);
- break;
- case 0xa8: count=1; send_ptr =AA8; // memcpy(temp,AA8,count);
- break;
- case 0x00: count=32; send_ptr =A00; // memcpy(temp,A00,count);
- break;
- case 0x20: count=32; send_ptr =A20;// memcpy(temp,A20,count);
- break;
- case 0x40: count=32; send_ptr =A40; // memcpy(temp,A40,count);
- break;
- case 0x60: count=32; send_ptr =A60;// / memcpy(temp,A60,count);
- break;
-
- }
-
- for(i=0;i<count;i++) // 要 读 多 少 字 节 , 由
- {
- //*send_ptr =WORD_ADR;
- temp = send_ptr[i];
- for(gg=8;gg>0;gg--) // 输出数据给主机
- {
- while(SCL);//如果为高,保持
- if( temp & 0x80)
- {
- SDA=1; // 输出 1
- }
- else
- {
- SDA=0; // 输出 0
- }
- while(!SCL);
- //while(SCL); //SCL 为 1 ,就保持 SDA 输出不变
- // SDA=1;
- //*send_ptr <<=1;
- temp <<=1;
- }
- WaitACK();//主机回复ACK
- //send_ptr++;
- }
-
- }//if(DEVICE_ADR==0xa1)
- else //如果不是,退出
- {
-
- }
- }//if(START_flag==1)
- else // 如果 START_flag!=1 则表示主机对从机进行写操作
- {
- if(WORD_ADR == 0xa9)
- {
- for(i=0;i<8;i++)
- {
- for(gg=8;gg>0;gg--) // 读取主机发来的数据
- {
- // while(!SCL);
- // //READ_BUF[i] <<=1;
- // //SDA=0;
- // if(SDA)
- // ;
- // //READ_BUF[i] |= 0x01;
- // //SDA=0;
- // while(SCL);
-
- while(!SCL);
-
- while(SCL);
- }
-
- ACK(); // 对设备地址 ACK 应答信
- }
-
- }
- }
- }// if(START_flag)
- }//end while(SCL && NN--)
- }//end while(1)
- }
- /********************************************************************
- 函数功能:初始化函数
- 入口参数:无
- 返 回:无。
- 备 注:无。
- ********************************************************************/
- void init(void)
- {
- SDA=1; // 初始数据引脚
- SCL=1; // 初始时钟引脚
- // EA=1; // 开总中断
- // IP=0x90; // 中断优先级设定,设为串口 >INTO>T0>INT1>T1
- // EX0=1; // 开外部中断 0
- }
- /********************************************************************
- 函数功能:从机应答函数
- 入口参数:无
- 返 回:无。
- 备 注:应答函数,保证在两个时钟跳变沿 SDA 为低,则主机认为是从机应答
- ********************************************************************/
- void ACK(void)
- {
- // while(!SCL);
- // SDA=0; // 第 9 个 CLK 变高的情况下, SDA 输出 0
- // while(SCL);
- // SDA=1; // 第 9 个 CLK 变低的情况下, SDA 输出 1
- while(SCL); //低就阻塞
- delay_24C02();
- SDA=0; // 第 9 个 CLK 变高的情况下, SDA 输出 0
- while(!SCL); //低就阻塞
- while(SCL); //高就阻塞
- delay_24C02();
- SDA=1; // 第 9 个 CLK 变低的情况下, SDA 输出 1
- }
- /********************************************************************
- 函数功能:主机应答函数
- 入口参数:无
- 返 回:无。
- 备 注:应答函数,保证在两个时钟跳变沿 SDA 为低,则主机认为是从机应答
- ********************************************************************/
- void WaitACK(void)
- {
- // while(!SCL);
- // SDA=0; // 第 9 个 CLK 变高的情况下, SDA 输出 0
- // while(SCL);
- // SDA=1; // 第 9 个 CLK 变低的情况下, SDA 输出 1
- while(SCL); //高就阻塞
- delay_24C02();
- SDA=1; // 第 9 个 CLK 变高的情况下, SDA 输出 0
- while(!SCL); //低就阻塞
- while(SCL); //高就阻塞
- delay_24C02();
- //SDA=1; // 第 9 个 CLK 变低的情况下, SDA 输出 1
- }
- /********************************************************************
- 函数功能:延时 us
- 入口参数:无
- 返 回:无。
- 备 注:函数是用来实现短暂延时,用于对接上主机时钟
- ********************************************************************/
- void delay_24C02(void) // 延时 5us
- {
- //; ; ; ; ;
- uchar i;
- i=3;
- while(i--);
- }
复制代码
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|
|