⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_f76.lst

📁 用PIC16F73编写的SMBUS通信测试程序
💻 LST
字号:
     1: 

     2: /******************************************************************* 

     3: 一、程序说明: 

     4: 1, 24LC02器件地址是1010000R/W. 

     5: 2, 数组写入24LC02采取页写方式. 

     6: 3, 数组code从24LC02读出时采取自由读方式. 

     7: 4, 采用4.00M晶体。 

     8: 5,采用软件I2C。 

     9: 

    10: 二、硬件连接: 

    11: 1, SDA_DIRE------->23 pin.(当然你可以任意选择脚位) 

    12: 2,  SCL_DIRE------->18 Pin.(当然你可以任意选择脚位) 

    13: 3, PORTD----->外接8个LED,显示读出的数据,在这里,读出的刚好是一个闪动的流水灯状态。 

    14: 

    15: *******************************************************************/ 

    16: #include "pic.h" 

    17: 

    18: #define uchar   unsigned char 

    19: #define nop()  asm("nop")

    20: //#define SCL_DIRE  TRISC3 

    21: //#define SDA_DIRE  TRISC4 

    22: //#define SCL_E     RC3

    23: //#define SDA_E     RC4

    24: 

    25: #define SCL_E     RA0

    26: #define SDA_E     RA1

    27: #define SCL_DIRE  TRISA0 

    28: #define SDA_DIRE  TRISA1 

    29: 

    30: void start_i2c(); 

    31: void stop_i2c(); 

    32: void send_byte(uchar c); 

    33: uchar receive_byte(); 

    34: void I_send_str(uchar sla,uchar suba,uchar *s,uchar no); 

    35: void delay_250ms(); 

    36: void i2c_error (); 

    37: int ReadByte_EE(uchar addr);

    38: 

    39: uchar code[]={0X21,0x64,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; 

    40: uchar no,ack,c,data; 

    41: 

    42: /*

    43: void main(void) 

    44: { 

    45:  uchar i; 

    46:  

    47:  ADCON1=0X06;

    48:  TRISA=0x0F;

    49:  PORTA=0;

    50:  

    51:  TRISC=0Xff;     //C口设为输入 RC3为SCL_DIRE线,RC4为SDA_DIRE线。 

    52:  PORTC=0X0;     

    53:  TRISB=0X00;     //D口为输出,显示IC24LC02中读出的内容 

    54:  PORTB=0X00;     //初始显示全亮 

    55: 

    56:  I_send_str(0xa0,0x00,code,6); //页写入code数组到24LC02,器件地址为0Xa0,子地址为0X00,共9个数。 

    57:   

    58:  delay_250ms(); 

    59:   

    60: 

    61:  ///////////开始读出到D口进行显示,根据Random read时序图。 

    62:  while (1) 

    63:   { 

    64:     for (i=0x00;i<0x09;i++) 

    65:      { 

    66:       start_i2c(); 

    67:       send_byte(0xA0);      //发送器件地址,即DEVICE ADDRESS。 

    68:         if (ack==0) i2c_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。 

    69:       send_byte(i);         //发送字地址,即WORD ADDRESS。D口显示数组。 

    70:         if (ack==0) i2c_error(); 

    71:       start_i2c();          //重新启动总线。 

    72:       send_byte(0xA1);      //发送读命令和器件地址DEVICE ADDRESS。 

    73:         if (ack==0) i2c_error(); 

    74:       data=receive_byte(); 

    75:       stop_i2c(); 

    76:       PORTB=data; 

    77:       delay_250ms(); 

    78:       PORTB=ReadByte_EE(2);

    79:       delay_250ms();

    80:      } 

    81:   } 

    82: } 

    83: */

    84: 

    85: /******************************************************************* 

    86: 起动总线函数 

    87: 函数原型: void start_i2c(); 

    88: Function: start on the I2C bus 

    89: *******************************************************************/ 

    90: void start_i2c() 

    91: { 

    92:  SDA_DIRE=1;       //发送启始条件的数据信号 

    93:  nop(); 

    94:  SCL_DIRE=1; 

    95:  nop();nop();nop();nop();nop(); //24LC02要求建立时间大于4,7S 

    96:  SDA_DIRE=0;                      //发送起始信号 

    97:  nop();nop();nop();nop();nop(); 

    98:  SCL_DIRE=0;                      //钳住I2C总线,准备发送数据或接收数据 

    99:  nop();nop(); 

   100: } 

   101: 

   102: 

   103: /******************************************************************* 

   104: 停止总线函数 

   105: 函数原型: void stop_i2c(); 

   106: Function: stop the I2C bus 

   107: *******************************************************************/ 

   108: void stop_i2c() 

   109: { 

   110:   

   111:  SDA_DIRE=0; //发送结束条件的数据信号 

   112:  nop(); 

   113:  SCL_DIRE=1; 

   114:  nop();nop();nop();nop();nop(); 

   115:  SDA_DIRE=1; 

   116:  nop();nop();nop();nop(); 

   117: } 

   118: 

   119: /*================================================================= 

   120: 字节数据传送函数 

   121: 函数原型: void send_byte(uchar c); 

   122: Function: 将数据C发送出去,可以是地址,也可以是数据,发完后等待回应,并对此状态 

   123:          位进行操作(不应答或非应答都使ack=0 ),发送数据正常,ack=1;ack=0 

   124:          表示被控器无应答或损坏。 

   125: ==================================================================*/ 

   126: void send_byte(uchar c) 

   127: { 

   128:  uchar bit_count; 

   129:  for (bit_count=0;bit_count<8;bit_count++) 

   130:   { 

   131:    if ((c<<bit_count)&0x80) {SDA_DIRE=1;} 

   132:    else {SDA_DIRE=0;} 

   133:    nop(); 

   134:    SCL_DIRE=1; 

   135:    nop();nop();nop();nop();nop(); 

   136:    SCL_DIRE=0; 

   137:   } 

   138:   nop();nop(); 

   139:   SDA_DIRE=1; 

   140:   nop();nop(); 

   141:   SCL_DIRE=1; 

   142:   nop();nop();nop(); 

   143:   if (SDA_E==1) ack=0; 

   144:   else ack=1; //用ASK=1为有应答信号 

   145:   SCL_DIRE=0; 

   146:   nop();nop(); 

   147: } 

   148: 

   149: /*================================================================== 

   150: 字节数据接收函数 

   151: 函数原型:uchar receive_byte(); 

   152: FUNCTION: 用来接收从器件传来的数据,并判断总线错误(不发应答信号), 

   153:          发完后请用应答函数。 

   154: ===================================================================*/ 

   155: uchar receive_byte() 

   156: { 

   157:   uchar retc,bit_count; 

   158:   retc=0; 

   159:   SDA_DIRE=1; 

   160:   for (bit_count=0;bit_count<8;bit_count++) 

   161:   { 

   162:      nop(); 

   163:      SCL_DIRE=0; 

   164:      nop();nop();nop();nop();nop(); 

   165:      SCL_DIRE=1; 

   166:      nop();nop(); 

   167:      retc=retc<<1; 

   168:      if (SDA_E==1)  retc=retc+1; 

   169:      nop();nop(); 

   170:    } 

   171:    SCL_DIRE=0; 

   172:    nop();nop(); 

   173:    return (retc); 

   174: } 

   175: 

   176: ////////********************************//////////////

   177: int ReadByte_EE(uchar addr){

   178: uchar data1;

   179:  start_i2c(); 

   180:       send_byte(0xA0);      //发送器件地址,即DEVICE ADDRESS。 

   181:         if (ack==0) i2c_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。 

   182:       send_byte(addr);         //发送字地址,即WORD ADDRESS。D口显示数组。 

   183:         if (ack==0) i2c_error(); 

   184:       start_i2c();          //重新启动总线。 

   185:       send_byte(0xA1);      //发送读命令和器件地址DEVICE ADDRESS。 

   186:         if (ack==0) i2c_error(); 

   187:       data1=receive_byte(); 

   188:       stop_i2c(); 

   189:       return(data1);

   190:       }

   191: 

   192: /*================================================================ 

   193: 

   194: 

   195: /*================================================================ 

   196: 向有子地址器件发送多字节数据函数 

   197: 函数原型: bit I_send_str(uchar sla,uchar suba,uchar *s,uchar no); 

   198: Function: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果 

   199:          返回1表示操作成功,否则操作有误。 

   200: =================================================================*/ 

   201: void I_send_str(uchar sla,uchar suba,uchar *s,uchar no) 

   202: { 

   203:   uchar i; 

   204:   start_i2c(); 

   205:   send_byte(sla); 

   206:   if (ack==0)  i2c_error(); 

   207:   send_byte(suba); 

   208:   if (ack==0)  i2c_error(); 

   209:   for (i=0;i<no;i++) 

   210:    { 

   211:      send_byte(*s); 

   212:      if (ack==0)  i2c_error(); 

   213:      s++; 

   214:    } 

   215:   stop_i2c(); 

   216:  // return(1); 

   217: } 

   218: 

   219: /***************************************************************** 

   220: 延时函数 

   221: 函数原型: void delay_250ms(); 

   222: FUNCTION: 延明250ms 

   223: *****************************************************************/ 

   224: void delay_250ms() 

   225: { 

   226:  unsigned int d=24999; 

   227:  while (--d); 

   228: } 

   229: 

   230: /***************************************************************** 

   231: 总线错误函数 

   232: 函数原型: void i2c_error(); 

   233: Function: 通过RD7闪动8次表示总线操作失败一次报警。 

   234: *****************************************************************/ 

   235: void i2c_error () 

   236: { 

   237:  uchar i; 

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

   239:  { 

   240:    RB7=0; 

   241:    delay_250ms(); 

   242:    RB7=1; 

   243:    delay_250ms(); 

   244:  } 

   245:   

   246: } 

   247: /**********END**************/ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -