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;
}
}
最简单方式是用示波器或者逻辑分析仪测量SCL,SDA信号,判断是否有ACK。
也可以在执行完RecvACK函数后读取I2CMSST寄存器的MSACKI位是0(ACK)还是1(NAK)。 IIC主机发送完一个字节后拉高 从机会拉低一下ACK应答 可以检测这个信号
我调试刚开始学习IIC的时候 调试了好长很长时间才知道从机会有个低电平应答信号 不看说明的后果
页:
[1]