找回密码
 立即注册
查看: 591|回复: 18

STC8H8K64U与ESP32进行IIC通讯,数据错误问题

[复制链接]
  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
    发表于 2024-2-26 17:23:42 | 显示全部楼层 |阅读模式
    本帖最后由 HHJuan 于 2024-2-26 17:28 编辑

    请问大家接触过用STC8H8K64U与ESP32进行IIC通讯吗?
    我尝试用ESP32作为IIC 主机,STC8H8K64U作为IIC从机。主机发送的数据  Wire.write(1);   ,从机能接收到,但是打印的结果是Read123=-10136
    不清楚是哪里出现了问题,求教!


    这是ESP32 IIC主机的ArduinoC代码:/**
    * 这是主机的程序
    */
    #include <Wire.h>

    int num = 1;           //用来发送给从机
    int address = 0x5a;      //从机地址

    void setup() {
      Serial.begin(115200);

      if(Wire.begin())    //主机加入I2C总线中
        Serial.println("i2c success");
      else
        Serial.println("i2c failed");
    }

    void loop() {
      //向从机发送数据
      char tmp[32];
      num=num+1;
      itoa(num, tmp, 10);  //将数字转换成字符串
      
      Wire.beginTransmission(address);
      Wire.write(1);    //传送数字字符串
          Serial.printf(tmp);

      int ret = Wire.endTransmission();
      if(ret != 0)
      {
        Serial.printf("send failed: %d\r\n", ret);
        return;
      }



      // int len = Wire.requestFrom(address, 32);   //最多不会超过32字节的数据
      // if(len > 0)
      // {
      //   //打印出来收到从机发来的数据
      //   Serial.print("Recv data size:");
      //   Serial.println(len);

      //   Wire.readBytes(tmp, 32);
      //   Serial.write(tmp);

      //   //打印出收到数据的16进制值
      //   for(int i=0;i<32;i++)
      //   {
      //     Serial.printf("%2X, ", tmp);
      //     if(i%8==7)
      //       Serial.println();
      //   }
      //   Serial.println();
      // }

      delay(5000);
    }




    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
     楼主| 发表于 2024-2-26 17:24:05 | 显示全部楼层
    这是STC8H8K64U的IIC从机main.c代码:

    /*---------------------------------------------------------------------*/

    /* --- STC MCU Limited ------------------------------------------------*/

    /* --- STC 1T Series MCU Demo Programme -------------------------------*/

    /* --- Mobile: (86)13922805190 ----------------------------------------*/

    /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/

    /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/

    /* --- Web: www.STCMCU.com --------------------------------------------*/

    /* --- Web: www.STCMCUDATA.com  ---------------------------------------*/

    /* --- QQ:  800003751 -------------------------------------------------*/

    /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */

    /*---------------------------------------------------------------------*/





    /*************  本程序功能说明  **************



    内部集成I2C串行总线控制器做从机模式,SCL->P3.2, SDA->P3.3;



    将接收到的数据通过串口打印出来, 串口默认设置: 115200,N,8,1.



    根据接收的存储器地址数据返回不同的数据内容.



    下载时, 选择时钟 24MHz (用户可自行修改频率).



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



    #include "reg51.h"

    #include "intrins.h"

    #include "stdio.h"



    #define MAIN_Fosc       24000000L   //定义主时钟

    #define Baudrate        115200L

    #define TM              (65536 -(MAIN_Fosc/Baudrate/4))



    typedef     unsigned char   u8;

    typedef     unsigned int    u16;

    typedef     unsigned long   u32;



    sfr INT_CLKO = 0x8F;

    sfr AUXR = 0x8E;

    sfr AUXR1 = 0xA2;

    sfr P_SW1 = 0xA2;

    sfr P_SW2 = 0xBA;

    sfr TH2  = 0xD6;

    sfr TL2  = 0xD7;

    sfr IE2   = 0xAF;



    sfr P1M1 = 0x91;    //PxM1.n,PxM0.n     =00--->Standard,    01--->push-pull

    sfr P1M0 = 0x92;    //                  =10--->pure input,  11--->open drain

    sfr P0M1 = 0x93;

    sfr P0M0 = 0x94;

    sfr P2M1 = 0x95;

    sfr P2M0 = 0x96;

    sfr P3M1 = 0xB1;

    sfr P3M0 = 0xB2;

    sfr P4M1 = 0xB3;

    sfr P4M0 = 0xB4;

    sfr P5M1 = 0xC9;

    sfr P5M0 = 0xCA;

    sfr P6M1 = 0xCB;

    sfr P6M0 = 0xCC;

    sfr P7M1 = 0xE1;

    sfr P7M0 = 0xE2;

    sfr P6   = 0xE8;

    sfr P7   = 0xF8;



    #define I2CCFG          (*(unsigned char volatile xdata *)0xfe80)

    #define I2CMSCR         (*(unsigned char volatile xdata *)0xfe81)

    #define I2CMSST         (*(unsigned char volatile xdata *)0xfe82)

    #define I2CSLCR         (*(unsigned char volatile xdata *)0xfe83)

    #define I2CSLST         (*(unsigned char volatile xdata *)0xfe84)

    #define I2CSLADR        (*(unsigned char volatile xdata *)0xfe85)

    #define I2CTXD          (*(unsigned char volatile xdata *)0xfe86)

    #define I2CRXD          (*(unsigned char volatile xdata *)0xfe87)

    #define I2CMSAUX        (*(unsigned char volatile xdata *)0xfe88)



    #define Timer0_Reload   (65536UL -(MAIN_Fosc / 1000))       //Timer 0 中断频率, 1000次/秒

    #define Baudrate1           115200L

    #define UART1_BUF_LENGTH    64



    /*************  本地常量声明    **************/



    /*************  本地变量声明    **************/

    u8  TX1_Cnt;    //发送计数

    u8  RX1_Cnt;    //接收计数

    bit B_TX1_Busy; //发送忙标志



    u8  xdata RX1_Buffer[UART1_BUF_LENGTH]; //接收缓冲



    bit isda;                                       //设备地址标志

    bit isma;                                       //存储地址标志

    bit B_1ms;          //1ms标志

    bit DisplayFlag;

    u8 addr;

    u8 Rx_Cnt;

    u8 Tx_Cnt;

    u8 RxBuffer[8];

    u16 Test_cnt;   //测试用的秒计数变量



    u8 code TxBuf0[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

    u8 code TxBuf1[8] = {0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};

    u8 code TxBuf2[8] = {0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28};

    u8 code TxBuf3[8] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};

    u8 code TxBuf4[8] = {0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48};

    u8 code TxBuf5[8] = {0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58};

    u8 code TxBuf6[8] = {0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68};

    u8 code TxBuf7[8] = {0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78};



    //void Timer0_config(void);

    void WriteNbyte(u8 addr, u8 *p, u8 number);

    void UART1_config(u8 brt);   // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.



    void UartPutc(unsigned char dat)

    {

            B_TX1_Busy = 1;

            SBUF = dat;

            while(B_TX1_Busy);

    }



    char putchar(char c)

    {

            UartPutc(c);

            return c;

    }



    void I2C_Isr() interrupt 24

    {

        char store;

       

        store = P_SW2;

        P_SW2 |= 0x80;



        if (I2CSLST & 0x40)

        {

            I2CSLST &= ~0x40;                       //处理START事件

        }

        else if (I2CSLST & 0x20)

        {

            I2CSLST &= ~0x20;                       //处理RECV事件,SLACKO设置为0

            if (isda)

            {

                isda = 0;                           //处理RECV事件(RECV DEVICE ADDR)

            }

            else if (isma)

            {

                isma = 0;                           //处理RECV事件(RECV MEMORY ADDR)

                addr = I2CRXD;

                Tx_Cnt = 0;

                Rx_Cnt = 0;

    //            I2CTXD = TxBuf[index];//RxBuffer[addr];

                switch(addr)

                {

                    case 0:

                        I2CTXD = TxBuf0[Tx_Cnt++];

                    break;

                    case 1:

                        I2CTXD = TxBuf1[Tx_Cnt++];

                    break;

                    case 2:

                        I2CTXD = TxBuf2[Tx_Cnt++];

                    break;

                    case 3:

                        I2CTXD = TxBuf3[Tx_Cnt++];

                    break;

                    case 4:

                        I2CTXD = TxBuf4[Tx_Cnt++];

                    break;

                    case 5:

                        I2CTXD = TxBuf5[Tx_Cnt++];

                    break;

                    case 6:

                        I2CTXD = TxBuf6[Tx_Cnt++];

                    break;

                    case 7:

                        I2CTXD = TxBuf7[Tx_Cnt++];

                    break;

                }

            }

            else

            {

                RxBuffer[Rx_Cnt++] = I2CRXD;            //处理RECV事件(RECV DATA)

            }

        }

        else if (I2CSLST & 0x10)

        {

            I2CSLST &= ~0x10;                       //处理SEND事件

            if (I2CSLST & 0x02)

            {

                I2CTXD = 0xff;

            }

            else

            {

                switch(addr)

                {

                    case 0:

                        I2CTXD = TxBuf0[Tx_Cnt++];

                    break;

                    case 1:

                        I2CTXD = TxBuf1[Tx_Cnt++];

                    break;

                    case 2:

                        I2CTXD = TxBuf2[Tx_Cnt++];

                    break;

                    case 3:

                        I2CTXD = TxBuf3[Tx_Cnt++];

                    break;

                    case 4:

                        I2CTXD = TxBuf4[Tx_Cnt++];

                    break;

                    case 5:

                        I2CTXD = TxBuf5[Tx_Cnt++];

                    break;

                    case 6:

                        I2CTXD = TxBuf6[Tx_Cnt++];

                    break;

                    case 7:

                        I2CTXD = TxBuf7[Tx_Cnt++];

                    break;

                }

            }

        }

        else if (I2CSLST & 0x08)

        {

            I2CSLST &= ~0x08;                       //处理STOP事件

            isda = 1;

            isma = 1;

            DisplayFlag = 1;

        }



        P_SW2 = store;

    }



    void main()

    {

        P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口

        P3M1 = 0x0c;   P3M0 = 0x0c;   //SCL、SDA设置为开漏模式



        P_SW2 = 0x80;

        P_SW2 |= 0x30;   //I2C功能脚选择,00:P1.5,P1.4; 01:P2.5,P2.4; 11:P3.2,P3.3



        I2CCFG = 0x80;                              //使能I2C从机模式

        I2CSLADR = 0x5a;                            //设置从机设备地址为5A

        I2CSLST = 0x00;

        I2CSLCR = 0x78;                             //使能从机模式中断



    //    Timer0_config();

        DisplayFlag = 0;



        UART1_config(1);    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.

        EA = 1;



        isda = 1;                                   //用户变量初始化

        isma = 1;

        addr = 0;

        I2CTXD = RxBuffer[addr];



        printf("STC8 I2C从机测试程序!\r\n");  //UART1发送一个字符串

       

        while (1)

                    {

                            if(DisplayFlag)

                            {

                                    DisplayFlag = 0;

                                    if(RxBuffer[0] < 10)

                                    {

                                            Test_cnt = RxBuffer[3]+(RxBuffer[2]*10)+(RxBuffer[1]*100)+(RxBuffer[0]*1000);

                                            printf("Read=%d\r\n", Test_cnt);

                                    }

                                    //printf("Read=0x%02bx%02bx%02bx%02bx\r\n", RxBuffer[0],RxBuffer[1],RxBuffer[2],RxBuffer[3]);

                            }

                    }

    }



    //========================================================================

    // 函数: void Timer0_config(void)

    // 描述: Timer0初始化函数。

    // 参数: 无.

    // 返回: 无.

    // 版本: V1.0, 2020-6-10

    //========================================================================

    //void Timer0_config(void)

    //{

    //    AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,

    //    TH0 = (u8)(Timer0_Reload / 256);

    //    TL0 = (u8)(Timer0_Reload % 256);

    //    ET0 = 1;    //Timer0 interrupt enable

    //    TR0 = 1;    //Tiner0 run

    //}



    ///********************** Timer0 1ms中断函数 ************************/

    //void timer0 (void) interrupt 1

    //{

    //    B_1ms = 1;      //1ms标志

    //}



    //========================================================================

    // 函数: SetTimer2Baudraye(u16 dat)

    // 描述: 设置Timer2做波特率发生器。

    // 参数: dat: Timer2的重装值.

    // 返回: none.

    // 版本: VER1.0

    // 日期: 2014-11-28

    // 备注:

    //========================================================================

    void SetTimer2Baudraye(u16 dat)  // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.

    {

        AUXR &= ~(1<<4);    //Timer stop

        AUXR &= ~(1<<3);    //Timer2 set As Timer

        AUXR |=  (1<<2);    //Timer2 set as 1T mode

        TH2 = dat / 256;

        TL2 = dat % 256;

        IE2  &= ~(1<<2);    //禁止中断

        AUXR |=  (1<<4);    //Timer run enable

    }



    //========================================================================

    // 函数: void UART1_config(u8 brt)

    // 描述: UART1初始化函数。

    // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.

    // 返回: none.

    // 版本: VER1.0

    // 日期: 2014-11-28

    // 备注:

    //========================================================================

    void UART1_config(u8 brt)    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.

    {

        /*********** 波特率使用定时器2 *****************/

        if(brt == 2)

        {

            AUXR |= 0x01;       //S1 BRT Use Timer2;

            SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate1);

        }



        /*********** 波特率使用定时器1 *****************/

        else

        {

            TR1 = 0;

            AUXR &= ~0x01;      //S1 BRT Use Timer1;

            AUXR |=  (1<<6);    //Timer1 set as 1T mode

            TMOD &= ~(1<<6);    //Timer1 set As Timer

            TMOD &= ~0x30;      //Timer1_16bitAutoReload;

            TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) / 256);

            TL1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) % 256);

            ET1 = 0;    //禁止中断

            INT_CLKO &= ~0x02;  //不输出时钟

            TR1  = 1;

        }

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



        SCON = (SCON & 0x3f) | 0x40;    //UART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率

    //  PS  = 1;    //高优先级中断

        ES  = 1;    //允许中断

        REN = 1;    //允许接收

        P_SW1 &= 0x3f;

        P_SW1 |= 0x00;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4

    //  PCON2 |=  (1<<4);   //内部短路RXD与TXD, 做中继, ENABLE,DISABLE



        B_TX1_Busy = 0;

        TX1_Cnt = 0;

        RX1_Cnt = 0;

    }



    //========================================================================

    // 函数: void UART1_int (void) interrupt UART1_VECTOR

    // 描述: UART1中断函数。

    // 参数: nine.

    // 返回: none.

    // 版本: VER1.0

    // 日期: 2014-11-28

    // 备注:

    //========================================================================

    void UART1_int (void) interrupt 4

    {

        if(RI)

        {

            RI = 0;

            RX1_Buffer[RX1_Cnt] = SBUF;

            if(++RX1_Cnt >= UART1_BUF_LENGTH)   RX1_Cnt = 0;    //防溢出

        }



        if(TI)

        {

            TI = 0;

            B_TX1_Busy = 0;

        }

    }

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
     楼主| 发表于 2024-2-26 17:24:59 | 显示全部楼层
    本帖最后由 HHJuan 于 2024-2-27 09:38 编辑


    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
     楼主| 发表于 2024-2-26 17:27:10 | 显示全部楼层
    本帖最后由 HHJuan 于 2024-2-27 09:39 编辑


    回复 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 08:23
  • 签到天数: 109 天

    [LV.6]常住居民II

    10

    主题

    581

    回帖

    918

    积分

    高级会员

    积分
    918
    发表于 2024-2-26 18:36:31 | 显示全部楼层
    这个问答题,条件太少,不好回答
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
     楼主| 发表于 2024-2-26 19:11:57 | 显示全部楼层
    本帖最后由 HHJuan 于 2024-2-27 09:40 编辑

    不知道是不是跟ESP32与STC的时钟有关,STC的时钟是24MHz吗?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
     楼主| 发表于 2024-2-26 19:13:00 | 显示全部楼层
    21cnsound 发表于 2024-2-26 18:36
    这个问答题,条件太少,不好回答

    STC的代码正在审核中,不知道还缺少哪些条件呢?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 09:21
  • 签到天数: 142 天

    [LV.7]常住居民III

    27

    主题

    1338

    回帖

    4173

    积分

    论坛元老

    积分
    4173
    发表于 2024-2-27 09:17:06 | 显示全部楼层
    printf函数里面%d是表示有符号的十进制数据,%u是无符号的十进制数据,数据传输建议使用%x输出十六进制数据。
    另外keil C51编译器使用printf函数时,
    打印8位数据,%后面加 b,如 %bd
    打印16位数据,%后面不加参数或者加 h,如 %u 或者 %hu
    打印32位数据,%后面加 l,如 %lx
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-2 15:38
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    2

    主题

    22

    回帖

    86

    积分

    注册会员

    积分
    86
     楼主| 发表于 2024-2-27 09:45:50 | 显示全部楼层
    乘风飞扬 发表于 2024-2-27 09:17
    printf函数里面%d是表示有符号的十进制数据,%u是无符号的十进制数据,数据传输建议使用%x输出十六进制数据 ...


    截图202402270943241872.jpg

    Test_cnt变量是u16类型的,我尝试了用您说的%u和%hu打印,因为%u是无符号十进制数,所以我又用%x和%lx尝试输出十六进制数

    但是结果都是0
    截图202402270945426301.jpg

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 09:21
  • 签到天数: 142 天

    [LV.7]常住居民III

    27

    主题

    1338

    回帖

    4173

    积分

    论坛元老

    积分
    4173
    发表于 2024-2-27 11:15:28 | 显示全部楼层
    HHJuan 发表于 2024-2-27 09:45
    Test_cnt变量是u16类型的,我尝试了用您说的%u和%hu打印,因为%u是无符号十进制数,所以我又用%x和%lx ...

    能确定RxBuffer里面的内容吗?打印前往RxBuffer写几个固定值试试。
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-17 04:43 , Processed in 0.071594 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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