目前手里有个项目,需要用到IIC通信;
主机用STM32模拟iic,从机用STM8硬件IIC。
现在的问题是主机可以与从机通信,也能讲数据读回来,但是有一点:
收到的第一个字节总是0XFF,然后才是我需要的数据;
但是收到的数据顺序总是不断变化;偶尔数据中还会出现一个字节是0xff。
希望有做过IIC主从机通信的朋友,给予帮助,感激不尽!!!
下面贴上代码:
主机的读数据函数
[mw_shl_code=c,true]
uint32_t read_one_byte(uint8_t s8_address)
{
uint8_t i;
uint32_t rec_32_buff;
bsp_SimuI2C_start(&TouchI2cPort);
bsp_SimuI2C_write_byte(&TouchI2cPort,s8_address);
bsp_SimuI2C_SandAck(&TouchI2cPort);
for(i=0;i<4;i++)
{
rec_32_buff<<=8;
rec_32_buff+=bsp_SimuI2C_read_byte(&TouchI2cPort);
bsp_SimuI2C_SandAck(&TouchI2cPort);
}
bsp_SimuI2C_stop(&TouchI2cPort);
return rec_32_buff;
}
[/mw_shl_code]
接下来是STM8从机程序:
这是IIC中断函数
[mw_shl_code=c,true]
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
//接收发送
u8 temp = 0;
if (I2C->SR1&0x02)//地址已经匹配(读SR1,SR3清除该位)
{
temp = I2C->SR3&0x07;
}
else if ((I2C->SR1&0x84)&&(I2C->SR3&0x04))//数据字节传送完
{
if(data_len>=4)data_len=0;
I2C->DR = My_Buffer[data_len];
data_len++;
}
else if ((I2C->SR1&0x40)&&(0 == (I2C->SR3&0x04)))//接收时数据寄存器
{
temp = I2C->DR; //读取数据寄存器
}
else if (I2C->SR1&0x10)//检测到停止位
{
I2C->CR2 = I2C->CR2;//清除停止位
}
//错误处理
if (I2C->SR2&0x01)//总线错误
{
I2C->SR2 &= ~0x01;//清零
}
else if(I2C->SR2&0x02)//仲裁失败
{
I2C->SR2 &= ~0x02;//清零
}
else if(I2C->SR2&0x04)//应答失败
{
I2C->SR2 &= ~0x04;//清零
}
else if(I2C->SR2&0x08)//上溢、下溢
{
I2C->SR2 &= ~0x08;//清零
}
return;
}
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
无聊继续更... 下面是根据stm32-stm32改的stm8硬件IIC从机,判断标志位的。
[mw_shl_code=c,true]unsigned char a[16]={0x00,0X01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
int main(void)
{
uint8_t *p1; //存放数据的指针
u8 i; //used for circle
All_Congfig(); //总初始化
printf("%c",0xff); //uart test
while(1)
{
p1 = a; //指针p1用来,接收主机数据和发送数据
/**********************************1-send start********************************/
//1 - judge if address matched as slave send data to matser
while(!I2C_CheckEvent(I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED));//地址匹配+从机作为发送方
printf("%c",0x55); //match address
for(i=0;i<15;i++)
{
I2C->DR = *(p1++);
while( !I2C_CheckEvent(I2C_EVENT_SLAVE_BYTE_TRANSMITTED ));
}
I2C->DR = *(p1++);
while( !I2C_CheckEvent(I2C_EVENT_SLAVE_ACK_FAILURE ));
printf("%c",0xfe);
/*********************************1-send end*********************************/
/*******************************2-receive start******************************
//1 - judge if address matched as slave receive data from master
while(!I2C_CheckEvent(I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED));//地址匹配+从机作为接收方
printf("%c",0x55); //show match success
//2 - receive data from master
for(i=0;i<8;i++)
{
while( !I2C_CheckEvent(I2C_EVENT_SLAVE_BYTE_RECEIVED )); //当收到一字节
*(p1++) = I2C_ReceiveData(); //将接收到的iic data放入接收指针p1
printf("%c",*(p1-1));
}
//3 - stop communication
while(!I2C_CheckEvent(I2C_EVENT_SLAVE_STOP_DETECTED ));
printf("%c",0xfe); //show communication ending
*******************************2-receive end********************************/
}
}[/mw_shl_code]
[mw_shl_code=c,true]/* 初始化相关 */
#define I2C_Speed 100000
#define I2C1_SLAVE_ADDRESS7 0x30
void I2C_Slave_Init(void)
{
u8 Input_Clock = 0x0;
/* Get system clock frequency */
Input_Clock = CLK_GetClockFreq()/1000000;
IIC_GPIO_Init();
I2C_Cmd(ENABLE); //一定要在I2C_Init前面
//Init 一定要在I2C_Cmd后面
I2C_Init(I2C_Speed, I2C1_SLAVE_ADDRESS7, I2C_DUTYCYCLE_2,
I2C_ACK_CURR, I2C_ADDMODE_7BIT, Input_Clock);
}
void IIC_GPIO_Init(void)
{
GPIO_Init(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_MODE_OUT_OD_LOW_FAST);
GPIO_Init(IIC_SDA_PORT, IIC_SCL_PIN, GPIO_MODE_OUT_OD_LOW_FAST);
//初始化高速开漏输出,低电平
}[/mw_shl_code]
不过这个靠判断标志位的效果肯定没第一次发的硬件IIC中断好,不过移植程序一步步来好理解点把
发的这几个都只是简单的通讯测试,实际项目中还要加别的判断的,比如主机有时候有问题,stm8硬件从机IIC可能就死在while里,也得根据根据项目的需求来的。另外通讯可以自定义个协议 。
一周热门 更多>