| 
 
| 我要通过i2c写入eeprom数据控制灯的开关,器件地址0x34,从地址0x07,目标数据0xfe(开灯),目前碰到的问题是main函数里面发送数据,目前程序里面我是直接写入(器件地址,从地址,数据),但是灯无响应。请大大们帮我看看是哪里出错了 #include "pic12f1822.h"
 #include "pic.h"
 //#include "I2C.h"
 #define uchar unsigned char  //定义无符号字符类型
 #define uint unsigned int    //定义无符号字符类型
 
 void i2c_start(void);                         //I2C打开
 void i2c_stop(void);                        //I2C关闭
 void send_byte(uchar c);                        //发送单个字节
 void senddata(uchar ad_main,uchar ad_sub,uchar c);
 
 #define ack 1                 //主应答
 #define no_ack 0        //从应答
 
 #define sda RA1                        //IIC数据脚
 #define scl RA0                        //IIC时钟脚
 
 //内部RC振荡器,看门狗关,上电延时开,外部复位关,代码保护关,数据保护关,低电复位关,时钟输出关,时钟内外切换关,时钟监视器关,闪存读写关,倍频锁相环关,堆栈使能关,低电压烧录使能开
 __CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_ON&MCLRE_OFF&CP_OFF&CPD_OFF&BOREN_OFF&CLKOUTEN_OFF&IESO_OFF&FCMEN_OFF&WRT_OFF&PLLEN_OFF&STVREN_OFF&LVP_ON);
 void delay1ms(uint k)
 {        uchar i,j;
 for(i=0;i<k;i++)
 {j=100;
 while(j--);
 }
 }
 void init()
 {
 //FOSC频率
 OSCCON=0b01101010;        // 4MHZ内部振荡器,指令周期1us
 ANSELA=0;
 //PORTA端口设置
 TRISA=0b00100000;        //RXD为输入,其余为输出
 PORTA=0b00100000;
 APFCON=0b10000100;                //RA5、TA4配置有RX/TX功能
 }
 
 void i2c_start(void)
 {        TRISA1=0;
 sda = 1;//发送起始条件的数据信号
 NOP();//1us
 scl = 1;
 NOP();//起始条件建立时间大于4.7us,延时
 NOP();
 NOP();
 NOP();
 NOP();
 sda = 0;//发送起始信号
 NOP();//起始条件锁定时间大于4us
 NOP();
 NOP();
 NOP();
 NOP();
 scl = 0;//嵌住I2C总线准备发送或接收数据
 NOP();
 }
 
 void i2c_stop(void)
 {        TRISA1=0;
 sda = 0;//发送结束条件的数据信号
 NOP();
 scl = 1;//发送结束条件的时钟信号
 NOP();//结束条件建立时间大于4us
 NOP();
 NOP();
 NOP();
 NOP();
 sda = 1;//发送I2C总线结束信号
 NOP();NOP();NOP();NOP();NOP();
 scl=0;NOP();NOP();scl=1;
 }
 
 void send_byte(uchar c)
 {
 uchar i;
 TRISA1=0;
 for(i=0;i<8;i++)
 {
 scl=0;
 if((c<<i) & 0x80)
 sda=1; //判断发送位
 else
 sda=0;
 NOP();
 scl=1;
 NOP();
 scl=0;
 }
 NOP();
 sda=1;                 //发送完8bit,释放总线准备接收应答位
 NOP();
 scl=1;
 NOP();        //sda上数据即是从应答位
 scl=0;                //不考虑从应答位但要控制好时序
 NOP();
 }
 
 void i2c_ack_main(uchar ack_main)
 {        TRISA1=1;
 scl=0;
 if(ack_main)sda=0;//ack主应答
 else
 sda=1;//no_ack无需应答
 NOP();
 NOP();
 scl = 1;
 NOP();//时钟低电平周期大于4us
 NOP();NOP();
 NOP();NOP();
 scl = 0;//清时钟线,嵌住I2C总线以便接收
 NOP();
 }
 
 uchar read_byte(void)
 {
 uchar i;
 uchar c;
 c=0;
 scl=0;
 NOP();
 TRISA1=1;  //sda总线 IO配置输入
 sda=1; //置数据线为输入方式
 for(i=0;i<8;i++)
 {
 NOP();
 scl=0; //置时钟线为低,准备接收数据位
 NOP();
 sda=1; //置时钟线为高,使数据线上数据有效
 NOP();
 c<<=1;
 if(sda)
 c+=1; //读数据位,将接收的数据存c
 }
 scl=0;
 return c;
 }
 
 void senddata(uchar ad_main,uchar ad_sub,uchar c)
 {
 i2c_start();
 send_byte(ad_main); //发送器件地址
 NOP();
 send_byte(ad_sub); //发送器件子地址
 NOP();
 send_byte(c); //发送数据s
 NOP();
 i2c_stop();
 }
 
 void readdata(uchar ad_main,uchar ad_sub,uchar s)
 {
 uchar i;
 uchar *sdata;
 i2c_start();
 send_byte(ad_main);
 send_byte(ad_sub);
 send_byte(ad_main+1);
 for(i=0;i<8;i++)
 {        TRISA1=1;
 *sdata=read_byte();
 i2c_ack_main(ack); //主应答<ack=1>
 sdata++;
 }
 s=read_byte();
 i2c_ack_main(no_ack); //无需应答<no_ack=0>
 i2c_stop();
 }
 
 void main()
 {
 init();
 delay1ms(255);//延时255ms
 senddata(0x34,0x07,0xfe);//写入器件地址0x34,从地址0x07,数据0xfe
 while(1);
 delay1ms(100);
 }
 
 | 
 |