找回密码
 立即注册
查看: 398|回复: 2

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

[复制链接]

该用户从未签到

4

主题

6

回帖

46

积分

新手上路

积分
46
发表于 2023-8-1 20:30:28 | 显示全部楼层 |阅读模式
本帖最后由 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>


sbit  SDA  =  P1^4;
sbit  SCL  =  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;
                                                       }
           }


8116A-3.png
回复 送花

使用道具 举报

  • TA的每日心情
    奋斗
    8 小时前
  • 签到天数: 143 天

    [LV.7]常住居民III

    27

    主题

    1342

    回帖

    4185

    积分

    论坛元老

    积分
    4185
    发表于 2023-8-2 18:35:38 | 显示全部楼层
    最简单方式是用示波器或者逻辑分析仪测量SCL,SDA信号,判断是否有ACK。
    也可以在执行完RecvACK函数后读取I2CMSST寄存器的MSACKI位是0(ACK)还是1(NAK)。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 10:04
  • 签到天数: 122 天

    [LV.7]常住居民III

    9

    主题

    92

    回帖

    590

    积分

    高级会员

    积分
    590
    发表于 2023-8-4 20:26:38 | 显示全部楼层
    IIC主机发送完一个字节后拉高    从机会拉低一下ACK应答    可以检测这个信号   
    我调试刚开始学习IIC的时候   调试了好长很长时间才知道从机会有个低电平应答信号     不看说明的后果
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-17 17:40 , Processed in 0.060605 second(s), 40 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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