搜索
bottom↓
回复: 6

马老师 模拟I2C总线 读写2402的问题

[复制链接]

出0入0汤圆

发表于 2007-7-10 22:24:01 | 显示全部楼层 |阅读模式
马老师:我用的16的AVR写的口线模拟I2C读写2402的程序,为什么写进去的时候判断回应位可以的,读2402时判断回应位就有问题了。因为我原来用162写2402的,PD4,PD5做SDA,SCL但是有问题。所以我又用16试的,选择PA0做SCL,PA1做SDA 别的口线复用功能太多,我也不知道有没有屏蔽掉。

以下是源程序

//ICC-AVR application builder : 2007-5-29 9:41:16

// Target : M16

// Crystal: 11.059Mhz



#include <iom16v.h>

#include <macros.h>

#include <eeprom.h>

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

//通讯部分的参数定义

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

char data_send;              //要发送的数据

char data_rev[100];          //接收的所有数据的数组

char send_step;              //发送数据步数

char rev_lenth;              //接收到的数组长度

char rev_counter;            //接收数据总计数器

char data_counter;           //接收的数组计数器

char check;                  //校验码

char send_counter;

char eep_test;

char eep_test2;

char i2cr;

char i2cs;

char mydata;

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

//处理接受数据的参数定义

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

char nm_24c02[100];          //从24C02读出的全部内码数组

char i2cr;                   //存放从24C02读出的一个字节数据

char i2cs;

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

//时间参数定义

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

char count_20ms;             //20MS计数器

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

struct data

{

  unsigned bit0:1;           //发送开始标志位

  unsigned bit1:1;           //接收完成标志位

  unsigned bit2:1;           //发送成功标志位

  unsigned bit3:1;           //接收开始标志位

} sign,time;

unsigned int count_1ms;

void port_init(void)

{

PORTA = 0xFF;

DDRA  = 0xFF;

PORTB = 0xFF;

DDRB  = 0x0F;

PORTC = 0xff;               //m103 output only

DDRC  = 0x03;

PORTD = 0x00;

DDRD  = 0x03;

}



//TIMER0 initialisation - prescale:64

// WGM: Normal

// desired value: 1mSec

// actual value:  0.995mSec (0.5%)

void timer0_init(void)

{

TCCR0 = 0x00;              //stop

TCNT0 = 0x54;              //set count

OCR0  = 0xAC;              //set compare

TCCR0 = 0x03;              //start timer

}



#pragma interrupt_handler timer0_ovf_isr:10

void timer0_ovf_isr(void)

{

TCCR0 = 0x00; //stop

TCNT0 = 0x54; //reload counter value

count_20ms++;

if(count_20ms>=20)

    {

      time.bit0=1;       //20ms

      count_20ms=0;

    }

TCCR0 = 0x03; //start timer

}



//UART0 initialisation

// desired baud rate: 9600

// actual: baud rate:9600 (0.0%)

// char size: 8 bit

// parity: Disabled

void uart0_init(void)

{

UCSRB = 0x00; //disable while setting baud rate

UCSRA = 0x00;

UCSRC = 0x86;

UBRRL = 0x47; //set baud rate lo

UBRRH = 0x00; //set baud rate hi

UCSRB = 0xD8;

}



#pragma interrupt_handler uart0_rx_isr:12

void uart0_rx_isr(void)

{



char recieve_data;            //每次接收数据的缓冲器

//uart has received a character in UDR

recieve_data=UDR;



switch(rev_counter)

{

case 0: if (recieve_data==0xfe)

           {

          rev_counter++;

         //PORTA|=0xfC;

         check+=0XFE;

         }

         else

         {

         check=0;

         rev_counter=0;

         

         }

         break;

case 1: if(recieve_data==0xfe)   

           {

           rev_counter++;

         //PORTA=0XFD;

         check+=0XFE;

           }   

         else

         {

         check=0;

         rev_counter=0;

         }

         break;

case 2:if(recieve_data==0x68)   

           {

           rev_counter++;

         //PORTA=0XFB;

         check+=0X68;

           }   

         else

         {

         check=0;

         rev_counter=0;

         }  

         break;  

case 3: rev_lenth=recieve_data;if(rev_lenth==0x1A){rev_counter++;check+=0X1A;}break;      

default:{

         if(rev_counter>=4)

          {

           data_counter++;

            if(data_counter<=rev_lenth)

               {

                 data_rev[data_counter-1]=recieve_data;

                rev_counter++;

               check+=data_rev[data_counter-1];

               }

            else  

               {

                  if (data_counter==rev_lenth+1)

                      {

                    //PORTA=0XEF;                        //第5个灯亮

                       if(check==recieve_data)

                        {

                       //PORTA=0XDF;                    //第6个灯亮

                         rev_counter++;

                         check=0;

                        }

                     else

                       {

                       rev_counter=0;

                       check=0;

                       recieve_data=0;

                      }

                      }

                 if (data_counter==rev_lenth+2)

                   {

                      //PORTA=0XBF;                     //第7个灯亮

                      if (recieve_data==0xAA)

                      {

                      //PORTA=0X7F;                    //全部正确,最后一个灯亮

                      sign.bit1=1;                   //置成功接收标志位                                

                     }   

                        

                      rev_counter=0;

                      check=0;

                      recieve_data=0;  

                      data_counter=0;

                   }

               }

           }

         }

            

}

     

}



#pragma interrupt_handler uart0_tx_isr:14

void uart0_tx_isr(void)

{   



  switch (send_step)

  {

  case 1:send_step=2;UDR=0x4B;PORTB |=0x02;PORTB &=~0x04;break;

  case 2:send_step=3;break;//send_step=2;UDR=nm_24c02[send_counter];send_counter++;if(send_counter>=rev_lenth){send_step=3;}break;

  case 3:send_step=0;sign.bit1=0; sign.bit0=0;break;  

  default:break;

  }

     //character has been transmitted

}



//call this routine to initialise all peripherals

void init_devices(void)

{

//stop errant interrupts until set up

CLI(); //disable all interrupts

port_init();

//timer0_init();

//uart0_init();



MCUCR = 0x00;

GICR  = 0x00;

TIMSK = 0x00; //timer interrupt sources

SEI(); //re-enable interrupts

//all peripherals are now initialised

}

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

//                                                       24C02部分

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

void delay_1ms()

{

unsigned int delay_1;

for(delay_1=0;delay_1<1571;delay_1++)

;

}

void delay(unsigned int n)                              

{

unsigned int delay_2=0;

  for(delay_2=0;delay_2<n;delay_2++)

     {

     delay_1ms();

     }

}

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

void delay_1us()

{

  asm("nop");

  asm("nop");  

  asm("nop");  

}

void delayus(unsigned int m)

{

  unsigned int delay_3=0;

  for(delay_3=0;delay_3<m;delay_3++)

  delay_1us();

}

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

//24c02测试区

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

void i2c_start()

{

   //C2402_SDA=1;   /*发送起始条件的数据信号*/

   PORTA|=0X02;

   delayus(10); /*起始条件建立时间大于4.7us,延时*/

   //C2402_SCL=1;

   PORTA|=0X01;

   delayus(10);   /*起始条件建立时间大于4.7us,延时*/

   //C2402_SDA=0;   /*发送起始信号*/

   PORTA&=~0X02;

   delayus(10);    /* 起始条件锁定时间大于4μs*/

   //C2402_SCL=0;   /*钳住I2C总线,准备发送或接收数据 */

   PORTA&=~0X01;

   delayus(10);    /*起始条件建立时间大于4.7us,延时*/

}

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

void i2c_stop()

{

  //C2402_SDA=0;  /*发送结束条件的数据信号*/

  PORTA&=~0X02;

  delayus(10);   /*发送结束条件的时钟信号*/

  //C2402_SCL=0;  /*结束条件建立时间大于4μs*/

  PORTA&=~0X01;

  delayus(10);

  //C2402_SCL=1;  /*发送I2C总线结束信号*/

  PORTA|=0X01;

  delayus(10);

  //C2402_SDA=1;

  PORTA|=0X02;

  delayus(10);

}

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

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

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

void i2c_send()

{

   unsigned char count_i2cs;

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

     {

      if(((i2cs<<count_i2cs)&0x80)==0)

        {

           //C2402_SDA=0;

             PORTA&=~0X02;

        }

      else

        {

           //C2402_SDA=1;

            PORTA|=0X02;  

        }

      delayus(10);

      //C2402_SCL=1;

        PORTA|=0X01;

      delayus(10);

      //C2402_SCL=0;

       PORTA&=~0X01;

       delayus(10);

    }

   //C2402_SDA=1;

       PORTA|=0X02;

        delayus(10);

   //C2402_SCL=1;

       PORTA|=0X01;

        delayus(10);

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

      //PIND=0XFF;

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

        //while(C2402_SDA==1)

      //PORTA&=~0X08;  

      DDRA&=~0x02;

      //delayus(20);

      PORTA&=~0X02;

      //PORTA|=0X02;

      //delayus(20);  

      while((PINA&0X02)==0X02)

       {

        ;

       }

       delayus(10);                    //灯亮,通过

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

      DDRA|=0X02;

      delayus(10);

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

        //C2402_SCL=0;

      PORTA&=~0X01;

        delayus(10);

}

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

void i2c_send2()

{

   unsigned char count_i2cs;

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

     {

      if(((i2cs<<count_i2cs)&0x80)==0)

        {

           //C2402_SDA=0;

             PORTA&=~0X02;

        }

      else

        {

           //C2402_SDA=1;

             PORTA|=0X02;  

        }

      delayus(10);

      //C2402_SCL=1;

        PORTA|=0X01;

      delayus(10);

      //C2402_SCL=0;

       PORTA&=~0X01;

        delayus(10);

    }

   //C2402_SDA=1;

       PORTA|=0X02;

        delayus(10);

   //C2402_SCL=1;

       PORTA|=0X01;

        delayus(10);

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

      //PIND=0XFF;

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

        //while(C2402_SDA==1)

      //PORTA&=~0X08;  

      DDRA&=~0x02;

      //delayus(20);

      PORTA&=~0X02;

      while((PINA&0X02)==0X02)

       {

        ;

       }

      PORTA &=~0XFC;                      //灯不亮了没有通过

       delayus(10);

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

      DDRA|=0X02;

      delayus(10);

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

        //C2402_SCL=0;

      PORTA&=~0X01;

        delayus(10);

}

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

void i2c_rece()

{

   unsigned char count_i2cr;

   //C2402_SCL=0;

    PORTA&=~0X01;

    i2cr=0;

    delayus(10);

   //C2402_SDA=1;

    PORTA|=0X02;

    DDRA&=~0x02;

   delayus(10);

   PORTA|=0X02;

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

     {

       //C2402_SCL=1;

       PORTA|=0X01;

        delayus(10);

        i2cr=i2cr<<1;

        //if(C2402_SDA==1)

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

      

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

        if((PINA&0X02)==0X02)

          {

           i2cr=i2cr+1;

           }

           delayus(10);

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

       //DDRD|=0X02;

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

       //C2402_SCL=0;

      

       PORTA&=~0X01;

        delayus(10);

     }

   DDRA|=0x02;  

   delayus(10);

}

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

//

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

void i2c_read(void)

{

   unsigned char count_read=0;

        i2c_start();

       i2cs=0xa0;

      i2c_send2();

      delayus(10);

        i2cs=0x30;

        i2c_send2();

      i2c_start();

        i2cs=0xa1;

        i2c_send2();

      delayus(10);

        i2c_rece();

      mydata=i2cr;     //0x30里的内容读到NM_LENGRH  

      i2c_stop();

        delayus(10);

  

}

void i2c_write(void)

{

  unsigned  char  count_wirte,count_write1;

   

    i2c_start();

   i2cs=0xa0;

    i2c_send();

   delayus(10);

    i2cs=0x30;

    i2c_send();

   delayus(10);

   i2cs=rev_lenth;

   i2c_send();

   delayus(10);

   i2c_stop();

    delayus(10);

}

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

void main(void)

{

init_devices();

  //PORTA  =0X00;

  delay_1us(50);

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

data_rev[0]=0x00;

data_rev[1]=0x01;

data_rev[2]=0x02;

data_rev[3]=0x03;

data_rev[4]=0x04;

data_rev[5]=0x05;

data_rev[6]=0x06;

data_rev[7]=0x07;

rev_lenth=0x08;

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

//insert your functional code here...

i2c_write();

PORTB |=0x04;

PORTB &=~0x02;

i2c_read();

   

   if(mydata==0x08)

     {

      PORTA&=~0XFC;

     }



}

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2007-7-10 22:27:57 | 显示全部楼层
PORTA&=~0XFC是点亮几个灯.我用来试我的程序有没有死机用的.同时也用来检验我写进2402的数对不对

出0入0汤圆

 楼主| 发表于 2007-7-12 09:20:07 | 显示全部楼层
马老师帮帮忙吧。我是个菜鸟,别打击我的积极性。我快崩溃了。

出0入0汤圆

 楼主| 发表于 2007-7-13 21:27:26 | 显示全部楼层
马老师,请您帮忙指点一下把!!!

出0入0汤圆

 楼主| 发表于 2007-7-16 14:20:42 | 显示全部楼层
马老师救命啊!!!指点一下即可!!

出0入0汤圆

 楼主| 发表于 2007-7-18 21:03:17 | 显示全部楼层
马老师救命啊!!!指点一下即可!!

出0入0汤圆

发表于 2007-8-11 17:13:09 | 显示全部楼层
这不是几句话能讲清的,你在网上找点例程参考吧,还是有2-3个的。



我的教材大约10月出版,那里面有对24C256操作的例子,介绍了4种实现方法,有使用I/O模拟的,有使用CVAVR提供的函数的(也是I/O模拟的),有采用硬件TWI实现的等。不过可能时间上等不及了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-23 02:21

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

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