/** * @brief Enables or disables the specified DMAy Channelx interrupts. * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel. * @param DMA_IT: specifies the DMA interrupts sources to be enabled * or disabled. * This parameter can be any combination of the following values: * @arg DMA_IT_TC: Transfer complete interrupt mask * @arg DMA_IT_HT: Half transfer interrupt mask * @arg DMA_IT_TE: Transfer error interrupt mask * @param NewState: new state of the specified DMA interrupts. * This parameter can be: ENABLE or DISABLE. * @retval None */ voidDMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState) { /* Check the parameters */ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx)); assert_param(IS_DMA_CONFIG_IT(DMA_IT)); assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE) { /* Enable the selected DMA interrupts */ DMAy_Channelx->CCR |= DMA_IT; } else { /* Disable the selected DMA interrupts */ DMAy_Channelx->CCR &= ~DMA_IT; } }
typedefstruct { uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */
uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */
uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. This parameter can be a value of @ref DMA_data_transfer_direction */
uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. The data unit is equal to the configuration set in DMA_PeripheralDataSize or DMA_MemoryDataSize members depending in the transfer direction. */
uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. This parameter can be a value of @ref DMA_peripheral_incremented_mode */
uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. This parameter can be a value of @ref DMA_memory_incremented_mode */
uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. This parameter can be a value of @ref DMA_peripheral_data_size */
uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. This parameter can be a value of @ref DMA_memory_data_size */
uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. This parameter can be a value of @ref DMA_circular_normal_mode. @note: The circular buffer mode cannot be used if the memory-to-memory data transfer is configured on the selected Channel */
uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. This parameter can be a value of @ref DMA_priority_level */
uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. This parameter can be a value of @ref DMA_memory_to_memory */ }DMA_InitTypeDef;
;******************** (C) COPYRIGHT 2011 STMicroelectronics ******************** ;* File Name : startup_stm32f10x_hd.s ;* Author : MCD Application Team ;* Version : V3.5.0 ;* Date : 11-March-2011 ;* Description : STM32F10x High Density Devices vector table for MDK-ARM ;* toolchain. ;* This module performs: ;* - Set the initial SP ; 初始化堆栈指针 ;* - Set the initial PC == Reset_Handler ; 初始化PC指针 == Reset_Handler程序 ;* - Set the vector table entries with the exceptions ISR address ; 初始化中断向量表 ;* - Configure the clock system and also configure the external ;* SRAM mounted on STM3210E-EVAL board to be used as data ;* memory (optional, to be enabled by user) ; 配置系统时钟 ;* - Branches to __main in the C library (which eventually ;* calls main()). ; 调用C库函数, 最终去到C的世界 ;* After Reset the CortexM3 processor is in Thread mode, ;* priority is Privileged, and the Stack is set to Main. ;* <<< Use Configuration Wizard in Context Menu >>> ;******************************************************************************* ; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS ; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. ; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, ; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE ; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING ; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. ;*******************************************************************************
; Amount of memory (in bytes) allocated for Stack ; Tailor this value to your application needs ; <h> Stack Configuration ; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ; </h> ; 配置栈: 用于变量存储(局部/全局), 函数调用
;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****
EQU指令
作用: The EQU directive is a register-relative address, a PC-relative address, an absolute address, or a 32-bit integer constant. // 为数值常量、寄存器相对值或 PC 相对值提供符号名称。(可以理解为重命名)
voidSystemInit(void) { /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001;
/** * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. * @param None * @retval None */ staticvoidSetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz SetSysClockTo36(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz SetSysClockTo72(); #endif /* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */ }
#elif defined SYSCLK_FREQ_72MHz /** * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 * and PCLK1 prescalers. * @note This function should be used only after reset. * @param None * @retval None */ staticvoidSetSysClockTo72(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ // 使能HSE RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ // 等待 HSE 就绪并作超时处理 do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
/* Wait till PLL is ready */ // 等待 PLL 稳定 while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Select PLL as system clock source */ // 选择 PLLCLK 作为系统时钟 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Wait till PLL is used as system clock source */ // 等待 PLLCLK 切换为系统时钟 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ // 如果 HSE 启动失败,用户可以在这里添加处理错误的代码 } } #endif
/** * @brief Configures the GPIO for MCO (Microcontroller Clock Output). * * This function initializes the GPIO pin for MCO and configures it as an alternate function push-pull output. * The GPIO pin used for MCO is GPIOA Pin 8. * * @param None * @return None */ voidMCO_GPIO_Config() { // MCO的GPIO初始化 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); }
typedefstruct { uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. This parameter can be any combination of @ref EXTI_Lines */ EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. This parameter can be a value of @ref EXTIMode_TypeDef */
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. This parameter can be a value of @ref EXTIMode_TypeDef */
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. This parameter can be set either to ENABLE or DISABLE */ }EXTI_InitTypeDef;
/** * @brief Selects the GPIO pin used as EXTI Line. * @param GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines. * This parameter can be GPIO_PortSourceGPIOx where x can be (A..G). * @param GPIO_PinSource: specifies the EXTI line to be configured. * This parameter can be GPIO_PinSourcex where x can be (0..15). * @retval None */ voidGPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) { uint32_t tmp = 0x00; /* Check the parameters */ assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource)); assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)); AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp; AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03))); }
/** * @brief EXTI0_IRQHandler: Interrupt handler for EXTI Line 0 * * This function is the interrupt handler for EXTI Line 0. It toggles the state of the blue LED. * It checks the interrupt status of EXTI Line 0 and clears the interrupt pending bit. */ voidEXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) // 判断中断位 { LED_B_TOGGLE; } EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位 }
/** * @brief Initialize and start the SysTick counter and its interrupt. * * @param ticks number of ticks between two interrupts * @return 1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate * periodical interrupts. */ static __INLINE uint32_tSysTick_Config(uint32_t ticks) { // 判断ticks的值是否大于2^24, 若大于则违法 if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ // 初始化reaload寄存器的值 SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
/** * @brief Main function of the program. * * This function initializes the LED GPIO and enters an infinite loop. * In each iteration of the loop, it turns off the blue LED, delays for 0.5 seconds, * turns on the blue LED, and delays for 0.5 seconds again. * * @return int The exit status of the program. */ intmain(void) { LED_GPIO_Config(); // Initialize the LED GPIO
while(1) { LED_B(OFF); // Turn off the blue LED SysTick_Delay_ms(500); // Delay for 0.5 seconds LED_B(ON); // Turn on the blue LED SysTick_Delay_us(500000); // Delay for 0.5 seconds } }
/** * @brief USART Init Structure definition */ typedefstruct { // 设置波特率 uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. The baud rate is computed using the following formula: - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */
// 设置字长 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_WordLength_8b ((uint16_t)0x0000) * #define USART_WordLength_9b ((uint16_t)0x1000) * ---------------------------------------------------------------------------*/ uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. This parameter can be a value of @ref USART_Word_Length */
// 设置停止位 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_StopBits_1 ((uint16_t)0x0000) * #define USART_StopBits_0_5 ((uint16_t)0x1000) * #define USART_StopBits_2 ((uint16_t)0x2000) * #define USART_StopBits_1_5 ((uint16_t)0x3000) * ---------------------------------------------------------------------------*/ uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted. This parameter can be a value of @ref USART_Stop_Bits */
// 设置校验 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_Parity_No ((uint16_t)0x0000) * #define USART_Parity_Even ((uint16_t)0x0400) * #define USART_Parity_Odd ((uint16_t)0x0600) * ---------------------------------------------------------------------------*/ uint16_t USART_Parity; /*!< Specifies the parity mode. This parameter can be a value of @ref USART_Parity @note When parity is enabled, the computed parity is inserted at the MSB position of the transmitted data (9th bit when the word length is set to 9 data bits; 8th bit when the word length is set to 8 data bits). */ // 设置模式 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_Mode_Rx ((uint16_t)0x0004) * #define USART_Mode_Tx ((uint16_t)0x0008) * ---------------------------------------------------------------------------*/ uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. This parameter can be a value of @ref USART_Mode */
// 设置硬件控制流 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_HardwareFlowControl_None ((uint16_t)0x0000) * #define USART_HardwareFlowControl_RTS ((uint16_t)0x0100) * #define USART_HardwareFlowControl_CTS ((uint16_t)0x0200) * #define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300) * ---------------------------------------------------------------------------*/ uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled or disabled. This parameter can be a value of @ref USART_Hardware_Flow_Control */ } USART_InitTypeDef;
// 设置使能时钟 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_Clock_Disable ((uint16_t)0x0000) * #define USART_Clock_Enable ((uint16_t)0x0800) * ---------------------------------------------------------------------------*/ uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled. This parameter can be a value of @ref USART_Clock */
// 设置时钟的极性, 即总线空闲时CK引脚保持低电平还是高电平 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_CPOL_Low ((uint16_t)0x0000) * #define USART_CPOL_High ((uint16_t)0x0400) * ---------------------------------------------------------------------------*/ uint16_t USART_CPOL; /*!< Specifies the steady state value of the serial clock. This parameter can be a value of @ref USART_Clock_Polarity */
// 设置时钟的相位, 即数据采样的时机为第一个边沿还是第二个边沿 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_CPHA_1Edge ((uint16_t)0x0000) * #define USART_CPHA_2Edge ((uint16_t)0x0200) * ---------------------------------------------------------------------------*/ uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made. This parameter can be a value of @ref USART_Clock_Phase */
// 设置时钟的最后一个数据位的时钟脉冲是否输出到SCLK引脚 /*----------------------------------------------------------------------------- * 参数如下: * #define USART_LastBit_Disable ((uint16_t)0x0000) * #define USART_LastBit_Enable ((uint16_t)0x0100) * ---------------------------------------------------------------------------*/ uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted data bit (MSB) has to be output on the SCLK pin in synchronous mode. This parameter can be a value of @ref USART_Last_Bit */ } USART_ClockInitTypeDef;
/** * @brief Sends an array of bytes over USART. * * This function sends an array of bytes over the specified USART peripheral. * * @param pUSARTx The USART peripheral to use. * @param array Pointer to the array of bytes to send. * @param num The number of bytes to send. */ voidUsart_SendArray(USART_TypeDef* pUSARTx, uint8_t* array, uint16_t num) { for(uint16_t i = 0; i < num; i++) { Usart_SendByte(pUSARTx, array[i]); } while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET) { ; } }
/** * @brief Interrupt handler for the DEBUG_USART. * * This function is called when there is a receive interrupt from the DEBUG_USART. * It receives data from the DEBUG_USART and sends it back. */ voidDEBUG_USART_IRQHandler(void) { uint8_t ucTemp;
if(USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET) { ucTemp = USART_ReceiveData(DEBUG_USARTx); // Receive data into ucTemp USART_SendData(DEBUG_USARTx, ucTemp); // Send data } }
typedefstruct { /*-------------------------------------------------------------------------------- * 外设地址 * 由寄存器 DMA_CPARx 进行配置 *---------------------------------------------------------------------------- */ uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */
/*-------------------------------------------------------------------------------- * 存储器地址 * 由寄存器 DMA_CMARx 进行配置 *---------------------------------------------------------------------------- */ uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */
/*-------------------------------------------------------------------------------- * 传输方向 * P->M 和 M->P 由寄存器 DMA_CCRx:DIR[4] 进行配置 * M->M 由寄存器 DMA_CCRx:MEM2MEM[14] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. This parameter can be a value of @ref DMA_data_transfer_direction */
/*-------------------------------------------------------------------------------- * 缓冲区大小, 传输数目 * 由寄存器 DMA_CNDTRx 进行配置 *-------------------------------------------------------------------------------*/ uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. The data unit is equal to the configuration set in DMA_PeripheralDataSize or DMA_MemoryDataSize members depending in the transfer direction. */
/*-------------------------------------------------------------------------------- * 外设增量模式 * 由寄存器 DMA_CCRx:PINC[6] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. This parameter can be a value of @ref DMA_peripheral_incremented_mode */
/*-------------------------------------------------------------------------------- * 存储器增量模式 * 由寄存器 DMA_CCRx:MINC[7] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. This parameter can be a value of @ref DMA_memory_incremented_mode */
/*-------------------------------------------------------------------------------- * 外设数据宽度 * 由寄存器 DMA_CCRx:PSIZE[9:8] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. This parameter can be a value of @ref DMA_peripheral_data_size */
/*-------------------------------------------------------------------------------- * 存储器数据宽度 * 由寄存器 DMA_CCRx:MSIZE[11:10] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. This parameter can be a value of @ref DMA_memory_data_size */
/*-------------------------------------------------------------------------------- * 传输模式 * 由寄存器 DMA_CCRx:CIRC[5] 进行配置 * 通过 DMA_ISR 判断传输状态来判断传输完成, 传输一半, 传输错误 *--------------------------------------------------------------------------------*/ uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. This parameter can be a value of @ref DMA_circular_normal_mode. @note: The circular buffer mode cannot be used if the memory-to-memory data transfer is configured on the selected Channel */
/*-------------------------------------------------------------------------------- * 优先级 * 由寄存器 DMA_CCRx:PL[1:0] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. This parameter can be a value of @ref DMA_priority_level */
/*-------------------------------------------------------------------------------- * 存储器到存储器模式 * 由寄存器 DMA_CCRx:MEM2MEM[14] 进行配置 *--------------------------------------------------------------------------------*/ uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. This parameter can be a value of @ref DMA_memory_to_memory */ }DMA_InitTypeDef;
/** * @brief Delays the execution for a specified number of milliseconds.(Not Sure) * @param ms The number of milliseconds to delay. * @return None. */ voidDelay_ms(uint32_t ms) { uint32_t i = 0; for(i = 0; i < ms; i++) { uint16_t j = 0; for(j = 0; j < 1000; j++) { ; } } }
typedefstruct { /*--------------------------------------------------------------------------------- * 设置时钟频率 * 设置I2C的传输速率, 函数根据该值经过运算后写入I2C_CCR寄存器 * 不得高于400kHz, 即400 000 * 由于I2C_CCR寄存器不能写入浮点数, 可能会导致实际速率小于设定的传输速率参数 * 使得通讯稍慢, 但是并不会对I2C的通讯造成其他影响 *-------------------------------------------------------------------------------*/ uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. This parameter must be set to a value lower than 400kHz */
/*--------------------------------------------------------------------------------- * 设置I2C的模式 * I2C_Mode_I2C: 标准I2C模式 * I2C_Mode_SMBusDevice: SMBus设备模式 * I2C_Mode_SMBusHost: SMBus主机模式 *-------------------------------------------------------------------------------*/ uint16_t I2C_Mode; /*!< Specifies the I2C mode. This parameter can be a value of @ref I2C_mode */
/*--------------------------------------------------------------------------------- * 设置I2C的SCL时钟的占空比 * I2C_DutyCycle_16_9: Tlow/Thigh = 16:9 * I2C_DutyCycle_2: Tlow/Thigh = 2:1 * 这两个选项差别不大, 开发中一般不会进行严格区分 *-------------------------------------------------------------------------------*/ uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle. This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
/*--------------------------------------------------------------------------------- * 配置STM32的I2C设备自己的地址 * 此参数可以是 7 位或 10 位地址 * 第二个地址可以通过函数I2C_OwnAddress2Config进行配置, 只能是7位地址 *-------------------------------------------------------------------------------*/ uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address. This parameter can be a 7-bit or 10-bit address. */
/*--------------------------------------------------------------------------------- * 配置I2C应答是否使能 * I2C_Ack_Enable: 允许应答使能 * I2C_Ack_Disable: 禁止应答使能 * 一般配置为允许应答使能, 改为禁止应答使能往往会导致通讯错误 *-------------------------------------------------------------------------------*/ uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement. This parameter can be a value of @ref I2C_acknowledgement */
/*--------------------------------------------------------------------------------- * 配置I2C的寻址长度 * I2C_AcknowledgedAddress_7bit: 7位地址 * I2C_AcknowledgedAddress_10bit: 10位地址 * 需要根据连接到I2C总线上的设备进行选择, 确保地址长度一致, 才能进行通信 * 只有I2C_OwnAddress1才能配置10位地址, I2C_OwnAddress2只支持7位地址 *-------------------------------------------------------------------------------*/ uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged. This parameter can be a value of @ref I2C_acknowledged_address */ }I2C_InitTypeDef;
I2C库函数
I2C_GenerateSTART函数, 用于产生起始条件
I2C_GetFlagStatus函数, 用于获取状态位
I2C_FLAG参数列表对应I2C_SRx状态寄存器的各个位, 可通过查询手册查看其含义
返回值说明
1
typedefenum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4); } /* Send START condition */ I2C_GenerateSTART(EEPROM_I2Cx, ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV5 and clear it */ while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5); } /* Send EEPROM address for write */ I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV6 and clear it */ while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6); } /* Send the EEPROM's internal address to write to */ I2C_SendData(EEPROM_I2Cx, WriteAddr);
I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV8 and clear it */ while(! I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(7); }
/* While there is data to be written */ while(NumByteToWrite--) { /* Send the current byte */ I2C_SendData(EEPROM_I2Cx, *pBuffer);
/* Point to the next byte to be written */ pBuffer++; I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */ while (!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8); } }
I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV6 and clear it */ while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(11); } /* Clear EV6 by setting again the PE bit */ I2C_Cmd(EEPROM_I2Cx, ENABLE);
/* Send the EEPROM's internal address to write to */ I2C_SendData(EEPROM_I2Cx, ReadAddr);
I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV8 and clear it */ while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(12); } /* Send START condition a second time */ I2C_GenerateSTART(EEPROM_I2Cx, ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV5 and clear it */ while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(13); } /* Send EEPROM address for read */ I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Receiver); I2CTimeout = I2CT_FLAG_TIMEOUT; /* Test on EV6 and clear it */ while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(14); } /* While there is data to be read */ while(NumByteToRead) { if(NumByteToRead == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(EEPROM_I2Cx, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE); }
/* Test on EV7 and clear it */ I2CTimeout = I2CT_LONG_TIMEOUT; while(I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0) { if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3); } { /* Read a byte from the EEPROM */ *pBuffer = I2C_ReceiveData(EEPROM_I2Cx);
/* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } }
/* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(EEPROM_I2Cx, ENABLE); return1; }