找回密码
 立即注册
查看: 280|回复: 3

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

[复制链接]

4

主题

10

回帖

46

积分

新手上路

积分
46
发表于 2024-8-19 10:08:45 | 显示全部楼层 |阅读模式
本帖最后由 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[256];

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[addr];
        }
        else
        {
                        buffer[++addr]= I2CRXD;            //处理RECV事件(RECV DATA)
                        rx_data=buffer[addr];
                        if(buffer[addr]==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[7:1]=010_1101B,MA=0B。
                                                //由于MA为0,主机发送的的设备地址必须与
                                                //I2CSLADR[7:1]相同才能访问此I2C从机设备。
                                                                                                //主机若需要写数据则要发送5AH(0101_1010B)
                                                //主机若需要读数据则要发送5BH(0101_1011B)
    I2CSLST = 0x00;
    I2CSLCR = 0x78;                             //使能从机模式中断
    EA = 1;

    isda = 1;                                   //用户变量初始化
    isma = 1;
    addr = 0;
    I2CTXD = buffer[addr];
}
/* 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_InitTypeDef  GPIO_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_InitTypeDef  GPIO_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的发送代码,求大神们指正








回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 08:26:53
已绑定手机

27

主题

341

回帖

1691

积分

金牌会员

机长

积分
1691
发表于 2024-8-19 10:16:15 | 显示全部楼层
代码太多不想看……但这种发送接收不一致的,大概率是双方波特率不同
业余撸代码,专业开飞机
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-02 07:55:56
已绑定手机

19

主题

3191

回帖

4872

积分

论坛元老

积分
4872
发表于 2024-8-19 10:21:31 来自手机 | 显示全部楼层
主从和i2c时序还有地址没问题吧
回复 支持 反对

使用道具 举报 送花

4

主题

10

回帖

46

积分

新手上路

积分
46
发表于 2024-8-19 10:27:07 | 显示全部楼层
so*** 发表于 2024-8-19 10:21
主从和i2c时序还有地址没问题吧

没问题,从官方案例找的,数据能成功发过去,就是接收数据有问题
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:35 , Processed in 0.126484 second(s), 68 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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