搜索
bottom↓
回复: 1

急问:马老师,能不能帮忙看16模拟I2C的程序,不能读,数码管显示的是2,都调了一周了

[复制链接]

出0入0汤圆

发表于 2006-10-1 16:08:46 | 显示全部楼层 |阅读模式
硬件电路是PA0 PA1接AT24C02的SDA SCL

程序:

#include <iom16v.h>

#include <stdio.h>

#include <macros.h>

#include <string.h>

#pragma data:data

//#include "pcf8563.h"

//#include "lcd.h"

//#include "keyboard.h"

unsigned char table[] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

unsigned char WriteDeviceAddress=0xa0;             //写命令数//const

unsigned char ReadDviceAddress=0xa1;                //读

unsigned char Data;

#pragma data:code

//时钟芯片数据接口PA0

#define DATE_DT_set asm("sbi 0x1B,0")

#define DATE_DT_clr asm("cbi 0x1B,0")

//时钟芯片时钟接口PA1

#define DATE_CLK_set asm("sbi 0x1B,1")

#define DATE_CLK_clr asm("cbi 0x1B,1")

void delayus(unsigned char i)

{int j;

while(i)

{

for(j=11000;j>0;j--)

;

i--;

}

}

///////////////////////////////////////////////////

void IO_init(void)

{

DDRD=0XFF;

DDRB=0XFF;

PORTD=0XFF;

PORTB=0XFF;

//DDRD=0XFF;

}

/////////////////////////////////////////////////

display(int temp)

{

PORTD=0X00;

PORTB=table[temp];



}



// ************************************************ //

// *** This routine will send the I2C Start Bit *** //

// ************************************************ //

void I2C_Start (void)         //I2C发送开始位

{

DDRA|=0x03;                  //将PA0数据端口(SDA),PA1时钟端口(SCL)设为输出

DATE_CLK_set;                          //将时钟端口(SCL)设为高

DATE_DT_set;                          //将数据端口(SDA)设为高

delayus(5);       

DATE_DT_clr;                          //将数据端口(SDA)设为低

delayus(10);

//DATE_DT_set;

}



// *********************************************** //

// *** This routine will send the I2C Stop Bit *** //

// *********************************************** //



void I2C_Stop (void)          //I2C发送停止位

{

DDRA|=0x03;                  //将PA0数据端口(SDA),PA1时钟端口(SCL)设为输出

DATE_DT_clr;                  //将数据端口(SDA)设为低

DATE_CLK_set;                //将时钟端口(SCL)设为高

delayus(10);

DATE_DT_set;                          //将数据端口(SDA)设为高

delayus(2);

}



// *********************************************************************** //

// *** 发送完毕检查校验位,有校验位返回1,无返回0 *** //

// *********************************************************************** //



unsigned char I2C_Ackn(void)

{

unsigned char errtime=255;

//DATE_CLK_clr;              // 将时钟端口(SCL)设为低



DATE_CLK_set;

//DDRA&=0x00;

DDRA|=0xFE;                             // 设置数据口(SDA)为输入       

// DDRA&=0xfe;

delayus(5);         

while(PINA&0x01)

{

    errtime--;

    if (!errtime)                           //errtime=0,没接收到

    {

          I2C_Stop();

      return 0;

    }

  }

// DDRA|=0x03;

//  DATE_DT_clr;       

   

//DATE_CLK_set;

  //delayus(2);

DATE_CLK_clr;                // 将时钟端口(SCL)设为低

delayus(2);

DATE_CLK_set;

delayus(2);

return 0x01;                                  //true       

}



// ******************************************************** //

// *** This routine will write a byte to the I2C device *** //

// ******************************************************** //



void Write_I2C_Byte(unsigned char byte)     //写一个字节到I2C设备

{

unsigned char i;

DDRA|=0x03;                                                           //将PA0数据端口(SDA)设为输出

for (i = 0; i < 8; i++)                                      //传送8位数据

     {         

         DATE_CLK_clr;                                        //将时钟端口(SCL)设为低         

     if((byte & 0x80)) DATE_DT_set;                    // 设置 SDA 位

         else DATE_DT_clr;                                                  // 清除 SDA 位

         delayus(2);

           DATE_CLK_set;                                        //将时钟端口(SCL)设为高

     asm("nop");       

         byte = byte << 1;                                                  //将输出数据左移一位

        }

// DATE_CLK_clr;                                                   // 校验标志位 (每传送8位,有一校验位)

//if (I2C_Ackn()==0)                                                          // Check for acknowledge from I2C device

//yonghudenglu();

//DATE_CLK_clr;

  DATE_CLK_set;

}

// ********************************************************* //

// *** This routine will read a byte from the I2C device *** //

// ********************************************************* //



unsigned char Read_I2C_Byte(void)   //读取I2C设备的数据

{       

unsigned char i,buff = 0;

delayus(2);

DDRA|=0x02;                                 //PA1为时钟,输出

DDRA&=0xfe;                                            //设置数据口(SDA)为输入

for (i = 0; i < 8; i++)

    {

         DATE_CLK_clr;                        // 将时钟端口(SCL)设为低

         delayus(2);

    // DATE_CLK_set;                        //将时钟端口(SCL)设为高

        // delayus(2);

         // 在 SDA 位上读取数据

         if ( PINA&=0x01 )

         buff++;

         

         buff = (buff << 1);

         delayus(2);

         DATE_CLK_set;                        //将时钟端口(SCL)设为高

         delayus(2);

   }

DDRA|=0x03;                                                            //设为输出,发送校验位

DATE_DT_clr;

delayus(2);

DATE_CLK_set;

delayus(2);

DATE_CLK_clr;                            //将时钟端口(SCL)设为高

DATE_DT_clr;                                        

return buff;                                             // 返回读取值

}





///////////////////////////////////

void main()

{   Data=2;

   IO_init();

    delayus(20);

        while(1)

        {

   I2C_Start();

   

    Write_I2C_Byte(0xa0);

       

        while(I2C_Ackn()==0)       

        {display(1);}

       

     Write_I2C_Byte(0x04);             //写入的字地址

       

        while(I2C_Ackn()==0)

        {display(9);}

       

     Write_I2C_Byte(4);            //写入的字地址的数据

       

        while(I2C_Ackn()==0)

        {display(5);}

   

   I2C_Stop ();

  

   delayus(2000);



  

    ////////////////////



  I2C_Start();

       

         Write_I2C_Byte(0xa0);

       

        while(I2C_Ackn()==0)

        {display(4);}

       

         Write_I2C_Byte(0x04);              //定位字地址



while(I2C_Ackn()==0)

        {display(7);}

       

   I2C_Stop ();



        /////////////////////////

         I2C_Start();

          delayus(2);

            

  Write_I2C_Byte(0xa1);              //定位字地址



   while(I2C_Ackn()==0)

        {display(2);}

       

    Data= Read_I2C_Byte();

       

    I2C_Stop ();

       

        display(Data);            

}

}

我的邮箱是youjiandong012@163.com.

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2006-11-9 01:49:38 | 显示全部楼层
用CVAVR吧,使用它的I2C模拟接口函数,1个小时搞定了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-18 16:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表