打印
[STM32F1]

【转】stm32 i2c通信 使用库函数

[复制链接]
577|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一灯大神|  楼主 | 2016-12-4 00:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
库函数操作

main.c
[cpp] view plain copy


  • #include "stm32f10x.h"  
  • #include "stdio.h"  
  •   
  • #define  PRINTF_ON  1  
  •   
  • void RCC_Configuration(void);  
  • void GPIO_Configuration(void);  
  • void USART_Configuration(void);  
  • void I2C_Configuration(void);  
  • void NVIC_Configuration(void);  
  •   
  •   
  • u8 I2C1_ADDRESS = 0x30;   //7位 I2C 地址  
  • u8 I2C2_ADDRESS = 0x31;  
  •   
  • #define Size 4  
  •   
  • vu8 I2C1_Buffer_Tx[Size] = {1,2,3,4};  
  • vu8 I2C2_Buffer_Rx[Size] = {0};  
  •   
  • u32 BufferSize = Size ;  
  •   
  • int main(void)  
  • {  
  •     RCC_Configuration();  
  •     GPIO_Configuration();  
  •     USART_Configuration();  
  •     I2C_Configuration();  
  •     NVIC_Configuration();  
  •   
  •     I2C_GenerateSTART(I2C1,ENABLE);  
  •   
  •     while(1);     
  • }  
  •   
  • void I2C_Configuration(void)  
  • {  
  •     I2C_InitTypeDef I2C_InitStructure;  
  •   
  •     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;  
  •     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  
  •     I2C_InitStructure.I2C_OwnAddress1 = I2C1_ADDRESS;  
  •     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  
  •     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  
  •     I2C_InitStructure.I2C_ClockSpeed = 200000;  
  •     I2C_Init(I2C1,&I2C_InitStructure);  
  •   
  •     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;  
  •     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  
  •     I2C_InitStructure.I2C_OwnAddress1 = I2C2_ADDRESS;  
  •     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  
  •     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  
  •     I2C_InitStructure.I2C_ClockSpeed = 200000;  
  •     I2C_Init(I2C2,&I2C_InitStructure);  
  •   
  •   
  •     I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,ENABLE);  
  •     I2C_ITConfig(I2C2,I2C_IT_EVT|I2C_IT_BUF,ENABLE);  
  •       
  •     I2C_Cmd(I2C1,ENABLE);  
  •     I2C_Cmd(I2C2,ENABLE);  
  • }  
  •   
  • void NVIC_Configuration(void)  
  • {  
  •     NVIC_InitTypeDef NVIC_InitStructure;  
  •   
  •     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  •   
  •     NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;  
  •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
  •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  •     NVIC_Init(&NVIC_InitStructure);  
  •   
  •     NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;  
  •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  •     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  •     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  •     NVIC_Init(&NVIC_InitStructure);  
  • }  
  •   
  • void GPIO_Configuration(void)  
  • {  
  •     GPIO_InitTypeDef    GPIO_InitStructure;  
  •   
  •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  •   
  •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;  
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;           
  •     GPIO_Init(GPIOB , &GPIO_InitStructure);   
  •   
  •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;        
  •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;   
  •     GPIO_Init(GPIOB , &GPIO_InitStructure);   
  •   
  •   
  •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           
  •     GPIO_Init(GPIOA , &GPIO_InitStructure);   
  •       
  •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;            
  •     GPIO_Init(GPIOA , &GPIO_InitStructure);   
  • }  
  •   
  • void RCC_Configuration(void)  
  • {  
  •     /* 定义枚举类型变量 HSEStartUpStatus */  
  •     ErrorStatus HSEStartUpStatus;  
  •   
  •     /* 复位系统时钟设置*/  
  •     RCC_DeInit();  
  •     /* 开启HSE*/  
  •     RCC_HSEConfig(RCC_HSE_ON);  
  •     /* 等待HSE起振并稳定*/  
  •     HSEStartUpStatus = RCC_WaitForHSEStartUp();  
  •     /* 判断HSE起是否振成功,是则进入if()内部 */  
  •     if(HSEStartUpStatus == SUCCESS)  
  •     {  
  •         /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */  
  •         RCC_HCLKConfig(RCC_SYSCLK_Div1);   
  •         /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */  
  •         RCC_PCLK2Config(RCC_HCLK_Div1);   
  •         /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */  
  •         RCC_PCLK1Config(RCC_HCLK_Div2);  
  •         /* 设置FLASH延时周期数为2 */  
  •         FLASH_SetLatency(FLASH_Latency_2);  
  •         /* 使能FLASH预取缓存 */  
  •         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
  •         /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */  
  •         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  
  •         /* 使能PLL */   
  •         RCC_PLLCmd(ENABLE);  
  •         /* 等待PLL输出稳定 */  
  •         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  
  •         /* 选择SYSCLK时钟源为PLL */  
  •         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
  •         /* 等待PLL成为SYSCLK时钟源 */  
  •         while(RCC_GetSYSCLKSource() != 0x08);  
  •     }   
  •     /* 打开APB2总线上的GPIOA时钟*/  
  •     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_USART1, ENABLE);  
  •   
  •     //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  
  •   
  •     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2,ENABLE);  
  •     //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG|RCC_APB1Periph_SPI2, ENABLE);  
  •          
  • }  
  •   
  •    
  • void USART_Configuration(void)  
  • {  
  •     USART_InitTypeDef USART_InitStructure;  
  •     USART_ClockInitTypeDef USART_ClockInitStructure;  
  •   
  •     USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;  
  •     USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;  
  •     USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                        
  •     USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;  
  •     USART_ClockInit(USART1 , &USART_ClockInitStructure);  
  •   
  •     USART_InitStructure.USART_BaudRate = 9600;  
  •     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_Init(USART1,&USART_InitStructure);  
  •   
  •     USART_Cmd(USART1,ENABLE);  
  • }  
  •   
  • #if  PRINTF_ON  
  •   
  • int fputc(int ch,FILE *f)  
  • {  
  •     USART_SendData(USART1,(u8) ch);  
  •     while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);  
  •     return ch;  
  • }  
  •   
  • #endif  



沙发
一灯大神|  楼主 | 2016-12-4 00:45 | 只看该作者
stm32f10x_it.c
[cpp] view plain copy


  • #include "stm32f10x_it.h"  
  • #include "stdio.h"  
  •   
  • extern u32 BufferSize ;  
  • extern u8 I2C1_ADDRESS ;  
  • extern u8 I2C2_ADDRESS ;  
  •   
  • extern vu8 I2C1_Buffer_Tx[];  
  • extern vu8 I2C2_Buffer_Rx[];  
  • vu32 Tx_Counter = 0;  
  • vu32 Rx_Counter = 0;  
  •   
  • void I2C1_EV_IRQHandler(void)  
  • {  
  •     switch(I2C_GetLastEvent(I2C1))  
  •     {  
  •         case I2C_EVENT_MASTER_MODE_SELECT: //已发送启始条件  
  •         {  
  •             I2C_Send7bitAddress(I2C1,I2C2_ADDRESS,I2C_Direction_Transmitter);     
  •             break;  
  •         }  
  •         case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: //已发送从机地址  
  •         {  
  •             printf("\r\n The I2C1 has send data %d \r\n",I2C1_Buffer_Tx[Rx_Counter]);  
  •             I2C_SendData(I2C1,I2C1_Buffer_Tx[Tx_Counter++]);  
  •             break;  
  •         }  
  •         case I2C_EVENT_MASTER_BYTE_TRANSMITTED: //第一个数据已发送  
  •         {  
  •             if(Tx_Counter<BufferSize)  
  •             {  
  •                 printf("\r\n The I2C1 has send data %d \r\n",I2C1_Buffer_Tx[Rx_Counter]);  
  •                 I2C_SendData(I2C1,I2C1_Buffer_Tx[Tx_Counter++]);                  
  •   
  •             }else{  
  •                 I2C_GenerateSTOP(I2C1,ENABLE);  
  •                 I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,DISABLE);  //计数发送的个数  
  •             }  
  •   
  •             break;  
  •         }  
  •         default: {break;}  
  •     }  
  • }  
  •   
  •   
  • void I2C2_EV_IRQHandler(void)  
  • {  
  •     switch(I2C_GetLastEvent(I2C2))  
  •     {  
  •         case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //收到匹配的地址数据  
  •         {  
  •             break;  
  •         }  
  •         case I2C_EVENT_SLAVE_BYTE_RECEIVED: //收到数据  
  •         {     
  •             if(Rx_Counter < BufferSize )  
  •             {  
  •                 I2C2_Buffer_Rx[Rx_Counter] = I2C_ReceiveData(I2C2);  
  •                 printf("\r\n The I2C2 has received data %d \r\n",I2C2_Buffer_Rx[Rx_Counter++]); //计数收到的个数                 
  •             }  
  •             break;  
  •         }  
  •         case I2C_EVENT_SLAVE_STOP_DETECTED: //收到结束条件  
  •         {  
  •             I2C_ClearFlag(I2C2,I2C_FLAG_STOPF);  
  •             I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,DISABLE);  
  •   
  •             break;  
  •         }  
  •         default: {break;}  
  •     }  
  • }  



使用特权

评论回复
板凳
一灯大神|  楼主 | 2016-12-4 00:46 | 只看该作者
串口接收数据如下:

I2C1 Start ..
I2C1 has send address ..
Write 0x86 to At24c02 ,Address 0x01 ..  
I2C1 Start ..
I2C1 has send address ..
I2C1 Start ..
I2C1 has send address ..
Read 0x86 from At24c02 ,Address 0x01 ..  


使用特权

评论回复
地板
mintspring| | 2016-12-4 11:12 | 只看该作者
现在是彻底明白了,搞这些外设就是在配置一堆的结构体变量,然后传递给寄存器。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

112

帖子

2

粉丝