STM32学习之I2C

2019-04-02来源: eefocus 关键字:STM32  I2C
30
31    I2C1 -> OAR1 |= 0<<15;             //寻址模式   1 响应10位地址  0  响应7位地址   
32
33    I2C1 -> OAR1 |= 1<<14;             //必须始终由软件保持为 1
34
35    I2C1 -> OAR1 |=  Addr <<1 ;            //设置接口地址的 7~1位
36
37    //I2C1 -> OAR1 |=  0 ;           //设置10位地址模式时地址第0位 
38    //I2C1 -> OAR1 |= 0<<8;                //设置10位地址模式时地址第9~8位
39
40    //I2C1 -> CR2 |=  1<<10;               //缓冲器中断使能
41    I2C1 -> CR2 |=  1<<9;              //事件中断使能
42    I2C1 -> CR2 |=  1<<8;              //出错中断使能
43
44    I2C1 -> CR1 |=   1<<0;             //开启I2C1
45}
46
47
48void  I2c_Start()
49{
50
51    I2C1 -> CR1 |=   1<<8;             //I2C1产生起始条件
52}
53
54void  I2c_Stop()
55{
56    I2C1 -> CR1 |=   1<<9;             //I2C1产生停止条件
57}
58
59
60void  I2c_Write(u8 data)
61{
62    I2C1 -> DR = data;
63}
64
65u8  I2c_Read()
66{
67    while(!(I2C1 -> SR1 & 1<<6));      //接收到数据标志位
68
69    return I2C1 -> DR;
70}
71
72void  I2c_End()                         //关闭I2C
73{
74    I2C1 -> CR1 &=   ~(1<<0);      
75}

 

Library/inc/i2c.h

 

1#include
2
3void I2c_Init(u16 Addr );   
4
5void  I2c_Start(void);
6void  I2c_Stop(void);
7void  I2c_Write(u8 data);
8u8    I2c_Read(void);
9void  I2c_End(void);

串口接收数据如下:

 

 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 ..  

 

 

库函数操作

 

main.c

001#include "stm32f10x.h"
002#include "stdio.h"
003
004#define  PRINTF_ON  1
005
006void RCC_Configuration(void);
007void GPIO_Configuration(void);
008void USART_Configuration(void);
009void I2C_Configuration(void);
010void NVIC_Configuration(void);
011
012
013u8 I2C1_ADDRESS = 0x30;   //7位 I2C 地址
014u8 I2C2_ADDRESS = 0x31;
015
016#define Size 4
017
018vu8 I2C1_Buffer_Tx[Size] = {1,2,3,4};
019vu8 I2C2_Buffer_Rx[Size] = {0};
020
021u32 BufferSize = Size ;
022
023int main(void)
024{
025    RCC_Configuration();
026    GPIO_Configuration();
027    USART_Configuration();
028    I2C_Configuration();
029    NVIC_Configuration();
030
031    I2C_GenerateSTART(I2C1,ENABLE);
032
033    while(1);   
034}
035
036void I2C_Configuration(void)
037{
038    I2C_InitTypeDef I2C_InitStructure;
039
040    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
041    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
042    I2C_InitStructure.I2C_OwnAddress1 = I2C1_ADDRESS;
043    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
044    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
045    I2C_InitStructure.I2C_ClockSpeed = 200000;
046    I2C_Init(I2C1,&I2C_InitStructure);
047
048    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
049    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
050    I2C_InitStructure.I2C_OwnAddress1 = I2C2_ADDRESS;
051    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
052    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
053    I2C_InitStructure.I2C_ClockSpeed = 200000;
054    I2C_Init(I2C2,&I2C_InitStructure);
055
056
057    I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,ENABLE);
058    I2C_ITConfig(I2C2,I2C_IT_EVT|I2C_IT_BUF,ENABLE);
059
060    I2C_Cmd(I2C1,ENABLE);
061    I2C_Cmd(I2C2,ENABLE);
062}
063
064void NVIC_Configuration(void)
065{
066    NVIC_InitTypeDef NVIC_InitStructure;
067
068    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
069
070    NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
071    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
072    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
073    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
074    NVIC_Init(&NVIC_InitStructure);
075
076    NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
077    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
078    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
079    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
080    NVIC_Init(&NVIC_InitStructure);
081}
082
083void GPIO_Configuration(void)
084{
085    GPIO_InitTypeDef    GPIO_InitStructure;
086
087    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
088
089    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
090    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;         
091    GPIO_Init(GPIOB , &GPIO_InitStructure); 
092
093    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;      
094    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
095    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; 
096    GPIO_Init(GPIOB , &GPIO_InitStructure); 
097
098
099    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
100    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
101    GPIO_Init(GPIOA , &GPIO_InitStructure); 
102
103    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
104    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;           
105    GPIO_Init(GPIOA , &GPIO_InitStructure); 
106}
107
108void RCC_Configuration(void)
109{
110    /* 定义枚举类型变量 HSEStartUpStatus */
111    ErrorStatus HSEStartUpStatus;
112
113    /* 复位系统时钟设置*/
114    RCC_DeInit();
115    /* 开启HSE*/
116    RCC_HSEConfig(RCC_HSE_ON);
117    /* 等待HSE起振并稳定*/
118    HSEStartUpStatus = RCC_WaitForHSEStartUp();
119    /* 判断HSE起是否振成功,是则进入if()内部 */
120    if(HSEStartUpStatus == SUCCESS)
121    {
122        /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
123        RCC_HCLKConfig(RCC_SYSCLK_Div1); 
124        /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
125        RCC_PCLK2Config(RCC_HCLK_Div1); 
126        /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
127        RCC_PCLK1Config(RCC_HCLK_Div2);
128        /* 设置FLASH延时周期数为2 */
129        FLASH_SetLatency(FLASH_Latency_2);
130        /* 使能FLASH预取缓存 */
131        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
132        /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
133        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
134        /* 使能PLL */ 
135        RCC_PLLCmd(ENABLE);
136        /* 等待PLL输出稳定 */
[1] [2] [3] [4]

关键字:STM32  I2C

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2019/ic-news040243677_3.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 IIC 详解 之 stm32 IIC 从机模式
下一篇:最后一页

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32Cube 工具说明和安装浅析

1、STM32CubeMX 简介说明STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具,允许用户使用图形化向导生成C 初始化代码,可以大大减轻开发工作,时间和费用。STM32CubeMX几乎覆盖了STM32 全系列芯片。它具有如下特性:1)直观的选择MCU 型号,可指定系列、封装、外设数量等条件;2)微控制器图形化配置;3)自动处理引脚冲突;4)动态设置时钟树,生成系统时钟配置代码;5)可以动态设置外围和中间件模式和初始化;6)功耗预测;7)C 代码工程生成器覆盖了STM32 微控制器初始化编译软件,如IAR, KEIL,GCC;8)可以独立使用或者作为Eclipse 插件使用
发表于 2019-04-01

STM32 编译结果 map 之 code、RO-data、RW-data、ZI-data 字段解析

1、Code即代码域,它指的是编译器生成的机器指令,这些内容被存储到ROM区。2、RO-dataRead Only data,即只读数据域,它指程序中用到的只读数据,这些数据被存储在ROM区,因而程序不能修改其内容。例如:C语言中const关键字定义的变量就是典型的RO-data。3、RW-dataRead Write data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值,且运行的时候它们会常驻在RAM区,因而应用程序可以修改其内容。例如:C语言中使用定义的全局变量,且定义时赋予“非0值”给该变量进行初始化。4、ZI-dataZero Initialie data,即0初始化数据
发表于 2019-04-01

STM32 结构体位域操作 (int a:4)

本身的长度,比如int类型就能超过32位二进位。3)位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:     struct k     {     int a:1     int :2 /*该2位不能使用*/     int b:3     int c:2     };  从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的。   
发表于 2019-04-01

STM32 分散加载文件 .sct 解析

1、STM32 启动文件与 .sct 文件分析1) 定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K;2) 定义HEAP段, {NOINIT,读写}:分配一段内存大小为1K;3) 定义RESET段,{DATA,只读}:DCD各种中断向量;4) 定义|.text|段,{CODE,只读}:Reset_Handler函数,函数中最后加载了__main;对剩余的中断函数进行了弱定义;在最后还有一段用户初始化堆栈的代码__user_initial_stackheap。那这些代码都存放在什么位置呢?5) 分析 .sct 文件:分散加载文件(即scatter file,后缀为.scf)。分散加载文件是一个文本文件,通过编写
发表于 2019-04-01

STM32 启动代码 __main 与用户主程序 main() 的区别

了。startup.s 这个文件并没有所谓的"段拷贝"功能。对含有启动程序来说,"执行地址与加载地址相同"不容易实现:如果执行地址与加载地址相同哪当然不需要做"段拷贝",但是个人理解编译器还会加入"段拷贝"程序(如果用B __main 的话),只是因为条件不满足而不执行而已;但是对含有启动程序来说,"执行地址与加载地址相同"就不容易了.因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM
发表于 2019-04-01
STM32 启动代码 __main 与用户主程序 main() 的区别

STM32 启动代码分析详解

__main就好了;c),虽然通过读标准的CMSIS汇编启动代码也可以知道堆栈是怎样初始化的。以LPC54608为例,早期的芯片会有不同的处理方式,比如大家都很熟悉的STM32F103系列,是需要启动代码与分散加载配合完成的。3.1、异常&中断向量表之前我们说这个可以用数组来实现,普通数组肯定不行,因为这些向量的本质是中断服务函数的入口,也就是“函数指针”所以这个数组必须得是函数指针数组:所以我们先声明一个函数指针类型:typedef void ( *__vector )( void );然后定义一个函数指针型数组取名为__vector_table:__vector __vector_table[] = {};   
发表于 2019-04-01
STM32 启动代码分析详解
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved