我要通过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);
}
|