liming 发表于 2023-8-1 20:30:28

STC8H作为IIC主机控制从机,怎么查看从机是否应达?

本帖最后由 liming 于 2023-8-1 20:40 编辑

   用STC8H做IIC控制主机连接触摸IC合泰BS8116A-3,通过上网查询触摸IC地址为0x50。当主机发送开始命令+发送地址(0xa0)后,不知道触摸IC是否应答,也不知道写的代码是否有错误。想用printf命令通过串口助手输出到屏幕上。代码如下:

#include    <STC8H.H>
#include    <intrins.h>
#include    <stdio.h>


sbitSDA=P1^4;
sbitSCL=P1^5;


void UartInit(void)//9600bps@11.0592MHz
{
               SCON = 0x50;//8位数据,可变波特率
          AUXR |= 0x40;//定时器1时钟为FOSC,就是1T
          AUXR &= 0xFE;//串口1选择定时器1为波特率发生器
                TMOD &= 0x0F;//设定定时器1为16位重装载方式
                  TL1 = 0xE0;//设定定时器低位值
                  TH1 = 0xFE ;//设定定时器高位值
             ET1 = 0;//禁止定时器1中断
                  TR1 = 1;//启动定时器1
}

void Uart1_SendChar(unsigned char Udat)
{
    SBUF = Udat;//串口1数据寄存器
    while(!TI);//串口1中断发送请求标志
    TI = 0;   
}

char putchar(char c)
{
    Uart1_SendChar(c);
                  return c;
}      




void Wait()
{
      while (!(I2CMSST & 0x40));
      I2CMSST &= ~0x40;
}
void Start()
{
      SCL = 0;//时钟信号拉低电平
      _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//在11.0592MHz频率下,每个_nop_()命令延时1.08us,该特例合泰BS8116A-3需要拉低电平并延时8us。
      SCL = 1;//恢复时钟信号的高电平
      
      I2CMSCR = 0x01; //发送START 命令
      Wait();
}
void SendData(char dat)
{
      I2CTXD = dat; //把想要发送的信息内容写到数据缓冲区,dat替换成信息内容。
      I2CMSCR = 0x02; //把想要发送的信息发送出去
      Wait();
}
void RecvACK()
{
      I2CMSCR = 0x03; //发送读ACK 命令
      Wait();
}
char RecvData()
{
      I2CMSCR = 0x04; //发送RECV 命令
      Wait();
      return I2CRXD;
}
void SendACK()
{
      I2CMSST = 0x00; //设置ACK 信号
      I2CMSCR = 0x05; //发送ACK 命令
      Wait();
}
void SendNAK()
{
      I2CMSST = 0x01; //设置NAK 信号
      I2CMSCR = 0x05; //发送ACK 命令
      Wait();
}
void Stop()
{
      I2CMSCR = 0x06; //发送STOP 命令
      Wait();
}
void Delay()
{
      int i;
      for (i=0; i<3000; i++)
      {
                _nop_();
                _nop_();
                _nop_();
                _nop_();
      }
}

unsigned int zhuandong_TK1;

void main()
      {
             P0M0 = 0x00; P0M1 = 0x00; //设置P0.X引脚为准双向口模式。                                                                                                                                                                                                         
             P1M0 = 0x00; P1M1 = 0x01; //设置P1.0为高阻输入模式,其余P1.X为双向口模式。注:作为ADC电压采集的GPIO引脚也必须设置为高阻输入模式。
             P2M0 = 0x00; P2M1 = 0x00; //设置P2.0~P2.7引脚为准双向口模式。                                                                                                                                                                                                               
             P3M0 = 0x00; P3M1 = 0x00; //设置P3.0~P3.7为准双向口模式。                                                                                                                                                                                                               
             P4M0 = 0x00; P4M1 = 0x00; //设置P4.0~P4.7为准双向口模式。                                                                                                                                                                                                               
             P5M0 = 0x00; P5M1 = 0x00; //设置P5.0~P5.7为准双向口模式。
            P_SW2 = 0x80;//当需要访问XFR寄存器时,必须先将寄存器的B7位置EAXFR置1,才能对XFR 进行正常的读写操作。                                                                                                                                                                                                                                       

                     while(1)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          I2CCFG = 0xDA;//11059200/2/(26*2+4)=98742.8571 根据手册查到BS8116A-3数据传输率最高100Kbps(100K=100000),根据STC8H手册查到I2C速率计算公式 总线速度=FOSC / 2 / (MSSPEED * 2 + 4);十进制26转化为二级制为11010,I2CCFG控制器前两位是控制器11,集中到一起二进制是11011010,十六进制是DA。                                                                                                               I2CMSST = 0x00;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   //*******************检测KeyStatus0寄存器是否有触摸键按下*********************
                                                                                  Start();//向从机发送开始命令信号
                                                                                  SendData(0xa0);//发送合泰BS8116A-3设备地址写命令,合泰BS8116A-3设备地址是0x50(1010000),实际使用时需要在最低位加上R/W读写位0或者1,写命令是0xA0(10100000),读命令是0xA1(10100001)。
                                                                                  RecvACK();//接收从机的ACK应答命令
                                                                                  UartInit();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          printf("主机发出地址写后,从机返回地址%02bx\r\n ", I2CMSST);               //查看是否接收到从机发来的ACK应答命令
                                                                                  SendData(0x08);//此芯片的固定格式发送命令
                                                                                  RecvACK();
                                                                                  Start();
                                                                                  SendData(0xa1);
                                                                                  RecvACK();
                                                                                  SendData(0x01);
                                                                                  SendNAK()
                                                                                  Stop();
                                                                                  zhuandong_TK1 = I2CMSST;
                                                       }
         }


乘风飞扬 发表于 2023-8-2 18:35:38

最简单方式是用示波器或者逻辑分析仪测量SCL,SDA信号,判断是否有ACK。
也可以在执行完RecvACK函数后读取I2CMSST寄存器的MSACKI位是0(ACK)还是1(NAK)。

lzzasd 发表于 2023-8-4 20:26:38

IIC主机发送完一个字节后拉高    从机会拉低一下ACK应答    可以检测这个信号   
我调试刚开始学习IIC的时候   调试了好长很长时间才知道从机会有个低电平应答信号   不看说明的后果
页: [1]
查看完整版本: STC8H作为IIC主机控制从机,怎么查看从机是否应达?