您的位置 首页 知识

STM8S105S4 I2C

STM8S105S4I2C这样配置可以从机发数据,从机接数据就不行,是什么问题//I2C端口初始化GPIO_Init(GPIOE,GPIO_PIN_1

STM8S105S4 I2C这样装备能够从机发数据,从机接数据就不可,是什么问题
//I2C端口初始化
GPIO_Init(GPIOE,GPIO_PIN_1|GPIO_PIN_2, GPIO_MODE_OUT_OD_HIZ_SLOW);
void I2C_init(void)
{
I2C_CCRH = 0; //规范I2C接口
I2C_CCRL = 80 ;
I2C_FREQR = 16;
I2C_OARL = (I2CAddr<<1);
I2C_OARH= 0x40;
I2C_ITR =0x06;
I2C_CR1 =0x01;
I2C_CR2 |=0x04;
}
@far @interrupt void I2C_Handler (void)
{
u8 state1,state2,state3;
state1 = I2C_SR1;
state2 = I2C_SR2;
state3 = I2C_SR3;
//地址匹配
if((state1&0x02)!=0){I2C_CR2 |= 0x04;}
//接纳到数据,需求处理
if( (state1& 0x40) != 0)
{
I2C_CR2|= 0x04;
temp1= I2C_DR;
SetOutput(temp1);
}
//从机需求发送数据
if((state1 & 0x80) != 0)
{
I2C_DR = num++;
}
if((state2 & 0x04) != 0)I2C_SR2 &= ~0x04; //应对失利,铲除该位
if((state1 & 0x10) != 0)
{
I2C_CR2 = 0x02;
}
}
我写成这姿态,发现现在是从机发数据是没问题,从机接纳数据不可,没有进入中止。

成功传输一次正确的数据后就进不去了。程序还正常运转

#define I2CAddr 0x01
在主机
//主机写数据,从机接,这个不可
Soft_I2C_Start();
Soft_I2C_Write(0x02);
Soft_I2C_Write(0xAA);
Soft_I2C_Stop();
//主机接纳数据。没有运转上一段程序,主机能够接纳数据,运转上段,主机接纳数据都是255
Soft_I2C_Start();
Soft_I2C_Write(0x03);
var0=Soft_I2C_Read(1);
Soft_I2C_Stop();
这个软I2C在操控其它设备是没有问题的,主机用的芯片是STM32。应该是没有问题的

解决问题:

这就是了,你第一次成功后了,你把应对给关掉了,还怎样接纳啊。。。今后配寄存器要多一个心眼才是。

问题就在这儿I2C_CR2 = 0x02; 修改为I2C_CR2 |= 0x02;原因是修改了,第一次成功后,没有再回复

1.PC0,PC1初始化,GPIO_Init(GPIOC, GPIO_Pin_1 | GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Fast);
2.有必要衔接硬件
3.总线不能busy,一定要闲暇
初始化代码如下:
GPIO_Init(GPIOC, GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Slow);
GPIO_Init(GPIOC, GPIO_Pin_1, GPIO_Mode_Out_OD_HiZ_Slow);
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
I2C_Init(I2C1, 50000, 0xA5, I2C_Mode_I2C, I2C_DutyCycle_2,
I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
//注:I2C_Init()里现已使能了I2C,所以能够不必I2C_Cmd(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

stm8 自带I2C总算调试成功。

1,此次调试I2C获益多多,首要证明官方的那个写EEPROM的程序是对的。
2,这次调试TW8816开端调不通的原因是误以为寄存器地址是16位的(芯片公司的事务也是这么说的,我信任了),才让我看到的数据不同,但我想,有数据了,并且用WHILE等候的办法,程序跑通了,阐明连上了从机。
3, I2C的GPIO不要装备,我看到有些同仁把GPIO装备了。
4,为了大家用好STM8的I2C,我把程序烤下来。

void IIC_Init(void)
{
UCHAR temp;

CLK_PCKENR1 |= 0x01;

I2C_FREQR |= 0x10; //输入外设时钟频率为1MHz
I2C_CR1 = 0x00; //制止I2C外设
I2C_CCRH&= ~0xcf;
I2C_CCRL&= ~0xff;
I2C_TRISER = 0x11;
I2C_CCRL = 0x10;
I2C_CCRH = 0x00;
I2C_CR1 |= 0x01; //敞开I2C外设
I2C_CR2 |= 0x04; //当时接纳字节回来应对
I2C_CR2 &= 0x08;
I2C_OARL = 0x86; //本身地址
I2C_OARH = 0x40;
}

void Read_8816(UCHAR *pBuffer, UCHAR index, UCHAR NumByteToRead)
{
UCHAR temp;

while(I2C_SR3 & 0x02); //等候总线闲暇
I2C_CR2 |= 0x01; //发生开始位
while(!(I2C_SR1 & 0x01)); //等候START发送完
I2C_DR = 0x8a; //发送8816器材地址
while(!(I2C_SR1 & 0x02)); //等特7位器材地址发送完
temp = I2C_SR1;
temp = I2C_SR3;
I2C_DR = (UCHAR)(index);
while(!(I2C_SR1 & 0x84));

I2C_CR2 |= 0x01; //发生重复开始位
while(!(I2C_SR1 & 0x01)); //等候START发送完
I2C_DR = 0x8b; //读
while(!(I2C_SR1 & 0x02)); //等特7位器材地址发送完
temp = I2C_SR1;
temp = I2C_SR3;
while(NumByteToRead) //要读几个字节
{
if(NumByteToRead == 1)
{
I2C_CR2 &= ~0x04; //不回来应对
I2C_CR2 |= 0x02; //发生中止位
}
if(I2C_SR1 & 0x40)
{
temp = I2C_SR1;
Buff[8-NumByteToRead]=I2C_DR;
*pBuffer = Buff[8-NumByteToRead];
pBuffer++;
NumByteToRead–;
}
}
I2C_CR2 |= 0x04;
I2C_CR2 &= ~0x08; //为下一次接纳使能应对
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/254905.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部