31 | I2C1 -> OAR1 |= 0<<15; //寻址模式 1 响应10位地址 0 响应7位地址 |
33 | I2C1 -> OAR1 |= 1<<14; //必须始终由软件保持为 1 |
35 | I2C1 -> OAR1 |= Addr <<1 ; //设置接口地址的 7~1位 |
37 | //I2C1 -> OAR1 |= 0 ; //设置10位地址模式时地址第0位 |
38 | //I2C1 -> OAR1 |= 0<<8; //设置10位地址模式时地址第9~8位 |
40 | //I2C1 -> CR2 |= 1<<10; //缓冲器中断使能 |
41 | I2C1 -> CR2 |= 1<<9; //事件中断使能 |
42 | I2C1 -> CR2 |= 1<<8; //出错中断使能 |
44 | I2C1 -> CR1 |= 1<<0; //开启I2C1 |
51 | I2C1 -> CR1 |= 1<<8; //I2C1产生起始条件 |
56 | I2C1 -> CR1 |= 1<<9; //I2C1产生停止条件 |
60 | void I2c_Write(u8 data) |
67 | while(!(I2C1 -> SR1 & 1<<6)); //接收到数据标志位 |
74 | I2C1 -> CR1 &= ~(1<<0); |
Library/inc/i2c.h
3 | void I2c_Init(u16 Addr ); |
7 | void I2c_Write(u8 data); |
串口接收数据如下:
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" |
006 | void RCC_Configuration(void); |
007 | void GPIO_Configuration(void); |
008 | void USART_Configuration(void); |
009 | void I2C_Configuration(void); |
010 | void NVIC_Configuration(void); |
013 | u8 I2C1_ADDRESS = 0x30; //7位 I2C 地址 |
014 | u8 I2C2_ADDRESS = 0x31; |
018 | vu8 I2C1_Buffer_Tx[Size] = {1,2,3,4}; |
019 | vu8 I2C2_Buffer_Rx[Size] = {0}; |
021 | u32 BufferSize = Size ; |
026 | GPIO_Configuration(); |
027 | USART_Configuration(); |
029 | NVIC_Configuration(); |
031 | I2C_GenerateSTART(I2C1,ENABLE); |
036 | void I2C_Configuration(void) |
038 | I2C_InitTypeDef I2C_InitStructure; |
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); |
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); |
057 | I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,ENABLE); |
058 | I2C_ITConfig(I2C2,I2C_IT_EVT|I2C_IT_BUF,ENABLE); |
060 | I2C_Cmd(I2C1,ENABLE); |
061 | I2C_Cmd(I2C2,ENABLE); |
064 | void NVIC_Configuration(void) |
066 | NVIC_InitTypeDef NVIC_InitStructure; |
068 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); |
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); |
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); |
083 | void GPIO_Configuration(void) |
085 | GPIO_InitTypeDef GPIO_InitStructure; |
087 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
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); |
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); |
099 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; |
100 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
101 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
103 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; |
104 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
105 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
108 | void RCC_Configuration(void) |
110 | /* 定义枚举类型变量 HSEStartUpStatus */ |
111 | ErrorStatus HSEStartUpStatus; |
116 | RCC_HSEConfig(RCC_HSE_ON); |
118 | HSEStartUpStatus = RCC_WaitForHSEStartUp(); |
119 | /* 判断HSE起是否振成功,是则进入if()内部 */ |
120 | if(HSEStartUpStatus == SUCCESS) |
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); |
129 | FLASH_SetLatency(FLASH_Latency_2); |
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); |

[
1] [
2] [
3] [
4]

本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
推荐阅读
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
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
本身的长度,比如int类型就能超过32位二进位。3)位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如: struct k { int a:1 int :2 /*该2位不能使用*/ int b:3 int c:2 }; 从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的。  
发表于 2019-04-01
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
了。startup.s 这个文件并没有所谓的"段拷贝"功能。对含有启动程序来说,"执行地址与加载地址相同"不容易实现:如果执行地址与加载地址相同哪当然不需要做"段拷贝",但是个人理解编译器还会加入"段拷贝"程序(如果用B __main 的话),只是因为条件不满足而不执行而已;但是对含有启动程序来说,"执行地址与加载地址相同"就不容易了.因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM
发表于 2019-04-01
__main就好了;c),虽然通过读标准的CMSIS汇编启动代码也可以知道堆栈是怎样初始化的。以LPC54608为例,早期的芯片会有不同的处理方式,比如大家都很熟悉的STM32F103系列,是需要启动代码与分散加载配合完成的。3.1、异常&中断向量表之前我们说这个可以用数组来实现,普通数组肯定不行,因为这些向量的本质是中断服务函数的入口,也就是“函数指针”所以这个数组必须得是函数指针数组:所以我们先声明一个函数指针类型:typedef void ( *__vector )( void );然后定义一个函数指针型数组取名为__vector_table:__vector __vector_table[] = {};  
发表于 2019-04-01