单片机是ATmega48的,写了个24C02的程序,但是程序一直没能进去,麻烦大侠们帮忙看看哪里出了问题。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机是ATmega48的,写了个24C02的程序,但是程序一直没能进去,麻烦大侠们帮忙看看哪里出了问题。相关的知识,希望对你有一定的参考价值。

#define setbit(sfr,bit) (sfr|=(1<<bit))
#define clrbit(sfr,bit) (sfr&=~(1<<bit))
#define SDA_out() setbit(DDRC,4) //设置SDA为输出
#define SCL_out() setbit(DDRC,5) //设置SCL为输出
#define SDA_in() clrbit(DDRC,4) //设置SDA为输入
#define SDA_high() setbit(PORTC,4) //设置SDA为高电平
#define SDA_low() clrbit(PORTC,4) //设置SDA为低电平
#define SCL_high() setbit(PORTC,5) //设置SCL为高电平
#define SCL_low() clrbit(PORTC,5) //设置SCL为低电平

void delay_us(uchar t)

uchar i;
for(i = 0;i < t;i++)
;

void delay_ms(uchar m)

uchar i;
for(i = 0;i < m;i++)

delay_us(250); //延时250us
delay_us(250);
delay_us(250);
delay_us(250);


void init_24c02()

SDA_out();
SCL_out();
//SCL_low();
MCUCR = 0x00; //使能上拉

/**********************************
SCL为高电平时,SDA下降沿触发起始条件
**********************************/
void start_signed()

SDA_out();
SDA_high();
SCL_high();
delay_us(4);
SDA_low();
delay_us(4);
SCL_low();

/**********************************
SCL为高电平时,SDA上升沿触发停止条件
**********************************/
void stop_signed()

SDA_out();
SDA_low();
SCL_high();
delay_us(4);
SDA_high();
delay_us(4);
SCL_low();

/**********************************
SCL为高电平时,SDA拉低电平做出应答
**********************************/
uchar ACK_signed()

uchar q = 1,i;
SDA_in();
SCL_high();
for(i = 0;i < 200;i++)

q = PINC&0x10; //SDA为PC4,SCL为PC5
if(!q) //低电平
break;
else //高电平
i = 0;

delay_us(4);
SCL_low();
return q;


/***********发送应答信号**********/
void mask_ack()

SDA_out();
SCL_low();
delay_us(2);
SDA_low();
delay_us(4);
SCL_high();
delay_us(4);

/************写字节****************/
void write_byte(uchar w_byte)

uchar i;
SDA_out();
SCL_out();
for(i = 0;i < 8;i++)

if((w_byte&0x80) != 0) //从高位开始写
SDA_high(); //写“1”
else
SDA_low(); //写“0”
w_byte = w_byte << 1;
SCL_high(); //送数据
delay_us(4);
SCL_low();
delay_us(4);


/************读字节**************/
uchar read_byte()

uchar i,read_byte;
SDA_in();
for(i = 0;i < 8;i++)

SCL_high();
delay_us(10);
read_byte = read_byte<<1;
if((PINC&0x10) != 0) //SDA为高电平
read_byte |= 0x10;
else
read_byte |= 0x00;
delay_us(10);
SCL_low();
delay_us(10);

return read_byte;

void write_24c02(uchar addr,uchar w_data)

start_signed();
write_byte(0xa0); //写标志位
if(ACK_signed())

write_byte(addr); //指定地址
if(ACK_signed())

write_byte(w_data); //写数据
if(ACK_signed())

stop_signed();
delay_ms(10);





uchar read_24c02(uchar addr)

uchar temp;
start_signed();
write_byte(0xa0);
if(ACK_signed())

write_byte(addr);
if(ACK_signed())

start_signed(); //从新开始
write_byte(0xa1); //读标志位
if(ACK_signed())

temp = read_byte();
mask_ack();
stop_signed();



return temp;

int main()

uchar p = 0xFF;
DDRB = 0xFF;
PORTB = 0xFF;
init_24c02();
while(1)

write_24c02(0x50,0x01);
delay_ms(10);
p = read_24c02(0x50);
PORTB = p;

return 0;

参考技术A 你的程序有点少东西。
写程序一定要扎实。时序图要求先什么电平,再什么电平是有道理的。不能少
你的写程序,把端口改完方向就完事了。应该所SCL也写0呀
然后,每个端口电平变化以后,你要做延时呀。
还有读数据的时候,你怎么可以
read_byte |= 0x10; 这接收到的数肯定会错。应该是0X01。
24C02有时序要求的,先写0XA0,再写或者读。这个时序呢?
最后,你在判断ACK的时候做了个死循环呀。万一哪一次有点时序问题。程序不就死掉了。连续读200次还读不到,表明读取有问题。这个时候也应该退出来。报错呀。在哪里把i=0;不就死掉了。永远出不来了。追问

程序改完之后,在执行读的时候,每次都是读的0xFE,这是什么原因啊

atmega328p 单片机里面有自带蜂鸣器吗

参考技术A 目前没有哪个单片机是带蜂鸣器的

以上是关于单片机是ATmega48的,写了个24C02的程序,但是程序一直没能进去,麻烦大侠们帮忙看看哪里出了问题。的主要内容,如果未能解决你的问题,请参考以下文章

单片机24c02程序求助

atmega328p 单片机里面有自带蜂鸣器吗

关于24c02芯片的程序问题,希望得到帮助解决,下面的程序有啥问题,为啥下载到单片机里面不能运行!

24c02 写问题。单片机使用4Mhz晶振都正常,但用20Mhz晶振时,写入数据都变成1了。

单片机模拟IIC,24C02程序有问题

51单片机 24C02器件读写+Proteus仿真