专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
哪位大神用stm8s003做IIC的从机?
2019-07-14 19:51
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
5979
18
1326
为什么主一直写正常,一直读也正常,但是写过之后再读,第一次读到的是0XFF,第二次读到的数据才是正确的呢?不知有哪位大神遇见过这个问题,指点一下
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
18条回答
风_轻_云淡
2019-07-17 06:00
//*******************硬件IIC从测试程序******************/
#include "stm8s.h"
#define SLAVE_ADDRESS 0xA0
void main(void)
{
/* system_clock / 1 */
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
I2C_DeInit();
/* Initialize I2C peripheral */
I2C_StretchClockCmd(DISABLE);
I2C_Init(100000, SLAVE_ADDRESS, I2C_DUTYCYCLE_16_9, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
/* Enable Error Interrupt*/
I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
/* Enable general interrupts */
enableInterrupts();
/*Main Loop */
while (1)
{
/* infinite loop */
}
}
/------------------------------------------------------------------------------------
下面是中断函数
------------------------------------------------------------------------------------/
unsigned char Slave_Buffer_Rx[10];
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
static unsigned char reg_slave = 0;
static unsigned char rx_count = 0;
/* Read SR2 register to get I2C error */
if ((I2C->SR2) != 0)
{
/* Clears SR2 register */
I2C->SR2 = 0;
}
Event = I2C_GetLastEvent();
switch (Event)
{
/******* Slave transmitter ******/
/* check on EV1 */
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
break;
/* check on EV3 */
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
/* Transmit data */
I2C_SendData(Slave_Buffer_Rx[reg_slave]);
break;
/******* Slave receiver **********/
/* check on EV1*/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
rx_count = 1;
break;
/* Check on EV2*/
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
if(rx_count == 1)
{
reg_slave = I2C_ReceiveData();
rx_count = 2;
}
else if(rx_count == 2)
{
Slave_Buffer_Rx[reg_slave] = I2C_ReceiveData();
rx_count = 0;
}
break;
/* Check on EV4 */
case (I2C_EVENT_SLAVE_STOP_DETECTED):
/* write to CR2 to clear STOPF flag */
I2C->CR2 |= I2C_CR2_ACK;
break;
default:
break;
}
}
//*******************硬件IIC主测试程序******************//
#include "stm8s.h"
#define EEPROM_ADDRESS 0xA0
#define Fsys 16000000
void Delay_ms(unsigned int mm)
{
unsigned int mm2,mm1=Fsys/6000;
while(mm--)
for(mm2=mm1;mm2>0;mm2--);
}
void I2C_Config(void)
{
I2C_DeInit();
I2C_Init(100000, 0xB0, I2C_DUTYCYCLE_16_9, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
I2C_Cmd(ENABLE);
}
/*******************************************************************************
* 名称: I2C_EEPROM_WriteOneByte
* 功能: I2C主模式往I2C从器件内部地址写一个字节
* 形参: WriteAddr Byte
* 返回: 无
* 说明:
*/
void I2C_WriteOneByte(u8 WriteAddr,u8 Byte)
{
/* 等待空闲 */
//while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
while((I2C->SR3 & 0x02 ) != 0);
/* 发起始位 */
//I2C_GenerateSTART(ENABLE);
I2C->CR2 |= 0x01;
/* 测试EV5 ,检测从器件返回一个应答信号*/
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 设置I2C从器件地址,I2C主设备为写模式*/
I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
/* 测试EV6并清除标志位,检测从器件返回一个应答信号 */
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* 设置往从器件写数据内部的地址 */
//I2C_SendData(WriteAddr);
I2C->DR = WriteAddr;
/* 测试EV8并清除标志位 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
/* 向从器件写一个字节 */
//I2C_SendData(Byte);
I2C->DR = Byte;
/* 测试EV8_2并清除标志位,检测从器件返回一个应答信号 */
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* 发结束位 */
//I2C_GenerateSTOP(ENABLE);
I2C->CR2 |= 0x02;
}
/*************************************************************************
* 名称: I2C_EEPROM_ReadOneByte
* 功能: 从从设备读取一个字节
* 形参: ReadAddr
* 返回: 字节数据
* 说明: 无
*/
u8 I2C_ReadOneByte(u8 ReadAddr)
{
u8 RxData;
/* 等待空闲 */
//while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
while((I2C->SR3 & 0x02 ) != 0);
/* 发起始位 */
//I2C_GenerateSTART(ENABLE);
I2C->CR2 |= 0x01;
/* 测试EV5 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 设置I2C从器件地址,I2C主设备为写模式*/
I2C_Send7bitAddress(EEPROM_ADDRESS , I2C_DIRECTION_TX);
/* 测试EV6并清除标志位 */
while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
//I2C_SendData(ReadAddr);
I2C->DR = ReadAddr;
/* 测试EV8并清除标志位 */
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* 发起始位 */
//I2C_GenerateSTART(ENABLE);
I2C->CR2 |= 0x01;
/* 测试EV5 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 设置I2C从器件地址,I2C主设备为读模式*/
I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_RX);
/* 测试EV6 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
//I2C_AcknowledgeConfig(I2C_ACK_NONE);//不使能应答
I2C->CR2 &= 0xfb;
/* 测试EV7,等待数据接收完毕 */
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED));
//RxData=I2C_ReceiveData();
RxData = ((uint8_t)I2C->DR);
/* 发结束位*/
//I2C_GenerateSTOP(ENABLE);
I2C->CR2 |= 0x02;
return RxData;
}
void main(void)
{
unsigned char read_data;
/*配置内部16MHz时钟------------------------------*/
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
I2C_Config();
while(1)
{
I2C_WriteOneByte(5,0x11);
read_data = I2C_ReadOneByte(5);
Delay_ms(100);
}
}
加载中...
查看其它18个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
#include "stm8s.h"
#define SLAVE_ADDRESS 0xA0
void main(void)
{
/* system_clock / 1 */
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
I2C_DeInit();
/* Initialize I2C peripheral */
I2C_StretchClockCmd(DISABLE);
I2C_Init(100000, SLAVE_ADDRESS, I2C_DUTYCYCLE_16_9, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
/* Enable Error Interrupt*/
I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
/* Enable general interrupts */
enableInterrupts();
/*Main Loop */
while (1)
{
/* infinite loop */
}
}
/------------------------------------------------------------------------------------
下面是中断函数
------------------------------------------------------------------------------------/
unsigned char Slave_Buffer_Rx[10];
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
static unsigned char reg_slave = 0;
static unsigned char rx_count = 0;
/* Read SR2 register to get I2C error */
if ((I2C->SR2) != 0)
{
/* Clears SR2 register */
I2C->SR2 = 0;
}
Event = I2C_GetLastEvent();
switch (Event)
{
/******* Slave transmitter ******/
/* check on EV1 */
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
break;
/* check on EV3 */
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
/* Transmit data */
I2C_SendData(Slave_Buffer_Rx[reg_slave]);
break;
/******* Slave receiver **********/
/* check on EV1*/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
rx_count = 1;
break;
/* Check on EV2*/
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
if(rx_count == 1)
{
reg_slave = I2C_ReceiveData();
rx_count = 2;
}
else if(rx_count == 2)
{
Slave_Buffer_Rx[reg_slave] = I2C_ReceiveData();
rx_count = 0;
}
break;
/* Check on EV4 */
case (I2C_EVENT_SLAVE_STOP_DETECTED):
/* write to CR2 to clear STOPF flag */
I2C->CR2 |= I2C_CR2_ACK;
break;
default:
break;
}
}
//*******************硬件IIC主测试程序******************//
#include "stm8s.h"
#define EEPROM_ADDRESS 0xA0
#define Fsys 16000000
void Delay_ms(unsigned int mm)
{
unsigned int mm2,mm1=Fsys/6000;
while(mm--)
for(mm2=mm1;mm2>0;mm2--);
}
void I2C_Config(void)
{
I2C_DeInit();
I2C_Init(100000, 0xB0, I2C_DUTYCYCLE_16_9, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
I2C_Cmd(ENABLE);
}
/*******************************************************************************
* 名称: I2C_EEPROM_WriteOneByte
* 功能: I2C主模式往I2C从器件内部地址写一个字节
* 形参: WriteAddr Byte
* 返回: 无
* 说明:
*/
void I2C_WriteOneByte(u8 WriteAddr,u8 Byte)
{
/* 等待空闲 */
//while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
while((I2C->SR3 & 0x02 ) != 0);
/* 发起始位 */
//I2C_GenerateSTART(ENABLE);
I2C->CR2 |= 0x01;
/* 测试EV5 ,检测从器件返回一个应答信号*/
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 设置I2C从器件地址,I2C主设备为写模式*/
I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_TX);
/* 测试EV6并清除标志位,检测从器件返回一个应答信号 */
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* 设置往从器件写数据内部的地址 */
//I2C_SendData(WriteAddr);
I2C->DR = WriteAddr;
/* 测试EV8并清除标志位 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
/* 向从器件写一个字节 */
//I2C_SendData(Byte);
I2C->DR = Byte;
/* 测试EV8_2并清除标志位,检测从器件返回一个应答信号 */
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* 发结束位 */
//I2C_GenerateSTOP(ENABLE);
I2C->CR2 |= 0x02;
}
/*************************************************************************
* 名称: I2C_EEPROM_ReadOneByte
* 功能: 从从设备读取一个字节
* 形参: ReadAddr
* 返回: 字节数据
* 说明: 无
*/
u8 I2C_ReadOneByte(u8 ReadAddr)
{
u8 RxData;
/* 等待空闲 */
//while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
while((I2C->SR3 & 0x02 ) != 0);
/* 发起始位 */
//I2C_GenerateSTART(ENABLE);
I2C->CR2 |= 0x01;
/* 测试EV5 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 设置I2C从器件地址,I2C主设备为写模式*/
I2C_Send7bitAddress(EEPROM_ADDRESS , I2C_DIRECTION_TX);
/* 测试EV6并清除标志位 */
while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
//I2C_SendData(ReadAddr);
I2C->DR = ReadAddr;
/* 测试EV8并清除标志位 */
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
/* 发起始位 */
//I2C_GenerateSTART(ENABLE);
I2C->CR2 |= 0x01;
/* 测试EV5 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
/* 设置I2C从器件地址,I2C主设备为读模式*/
I2C_Send7bitAddress(EEPROM_ADDRESS, I2C_DIRECTION_RX);
/* 测试EV6 ,检测从器件返回一个应答信号*/
while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
//I2C_AcknowledgeConfig(I2C_ACK_NONE);//不使能应答
I2C->CR2 &= 0xfb;
/* 测试EV7,等待数据接收完毕 */
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED));
//RxData=I2C_ReceiveData();
RxData = ((uint8_t)I2C->DR);
/* 发结束位*/
//I2C_GenerateSTOP(ENABLE);
I2C->CR2 |= 0x02;
return RxData;
}
void main(void)
{
unsigned char read_data;
/*配置内部16MHz时钟------------------------------*/
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
I2C_Config();
while(1)
{
I2C_WriteOneByte(5,0x11);
read_data = I2C_ReadOneByte(5);
Delay_ms(100);
}
}
一周热门 更多>