TSHE 发表于 2024-8-19 10:08:45

32F407ZE和8H8K64U使用IIC进行通信,获取的数据是?,请问我的代码哪里有问题

本帖最后由 DebugLab 于 2024-8-19 12:39 编辑

/* 8H8K64U*的i2c.c代码/
#include "iic.h"
bit isda;                                       //设备地址标志
bit isma;                                       //存储地址标志

char rx_data;
unsigned char addr;
unsigned char pdata buffer;

void Delay500ms(void)      //@11.0592MHz
{
      unsigned char data i, j, k;

      _nop_();
      _nop_();
      i = 22;
      j = 3;
      k = 227;
      do
      {
                do
                {
                        while (--k);
                } while (--j);
      } while (--i);
}

void I2C_Isr() interrupt 24
{
    _push_(P_SW2);
    P_SW2 |= 0x80;

    if (I2CSLST & 0x40)
    {
      I2CSLST &= ~0x40;                     //处理START事件
    }
    else if (I2CSLST & 0x20)
    {
      I2CSLST &= ~0x20;                     //处理RECV事件
      if (isda)
      {
            isda = 0;                           //处理RECV事件(RECV DEVICE ADDR)
      }
      else if (isma)
      {
            isma = 0;                           //处理RECV事件(RECV MEMORY ADDR)
            addr = I2CRXD;
            I2CTXD = buffer;
      }
      else
      {
                        buffer[++addr]= I2CRXD;            //处理RECV事件(RECV DATA)
                        rx_data=buffer;
                        if(buffer==0x0e)
                        {
                              P62=~P62;
                              P63=~P63;
                              Delay500ms();
                        }
      }
    }
    else if (I2CSLST & 0x10)
    {
      I2CSLST &= ~0x10;                     //处理SEND事件
      if (I2CSLST & 0x02)
      {
            I2CTXD = 0xff;                      //接收到NAK则停止读取数据
      }
      else
      {
            I2CTXD = buffer[++addr];            //接收到ACK则继续读取数据
      }
    }
    else if (I2CSLST & 0x08)
    {
      I2CSLST &= ~0x08;                     //处理STOP事件
      isda = 1;
      isma = 1;
    }

    _pop_(P_SW2);
}

void iic_init(void)
{
    P1M0 = 0x00;
    P1M1 = 0x00;


    P_SW2 = 0x80;

    I2CCFG = 0x81;                              //使能I2C从机模式
    I2CSLADR = 0x5a;                            //设置从机设备地址寄存器I2CSLADR=0101_1010B
                                                //即I2CSLADR=010_1101B,MA=0B。
                                                //由于MA为0,主机发送的的设备地址必须与
                                                //I2CSLADR相同才能访问此I2C从机设备。
                                                                                                //主机若需要写数据则要发送5AH(0101_1010B)
                                                //主机若需要读数据则要发送5BH(0101_1011B)
    I2CSLST = 0x00;
    I2CSLCR = 0x78;                           //使能从机模式中断
    EA = 1;

    isda = 1;                                 //用户变量初始化
    isma = 1;
    addr = 0;
    I2CTXD = buffer;
}
/* STC8H8K64U main.c*/

void main()
{
      Led_init();
      iic_init();
      while(1);
}





/*基于STM32的主机代码*/

/*STM32 main.c*/

#include <stdio.h>
#include <string.h>
#include "stm32f4xx.h"
#include "MySysTick.h"
#include "myiic.h"
#include "uart.h"



int main(void)
{      
      
      SCL();
      USART1_Config(115200);
      while(1)
      {      
                STC8H_Write(0x0e);
                MySysTick_s(1);
                STC8H_Read();
                MySysTick_s(1);
      }
      
}

/*STM32 iic.c*/

void SDA(GPIOMode_TypeDef mode)
{
      //定义结构体变量
      GPIO_InitTypeDefGPIO_InitStructure;
      /*配置灯的引脚*/
      /* GPIOG Peripheral clock enable */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
      /* Configure PG6 and PG8 in output pushpull mode */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
      GPIO_InitStructure.GPIO_Mode = mode;      //输出模式
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //输出模式的具体方式:推挽
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
}


void SCL(void)
{
      //定义结构体变量
      GPIO_InitTypeDefGPIO_InitStructure;
      /*配置灯的引脚*/
      /* GPIOG Peripheral clock enable */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
      /* Configure PG6 and PG8 in output pushpull mode */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;      //输出模式
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //输出模式的具体方式:推挽
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
}



void IIC_start()
{
      SDA(OUT);
      SCL_Send(1);
      SDA_Send(1);
      
      MySysTick_us(5);
      SDA_Send(0);
      MySysTick_us(10);
      SCL_Send(0);
}



void IIC_end()
{
      SDA(OUT);
      SDA_Send(0);
      SCL_Send(0);
      
      MySysTick_us(5);
      SCL_Send(1);
      MySysTick_us(5);
      SDA_Send(1);
}

void IIC_send(char data)
{
      int i=0;
      SDA(OUT);
      for(;i<8;i++)
      {
                SCL_Send(0);
                MySysTick_us(5);
                SDA_Send(data>>(7-i) & 0x01);
                MySysTick_us(5);
                //printf("data fragment:%d\r\n",data>>(7-i) & 0x01);
                SCL_Send(1);
                MySysTick_us(5);
      }
      SCL_Send(0);
}


char IIC_Receive()
{
      int i=0;
      char data=0;
      SDA(IN);
      
      for(;i<8;i++)
      {
                SCL_Send(0);
                MySysTick_us(5);
                SCL_Send(1);
                MySysTick_us(5);
                if(SDA_Polar)
                {
                        data |= (0x01<<(7-i));
                }
                MySysTick_ms(500);
               
      }
      return data;
}


void IIC_SACK(char ack)
{
      SDA(OUT);
      SCL_Send(0);
      MySysTick_us(2);
      
      SDA_Send(ack);
      MySysTick_us(5);
      
      SCL_Send(1);
      MySysTick_us(5);
      
      SCL_Send(0);
}

char IIC_RACK()
{
      char ack=0;
      SDA(IN);
      
      
      SCL_Send(0);
      MySysTick_us(5);
      
      SCL_Send(1);
      MySysTick_us(5);
      if(SDA_Polar)
      {
                ack=1;
      }
      MySysTick_us(5);
      return ack;
}


void STC8H_Write(char data)
{
      IIC_start();
      
      IIC_send(0x5a);
      if(IIC_RACK()==1)
      {
                printf("写:发送设备地址写命令失败\r\n");
                IIC_end();
                return ;
      }      
      MySysTick_us(5);
      IIC_send(0x00);
      if(IIC_RACK()==1)
      {
                printf("写:发送存储地址失败\r\n");
                IIC_end();
                return ;
      }      
      MySysTick_us(5);
      IIC_send(data);
      MySysTick_us(5);
      if(IIC_RACK()==1)
      {
                printf("发送数据失败\r\n");
                IIC_end();
                return ;
      }      
      else
      {
                printf("发送数据成功\r\n");
      }
      IIC_end();
}

void STC8H_Read()
{
      char data=0;
      IIC_start();
      IIC_send(0x5a);
      if(IIC_RACK()==1)
      {
                printf("读:发送设备地址写命令失败\r\n");
                IIC_end();
                return ;
      }      

      IIC_send(0x00);
      
      if(IIC_RACK()==1)
      {
                printf("读:发送存储地址高字节地址失败\r\n");
                IIC_end();
                return ;
      }      

      IIC_start();

      IIC_send(0x5b);
      if(IIC_RACK()==1)
      {
                printf("读:发送设备地址读命令失败\r\n");
                IIC_end();
                return ;
      }
      data=IIC_Receive();
      IIC_SACK(1);
      IIC_end();
      
      printf("读取成功,data:%c\r\n",data);
}



//发送的数据是0x0e,但接收到的数据是?,我的代码有什么问题啊,感觉问题主要是在STC8H的发送代码,求大神们指正








hsrzq 发表于 2024-8-19 10:16:15

代码太多不想看……但这种发送接收不一致的,大概率是双方波特率不同

soma 发表于 2024-8-19 10:21:31

主从和i2c时序还有地址没问题吧

TSHE 发表于 2024-8-19 10:27:07

soma 发表于 2024-8-19 10:21
主从和i2c时序还有地址没问题吧

没问题,从官方案例找的,数据能成功发过去,就是接收数据有问题
页: [1]
查看完整版本: 32F407ZE和8H8K64U使用IIC进行通信,获取的数据是?,请问我的代码哪里有问题