a2xa2x 2016-06-10 11:59 采纳率: 0%
浏览 1588
已结题

求大神指导,小白一只。

#include "reg52.h"#include "intrins.h"sbit SDA=P2^1;//总线连接口定义sbit SCL=P2^0;//总线连接口定义sbit duan=P2^2;sbit wei=P2^3;typedef unsigned char uchar;uchar duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};uchar weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};uchar t[8];void delay(uchar m)//us延时作用{ while(--m);}void delays(uchar t)//ms延时作用{ while(t--) { delay(245); delay(245); }}/*void display(uchar firstbit,uchar weishu){ static unsigned char i; P0=0; duan=1; duan=0; P0=weima[firstbit+i]; wei=1; wei=0; P0=t[i]; duan=1; duan=0; i++; if(i==weishu) i=0;}*//*void time_0()interrupt 1{ TH0=(65536-2000)/256; TL0=(65536-2000)%256; display(0,8);}*/void iic_start()//开始通知芯片读写开始。{ SDA=1;//上来先让数据线置高电平 SCL=1;//接着让时钟线置高电平 delay(5);//SDA和SCL同时为高电平保持4.7us以上 nop();//1.805us,共5.78us,下面SDA=0;是下降沿,不能计算在延时时间中 SDA=0;//在时钟线为高电平,而数据线由高电平到低电平的过程读写芯片开始进行.//下降沿 delay(5);//SDA低电平保持4us以上,这里是4.34us满足要求。 //注意开始后SCL为1,SDA为0; }void iic_inti()//总线初始化{ SCL=1;//=-----————————————————————>>>>>>>>>>>>>让时钟线和数据线都为高电平 SDA=1;//------——————————————————>>>>>>>>>>>>让时钟线和数据线都为高电平 delay(5);}void iic_stop(){ SDA=0; nop();//准备状态 SCL=1; //————————————————————————>>>>>>>>结束信号是时钟线为高电平,而数据线由低电平到高电平的过程 delay(5);//该稳态需要保持时间为4us以上。 SDA=1;//SCL高电平期间,SDA来一个上升沿, delay(5);//SDA保持4US以上,4.34加上函数返回时间大于4.7us; //注意结束时SCL和SDA都为1;}void iic_sendbyte(uchar bytedate)//发送一个字节{ uchar i,temp; temp=bytedate; for(i=0;i<8;i++) { temp=temp<<1;//移动后最高位到了PSW寄存器的CY位中。 SCL=0;//准备发送阶段 nop();//稳定一下 SDA=CY;//将发送的数据一位位的发送到CY位的SDA上 nop();//稳定一下 SCL=1;//每一个高电平期间,IC器件都会将数据取走 nop();//稳定一下 } SCL=0;//如果写成SCL=1,SDA=1;就是停止信号了,所以不能那样写 nop(); SDA=1;//释放总线,数据总线不用时要释放 nop();}uchar iic_readbyte(){ uchar i,temp; SCL=0;//准备读数据 nop(); SDA=1;//释放总线 nop(); for(i=0;i<8;i++) { SCL=1;//MCU开始取数据 delay(5);//SCL为高电平后,IC器件就会将一位数据送到SDA上, //总共用时不会大于4.34us的,然后就可以让MCU度SDA了 temp=(temp<<1)|SDA;//读一位,保存到temp中。 SCL=0; delay(5); } return temp;}bit iic_checkACK()//处理信号{ uchar errcount=255;//定义超时量为255次 SCL=1; nop(); while(SDA) { //在一段时间内检测到SDA=0的话认为是应答信号 if(0==errcount) { SCL=0;//钳住总线 nop(); return 0;//没有应答信号 } errcount--; } SCL=0;//钳住总线,为下一次通信做准备 nop(); return 1;//成功处理应答信号}void iic_sendACK(bit b_ACK)//发送应答或非应答信号{ SCL=0;//准备 nop(); if(b_ACK)//ACK { SDA=0; } else //UACK { SDA=1; } nop(); SCL=1; delay(5);//大于4us的延时 SCL=0;// 钳住SCL,以便接受数据. nop();}void AT24c02_writebyte(unsigned char addr,unsigned char byte)//向24c02写一个字节数据{ iic_start(); iic_sendbyte(0xa0);//MCU写控制字,前四位固定1010,后三位地址0,末位0是写数据的模式 iic_checkACK();//MCU 处理应答信号 iic_sendbyte(addr);// 准备在指定的地址写入 iic_checkACK(); iic_sendbyte(byte);//写数据 iic_checkACK(); iic_stop(); delays(2);//按字节写入时,24c02在接收到停止信号后,将数据擦写到内部,这需要时间 //并且在这段时间内不会响应总线上的任何请求,固让MCU有2毫秒以上的等待 } void AT24c02_writeData(unsigned char address,unsigned char numbytes,unsigned char *buf)//写入任意长度数据 { while(numbytes--) { AT24c02_writebyte(address++,*buf++); }} void AT24c02_readData(unsigned char beignAddr,unsigned char dataSize,unsigned char *buf)//读取任意长度字节 { iic_start();//起始信号 iic_sendbyte(0xa0);//控制字,写的模式//控制字,读的模式//1010(固定模式)000,地址;最后一位是控制读或写的模式,1为读,0为写 iic_checkACK();//处理应答信号 iic_sendbyte(beignAddr);//发送地址 iic_checkACK();//处理应答信号 iic_start();//发送起始信号 iic_sendbyte(0xa1);//控制字,读的模式//1010(固定模式)000,地址;最后一位是控制读或写的模式,1为读,0为写 iic_checkACK();//处理应答信号 while(dataSize--) { *buf++=iic_readbyte();//读取一个个字节并保存到缓冲区buf中, iic_sendACK(dataSize);//发送应答,当dataSize为0时发送非应答 } iic_stop();//发送停止信号}unsigned char dat[]={0x7f,0xbf,0xdf,0xef, 0xf7,0xfb,0xfd,0xfe, 0xff,0xff,0x00,0x00, 0x55,0x55,0xaa,0xaa };//ram允许情况可以无限添加i;void main(){ uchar i; iic_inti(); AT24c02_writeData(0xae,16,dat); //写入24c02 //第一个数据0xae,代表大地址,第二个1,代表小弟指,一个24c02的小地址的范围是0--250, //第三个是代表数据的地址 delays(1); for

为什么这个程序在不插数据线和时钟线的时候,led灯不亮。

  • 写回答

4条回答 默认 最新

  • a2xa2x 2016-06-10 12:02
    关注

    #include "reg52.h"#include "intrins.h"sbit SDA=P2^1;//总线连接口定义sbit SCL=P2^0;//总线连接口定义sbit duan=P2^2;sbit wei=P2^3;typedef unsigned char uchar;uchar duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};uchar weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};uchar t[8];void delay(uchar m)//us延时作用{ while(--m);}void delays(uchar t)//ms延时作用{ while(t--) { delay(245); delay(245); }}/*void display(uchar firstbit,uchar weishu){ static unsigned char i; P0=0; duan=1; duan=0; P0=weima[firstbit+i]; wei=1; wei=0; P0=t[i]; duan=1; duan=0; i++; if(i==weishu) i=0;}*//*void time_0()interrupt 1{ TH0=(65536-2000)/256; TL0=(65536-2000)%256; display(0,8);}*/void iic_start()//开始通知芯片读写开始。{ SDA=1;//上来先让数据线置高电平 SCL=1;//接着让时钟线置高电平 delay(5);//SDA和SCL同时为高电平保持4.7us以上 nop();//1.805us,共5.78us,下面SDA=0;是下降沿,不能计算在延时时间中 SDA=0;//在时钟线为高电平,而数据线由高电平到低电平的过程读写芯片开始进行.//下降沿 delay(5);//SDA低电平保持4us以上,这里是4.34us满足要求。 //注意开始后SCL为1,SDA为0; }void iic_inti()//总线初始化{ SCL=1;//=-----————————————————————>>>>>>>>>>>>>让时钟线和数据线都为高电平 SDA=1;//------——————————————————>>>>>>>>>>>>让时钟线和数据线都为高电平 delay(5);}void iic_stop(){ SDA=0; nop();//准备状态 SCL=1; //————————————————————————>>>>>>>>结束信号是时钟线为高电平,而数据线由低电平到高电平的过程 delay(5);//该稳态需要保持时间为4us以上。 SDA=1;//SCL高电平期间,SDA来一个上升沿, delay(5);//SDA保持4US以上,4.34加上函数返回时间大于4.7us; //注意结束时SCL和SDA都为1;}void iic_sendbyte(uchar bytedate)//发送一个字节{ uchar i,temp; temp=bytedate; for(i=0;i<8;i++) { temp=temp<<1;//移动后最高位到了PSW寄存器的CY位中。 SCL=0;//准备发送阶段 nop();//稳定一下 SDA=CY;//将发送的数据一位位的发送到CY位的SDA上 nop();//稳定一下 SCL=1;//每一个高电平期间,IC器件都会将数据取走 nop();//稳定一下 } SCL=0;//如果写成SCL=1,SDA=1;就是停止信号了,所以不能那样写 nop(); SDA=1;//释放总线,数据总线不用时要释放 nop();}uchar iic_readbyte(){ uchar i,temp; SCL=0;//准备读数据 nop(); SDA=1;//释放总线 nop(); for(i=0;i<8;i++) { SCL=1;//MCU开始取数据 delay(5);//SCL为高电平后,IC器件就会将一位数据送到SDA上, //总共用时不会大于4.34us的,然后就可以让MCU度SDA了 temp=(temp<<1)|SDA;//读一位,保存到temp中。 SCL=0; delay(5); } return temp;}bit iic_checkACK()//处理信号{ uchar errcount=255;//定义超时量为255次 SCL=1; nop(); while(SDA) { //在一段时间内检测到SDA=0的话认为是应答信号 if(0==errcount) { SCL=0;//钳住总线 nop(); return 0;//没有应答信号 } errcount--; } SCL=0;//钳住总线,为下一次通信做准备 nop(); return 1;//成功处理应答信号}void iic_sendACK(bit b_ACK)//发送应答或非应答信号{ SCL=0;//准备 nop(); if(b_ACK)//ACK { SDA=0; } else //UACK { SDA=1; } nop(); SCL=1; delay(5);//大于4us的延时 SCL=0;// 钳住SCL,以便接受数据. nop();}void AT24c02_writebyte(unsigned char addr,unsigned char byte)//向24c02写一个字节数据{ iic_start(); iic_sendbyte(0xa0);//MCU写控制字,前四位固定1010,后三位地址0,末位0是写数据的模式 iic_checkACK();//MCU 处理应答信号 iic_sendbyte(addr);// 准备在指定的地址写入 iic_checkACK(); iic_sendbyte(byte);//写数据 iic_checkACK(); iic_stop(); delays(2);//按字节写入时,24c02在接收到停止信号后,将数据擦写到内部,这需要时间 //并且在这段时间内不会响应总线上的任何请求,固让MCU有2毫秒以上的等待 } void AT24c02_writeData(unsigned char address,unsigned char numbytes,unsigned char *buf)//写入任意长度数据 { while(numbytes--) { AT24c02_writebyte(address++,*buf++); }} void AT24c02_readData(unsigned char beignAddr,unsigned char dataSize,unsigned char *buf)//读取任意长度字节 { iic_start();//起始信号 iic_sendbyte(0xa0);//控制字,写的模式//控制字,读的模式//1010(固定模式)000,地址;最后一位是控制读或写的模式,1为读,0为写 iic_checkACK();//处理应答信号 iic_sendbyte(beignAddr);//发送地址 iic_checkACK();//处理应答信号 iic_start();//发送起始信号 iic_sendbyte(0xa1);//控制字,读的模式//1010(固定模式)000,地址;最后一位是控制读或写的模式,1为读,0为写 iic_checkACK();//处理应答信号 while(dataSize--) { *buf++=iic_readbyte();//读取一个个字节并保存到缓冲区buf中, iic_sendACK(dataSize);//发送应答,当dataSize为0时发送非应答 } iic_stop();//发送停止信号}unsigned char dat[]={0x7f,0xbf,0xdf,0xef, 0xf7,0xfb,0xfd,0xfe, 0xff,0xff,0x00,0x00, 0x55,0x55,0xaa,0xaa };//ram允许情况可以无限添加i;void main(){ uchar i; iic_inti(); AT24c02_writeData(0xae,16,dat); //写入24c02 //第一个数据0xae,代表大地址,第二个1,代表小弟指,一个24c02的小地址的范围是0--250, //第三个是代表数据的地址 delays(1); for(i=0;i<16;i++) dat[i]=0; AT24c02_readData(0xae,16,dat); //从24c02读数据 //第一个数据0xae,代表大地址,第二个1,代表小弟指,一个24c02的小地址的范围是0--250, //第三个是代表数据的地址 while(1) { for(i=0;i<16;i++) //查表 { delays(200); P1=dat[i]; } }}

    完整程序。

    评论

报告相同问题?

悬赏问题

  • ¥15 Matlab怎么求解含参的二重积分?
  • ¥15 苹果手机突然连不上wifi了?
  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用
  • ¥15 kafka topic 所有分副本数修改
  • ¥15 小程序中fit格式等运动数据文件怎样实现可视化?(包含心率信息))
  • ¥15 如何利用mmdetection3d中的get_flops.py文件计算fcos3d方法的flops?
  • ¥40 串口调试助手打开串口后,keil5的代码就停止了
  • ¥15 电脑最近经常蓝屏,求大家看看哪的问题
  • ¥60 高价有偿求java辅导。工程量较大,价格你定,联系确定辅导后将采纳你的答案。希望能给出完整详细代码,并能解释回答我关于代码的疑问疑问,代码要求如下,联系我会发文档