I2C主机收到的RecvData()数值无法正确的输出到串口助手
本帖最后由 liming 于 2023-8-14 16:12 编辑STC8H4K64TLCS作为主机控制合泰BS8116A-3触摸芯片,用逻辑分析仪查看从机可以正确输出触摸数值,但是串口助手接收的信息一直是错误的0xff。求解?
#include <STC8H.H>
#include <intrins.h>
#include <stdio.h>
sbit SDA = P1^4;
sbit SCL = P1^5;
void Delay_ms(unsigned int n)//1毫秒单位,设置时间不能多于65535毫秒。
{
int i;
for(i=0;i<n;i++)
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //定时器0,工作模式1
TH0 = 0xD4; //至初值
TL0 = 0xCD;
TF0 = 0; //清除溢出标志
TR0 = 1; //开启定时器0
EA=0; //关中断(使用查询方式)
ET0=0; //关T0中断
while(TF0 == 0); //溢出等待
TR0 = 0; //暂停定时器
}
}
void Delay_us(unsigned int weimiaoshuliang)//1微秒@12.000MHz
{
unsigned int xunhuancishu;
for(xunhuancishu = 0;xunhuancishu < weimiaoshuliang;xunhuancishu++)
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式,定时器1 工作模式1
TL1 = 0xFF; //设置定时初始值
TH1 = 0xFF; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 0; //关定时器1中断
EA=0; //关中断(使用查询方式)
while(TF1 == 0); //溢出等待
TR1 = 0; //暂停定时器
}
}
void UartInit(void)//115200bps@12MHz
{
SCON = 0x50;//8位数据,可变波特率
AUXR |= 0x40;//定时器1时钟为FOSC,就是1T
AUXR &= 0xFE;//串口1选择定时器1为波特率发生器
TMOD &= 0x0F;//设定定时器1为16位重装载方式
TL1 = 0xE6;//设定定时器低位值
TH1 = 0xFF ;//设定定时器高位值
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;
}
//**********************************************IIC函数定义************************************************
//根据手册查到BS8116A-3数据传输率最高100Kbps
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();
}
unsignedchar chumozhi;
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为准双向口模式。
while(1)
{ P_SW2 = 0x80;
// I2CCFG = 0xDA;//打开IIC开关,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。
//I2CCFG = 0xDC;//IIC的数据传输速率设置为92160=92.16K
// I2CCFG = 0xF4;//IIC的数据传输速率设置为51200=51.2K
I2CCFG = 0xFF;//IIC的数据传输速率设置为42.535K X=63最慢速度
I2CMSST = 0x00;
//*******************检测KeyStatus0寄存器是否有触摸键按下*********************
Start();//向从机发送开始命令信号 SendData(0xA0);//发送合泰BS8116A-3设备地址写命令,合泰BS8116A-3设备地址是0x50(1010000),实际使用时需要在最低位加上R/W读写位0或者1,写命令是0xA0(10100000),读命令是0xA1(10100001)。
RecvACK();//接收从机的ACK应答命令
SendData(0x08);//此芯片的固定格式发送命令 RecvACK(); Start();
SendData(0xA1);
RecvACK();
RecvData();
// chumozhi = RecvData();
UartInit();
printf("触摸按键值是0x%bx\r\n ",RecvData()); Stop(); Delay_ms(200); }
}
你的代码里进行了2次读取,打印的是第二次读取的内容:
从逻辑分析仪抓取的信号分析第二次读取的内容确实是0xff:
页:
[1]