- 打卡等级:初来乍到
 
				- 打卡总天数:6
 
				
				
				- 最近打卡:2024-03-02 15:38:24
 
				  
注册会员 
 
 
	- 积分
 - 86
 
 
 
 
 | 
 
STC8H8K64U与ESP32/Arduino的新结合!! 
最近研究STC8K8K64U与ESP32的主从IIC通信,以STC8H8K64U作为IIC从机接收ESP32(IIC主机)发送的消息。 
目前遇到的问题是:STC8K8K64U接收到的消息与ESP32发送的消息不一致。 
如下图所示: 
 
 
 
测试结果发现:STC8H8K64U接收到的消息是ESP32发送消息*2的内容,但当发送的数据是3位数后,STC接收到的数据是后2位数的结果。 
 
 
 
ESP32采用ArduinoIDE编程,SCL->IO22, SDA->IO23,通过Serial0查看发送的消息,ESP32端代码如下: 
 
 
/** 
 * 这是主机的程序 
 */ 
#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(num);    //传送数字字符串 
  Serial.println(num); 
  int ret = Wire.endTransmission(); 
  if(ret != 0) 
  { 
    Serial.printf("send failed: %d\r\n", ret); 
    return; 
  } 
 
 
STC8K8K64U采用keil5编程,SCL->P3.2, SDA->P3.3,时钟 24MHz,通过USB转TTL模块接STC8K8K64U的3.0 3.1引脚查看接收到的消息,STC8K8K64U端代码如下: 
 
#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 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; 
            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 
        { 
           // Rx_Cnt = 0; 
            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 = 0x2d;                            //设置从机设备地址为5A 
    I2CSLST = 0x00; 
    I2CSLCR = 0x78;                             //使能从机模式中断 
    DisplayFlag = 0; 
    UART1_config(1);    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率. 
    EA = 1; 
    isda = 1;                                   //用户变量初始化 
    isma = 1; 
    addr = 0; 
    I2CTXD = RxBuffer[addr];  
    while (1) 
                { 
                        if(DisplayFlag) 
                        { 
                                DisplayFlag = 0; 
                                if(RxBuffer[0] < 10) 
                                { 
                                                printf("I2CRXD=%bd\r\n",I2CRXD);  //尝试打印接收到的消息 
                                                printf("RxBuffer=%bd\r\n",RxBuffer[0]);  //尝试打印接收到的消息 
                                                printf("Rx_Cnt=%bd\r\n",Rx_Cnt);  //尝试打印接收到的消息 
                                } 
                        } 
                } 
} 
//======================================================================== 
// 函数: SetTimer2Baudraye(u16 dat) 
// 描述: 设置Timer2做波特率发生器。 
// 参数: dat: Timer2的重装值. 
// 返回: none. 
//======================================================================== 
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. 
//======================================================================== 
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; 
} 
//========================================================================bh88gt 
// 函数: void UART1_int (void) interrupt UART1_VECTOR 
// 描述: UART1中断函数。 
// 参数: nine. 
// 返回: none. 
//======================================================================== 
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; 
    } 
} 
 
 
 |   
 
 
 
 |