STM32的串口转I2C

sunzhil1987 2012-02-17 10:15:17
请问坛里的各位,STM32的串口接收到的数据如何转成I2C数据格式发送出去呢?给些意见吧!
...全文
647 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Simality 2012-02-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sunzhil1987 的回复:]
引用 7 楼 woshi_ziyu 的回复:

需要外接上拉电阻 最好能接外设

请问,上拉电阻要接多大为好呢?
[/Quote]

时钟不快、外设不多的话10K就行,多个外设时钟400K左右的话可以减到2K,大致这个区间。

上拉和通讯时序都是I2C最基本的知识,建议LZ还是去看看I2C的说明。支持I2C总线的元件数据手册在介绍总线的那一章都会详细说明。如果嫌STM32的手册复杂可以去翻翻24C01的。
sunzhil1987 2012-02-20
  • 打赏
  • 举报
回复
不接外设,直接用示波器就捕捉不到I2C发送数据的信号吗?
sunzhil1987 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 woshi_ziyu 的回复:]

需要外接上拉电阻 最好能接外设
[/Quote]
请问,上拉电阻要接多大为好呢?
woshi_ziyu 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sunzhil1987 的回复:]

不接外设,直接用示波器就捕捉不到I2C发送数据的信号吗?
[/Quote]
需要外接上拉电阻 最好能接外设
Simality 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sunzhil1987 的回复:]
不接外设,直接用示波器就捕捉不到I2C发送数据的信号吗?
[/Quote]

如果I2C发送数据了,当然能捕捉到。问题在于不接外设,主机根本不会发数据。I2C总线是双向的,主机发完地址了要等待外设回复一个ACK信号,没有接外设,主机收不到回复就一直等在那里。
sunzhil1987 2012-02-19
  • 打赏
  • 举报
回复
我现在用示波器测不到I2C1时钟和数据两个管脚的波形,

下面是我的代码(参考了例程给的代码):

////////////////////I2C的配置函数/////////////////////////////
void I2C_Configuration(void)
{
/* Enable I2C1 event and buffer interrupt */
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE); //开启I2C1事件中断与缓冲区中断
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //I2C接口配置成I2C模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //定义I2C周期占空比为:低/高=2
I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7; //配置I2C1_SLAVE_ADDRESS7地址的I2C设备
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能确认特性
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //地址确认
I2C_InitStructure.I2C_ClockSpeed = ClockSpeed; //配置I2C时钟频率
I2C_Init(I2C1, &I2C_InitStructure); //用以上参数配置I2C1
/* Enable I2C1 ----------------------------------------------------*/
I2C_Cmd(I2C1, ENABLE); //使能I2C1

其中 ClockSpeed =200000;
其中 I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7; 我始终不理解这个I2C1_SLAVE_ADDRESS7是什么含义,怎么设置。例程给的是 #define I2C1_SLAVE_ADDRESS7 0x30
这个0X30是根据什么得来的。

/////////////串口配置函数//////////////////
void USART_Configuration(void)
{
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Clock = USART_Clock_Disable;
USART_InitStructure.USART_CPOL = USART_CPOL_Low;
USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_InitStructure.USART_LastBit = USART_LastBit_Disable;
/* Configure the USART1 */
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART Receive interrupt: this interrupt is generated when the
USART1 receive data register is not empty */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
/* Enable USART1 */
USART_Cmd(USART1, ENABLE);

}


////中断设置函数/////////
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM //中断向量表存放位置选择
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //中断向量表存放于RAM中0x00
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); //中断向量表存放于FLASH中0x00
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置优先级组,包括优先级和子优先级

/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


下面是我的main函数
int main(void)
{
#ifdef DEBUG
debug();
#endif

u32 i = 0;
/* System Clocks Configuration(SYSCLK=72M) */
RCC_Configuration();
/* NVIC configuration */
NVIC_Configuration();
/* I2C1 configuration */
I2C_Configuration();
/* USART1 configuration */
USART_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();

//////////////////////////接下来我就不知道该怎么写了////////////////////////////////
while(1)
{ //我的测试代码。想先通过I2C1发0x55电平 ,用示波器观察波形。0x55在示波器上是01010101.
//但在示波器上就是不显示波形。???????
I2C_SendData(I2C1, 0x55);
Delay(1000);
}

}

第一步,我的I2C_SendData(I2C1, 0x55);这句该怎么改,才能测到I2C1的数据线和是时钟线这两个管脚的波形呢?
这个不解决,我接下来就没法做下去了。
Simality 2012-02-19
  • 打赏
  • 举报
回复
I2C总线要工作是需要外接设备回复ACK信号的,只是一个STM32在那里走不下去。SLAVE ADDRESS就是外接设备的地址。你必须让STM32和外设通上,把I2C通路建立起来才能继续传输数据,传输过程也必须符合I2C外设的通讯格式。在这个基础之上才能像我一开始说的收到一个字节就转发一个字节。
durant 2012-02-17
  • 打赏
  • 举报
回复
stm32不是本身有I2C的吗?

串口数据进来I2C,再出去就是了
Simality 2012-02-17
  • 打赏
  • 举报
回复
都能以字节操作,两个模块初始化了一个收一个发就行了啊。异步操作就做两个FIFO,怕拥堵就加入简单协议做个流控,想容错就加入一些错误状态标志。

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧