stm32 i2c dma.doc_第1頁
stm32 i2c dma.doc_第2頁
stm32 i2c dma.doc_第3頁
stm32 i2c dma.doc_第4頁
stm32 i2c dma.doc_第5頁
免費預覽已結束,剩余16頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

#ifndef _AT24C256_H#define _AT24C256_H/* Includes -*/#include stm32f10x.h#ifdef _cplusplus extern C #endif#define I2C_SPEED 300000#define I2C_SLAVE_ADDRESS7 0xA0 #define sEE_PAGESIZE 32/* Maximum number of trials for sEE_WaitEepromStandbyState() function */#define sEE_MAX_TRIALS_NUMBER 150 /* Defintions for the state of the DMA transfer */ #define sEE_STATE_READY 0#define sEE_STATE_BUSY 1#define sEE_STATE_ERROR 2 #define sEE_OK 0#define sEE_FAIL 1 #define sEE_FLAG_TIMEOUT (uint32_t)0x1000)#define sEE_LONG_TIMEOUT (uint32_t)(10 * sEE_FLAG_TIMEOUT)#define sEE_I2C I2C1#define sEE_I2C_CLK RCC_APB1Periph_I2C1#define sEE_I2C_SCL_PIN GPIO_Pin_6 #define sEE_I2C_SCL_GPIO_PORT GPIOB #define sEE_I2C_SCL_GPIO_CLK RCC_APB2Periph_GPIOB#define sEE_I2C_SDA_PIN GPIO_Pin_7 #define sEE_I2C_SDA_GPIO_PORT GPIOB #define sEE_I2C_SDA_GPIO_CLK RCC_APB2Periph_GPIOB#define sEE_M24C64_32#define sEE_I2C_DMA DMA1 #define sEE_I2C_DMA_CHANNEL_TX DMA1_Channel6#define sEE_I2C_DMA_CHANNEL_RX DMA1_Channel7 #define sEE_I2C_DMA_FLAG_TX_TC DMA1_IT_TC6 #define sEE_I2C_DMA_FLAG_TX_GL DMA1_IT_GL6 #define sEE_I2C_DMA_FLAG_RX_TC DMA1_IT_TC7 #define sEE_I2C_DMA_FLAG_RX_GL DMA1_IT_GL7 #define sEE_I2C_DMA_CLK RCC_AHBPeriph_DMA1#define sEE_I2C_DR_Address (uint32_t)0x40005410)#define sEE_USE_DMA #define sEE_I2C_DMA_TX_IRQn DMA1_Channel6_IRQn#define sEE_I2C_DMA_RX_IRQn DMA1_Channel7_IRQn#define sEE_I2C_DMA_TX_IRQHandler DMA1_Channel6_IRQHandler#define sEE_I2C_DMA_RX_IRQHandler DMA1_Channel7_IRQHandler #define sEE_I2C_DMA_PREPRIO 0#define sEE_I2C_DMA_SUBPRIO 0 #define sEE_DIRECTION_TX 0#define sEE_DIRECTION_RX 1 /* Time constant for the delay caclulation allowing to have a millisecond incrementing counter. This value should be equal to (System Clock / 1000). ie. if system clock = 24MHz then sEE_TIME_CONST should be 24. */#define sEE_TIME_CONST 48 void sEE_DeInit(void);void sEE_Init(void);uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite);void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);uint32_t sEE_WaitEepromStandbyState(void);/* USER Callbacks: These are functions for which prototypes only are declared in EEPROM driver and that should be implemented into user applicaiton. */ /* sEE_TIMEOUT_UserCallback() function is called whenever a timeout condition occure during communication (waiting on an event that doesnt occur, bus errors, busy devices .). You can use the default timeout callback implementation by uncommenting the define USE_DEFAULT_TIMEOUT_CALLBACK in stm32_evel_i2c_ee.h file. Typically the user implementation of this callback should reset I2C peripheral and re-initialize communication or in worst case reset all the application. */uint32_t sEE_TIMEOUT_UserCallback(void);/* Start and End of critical section: these callbacks should be typically used to disable interrupts when entering a critical section of I2C communication You may use default callbacks provided into this driver by uncommenting the define USE_DEFAULT_CRITICAL_CALLBACK in stm32_evel_i2c_ee.h file. Or you can comment that line and implement these callbacks into your application */void sEE_EnterCriticalSection_UserCallback(void);void sEE_ExitCriticalSection_UserCallback(void);#ifdef _cplusplus#endif#endif 以下是C文件#include at24c256.h_IO uint16_t sEEAddress = 0xa0; _IO uint32_t sEETimeout = sEE_LONG_TIMEOUT; _IO uint16_t* sEEDataReadPointer; _IO uint8_t* sEEDataWritePointer; _IO uint8_t sEEDataNum;DMA_InitTypeDef sEEDMA_InitStructure;void sEE_LowLevel_DeInit(void) GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* sEE_I2C Peripheral Disable */ I2C_Cmd(sEE_I2C, DISABLE); /* sEE_I2C DeInit */ I2C_DeInit(sEE_I2C); /*! sEE_I2C Periph clock disable */ RCC_APB1PeriphClockCmd(sEE_I2C_CLK, DISABLE); /*! GPIO configuration */ /*! Configure sEE_I2C pins: SCL */ GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); /*! Configure sEE_I2C pins: SDA */ GPIO_InitStructure.GPIO_Pin = sEE_I2C_SDA_PIN; GPIO_Init(sEE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); /* Configure and enable I2C DMA TX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = sEE_I2C_DMA_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = sEE_I2C_DMA_PREPRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = sEE_I2C_DMA_SUBPRIO; NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); /* Configure and enable I2C DMA RX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = sEE_I2C_DMA_RX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = sEE_I2C_DMA_PREPRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = sEE_I2C_DMA_SUBPRIO; NVIC_Init(&NVIC_InitStructure); /* Disable and Deinitialize the DMA channels */ DMA_Cmd(sEE_I2C_DMA_CHANNEL_TX, DISABLE); DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, DISABLE); DMA_DeInit(sEE_I2C_DMA_CHANNEL_TX); DMA_DeInit(sEE_I2C_DMA_CHANNEL_RX);/* * brief Initializes peripherals used by the I2C EEPROM driver. * param None * retval None */void sEE_LowLevel_Init(void) GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /*! sEE_I2C_SCL_GPIO_CLK and sEE_I2C_SDA_GPIO_CLK Periph clock enable */ RCC_APB2PeriphClockCmd(sEE_I2C_SCL_GPIO_CLK | sEE_I2C_SDA_GPIO_CLK, ENABLE); /*! sEE_I2C Periph clock enable */ RCC_APB1PeriphClockCmd(sEE_I2C_CLK, ENABLE); /*! GPIO configuration */ /*! Configure sEE_I2C pins: SCL */ GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); /*! Configure sEE_I2C pins: SDA */ GPIO_InitStructure.GPIO_Pin = sEE_I2C_SDA_PIN; GPIO_Init(sEE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); /* Configure and enable I2C DMA TX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = sEE_I2C_DMA_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = sEE_I2C_DMA_PREPRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = sEE_I2C_DMA_SUBPRIO; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure and enable I2C DMA RX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = sEE_I2C_DMA_RX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = sEE_I2C_DMA_PREPRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = sEE_I2C_DMA_SUBPRIO; NVIC_Init(&NVIC_InitStructure); /*! I2C DMA TX and RX channels configuration */ /* Enable the DMA clock */ RCC_AHBPeriphClockCmd(sEE_I2C_DMA_CLK, ENABLE); /* I2C TX DMA Channel configuration */ DMA_DeInit(sEE_I2C_DMA_CHANNEL_TX); sEEDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)sEE_I2C_DR_Address; sEEDMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)0; /* This parameter will be configured durig communication */ sEEDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; /* This parameter will be configured durig communication */ sEEDMA_InitStructure.DMA_BufferSize = 0xFFFF; /* This parameter will be configured durig communication */ sEEDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; sEEDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; sEEDMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; sEEDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; sEEDMA_InitStructure.DMA_Mode = DMA_Mode_Normal; sEEDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; sEEDMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(sEE_I2C_DMA_CHANNEL_TX, &sEEDMA_InitStructure); /* I2C RX DMA Channel configuration */ DMA_DeInit(sEE_I2C_DMA_CHANNEL_RX); DMA_Init(sEE_I2C_DMA_CHANNEL_RX, &sEEDMA_InitStructure); /* Enable the DMA Channels Interrupts */ DMA_ITConfig(sEE_I2C_DMA_CHANNEL_TX, DMA_IT_TC, ENABLE); DMA_ITConfig(sEE_I2C_DMA_CHANNEL_RX, DMA_IT_TC, ENABLE); /* * brief Initializes DMA channel used by the I2C EEPROM driver. * param None * retval None */void sEE_LowLevel_DMAConfig(uint32_t pBuffer, uint32_t BufferSize, uint32_t Direction) /* Initialize the DMA with the new parameters */ if (Direction = sEE_DIRECTION_TX) /* Configure the DMA Tx Channel with the buffer address and the buffer size */ sEEDMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer; sEEDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; sEEDMA_InitStructure.DMA_BufferSize = (uint32_t)BufferSize; DMA_Init(sEE_I2C_DMA_CHANNEL_TX, &sEEDMA_InitStructure); else /* Configure the DMA Rx Channel with the buffer address and the buffer size */ sEEDMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer; sEEDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; sEEDMA_InitStructure.DMA_BufferSize = (uint32_t)BufferSize; DMA_Init(sEE_I2C_DMA_CHANNEL_RX, &sEEDMA_InitStructure); void sEE_DeInit(void) sEE_LowLevel_DeInit(); /* * brief Initializes peripherals used by the I2C EEPROM driver. * param None * retval None */void sEE_Init(void) I2C_InitTypeDef I2C_InitStructure; sEE_LowLevel_Init(); /*! I2C configuration */ /* sEE_I2C configuration */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; /* sEE_I2C Peripheral Enable */ I2C_Cmd(sEE_I2C, ENABLE); /* Apply sEE_I2C configuration after enabling it */ I2C_Init(sEE_I2C, &I2C_InitStructure); /* Enable the sEE_I2C peripheral DMA requests */ I2C_DMACmd(sEE_I2C, ENABLE);/* * brief Reads a block of data from the EEPROM. * param pBuffer : pointer to the buffer that receives the data read from * the EEPROM. * param ReadAddr : EEPROMs internal address to start reading from. * param NumByteToRead : pointer to the variable holding number of bytes to * be read from the EEPROM. * * note The variable pointed by NumByteToRead is reset to 0 when all the * data are read from the EEPROM. Application should monitor this * variable in order know when the transfer is complete. * * note When number of data to be read is higher than 1, this function just * configures the communication and enable the DMA channel to transfer data. * Meanwhile, the user application may perform other tasks. * When number of data to be read is 1, then the DMA is not used. The byte * is read in polling mode. * * retval sEE_OK (0) if operation is correctly performed, else return value * different from sEE_OK (0) or the timeout user callback. */uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead) /* Set the pointer to the Number of data to be read. This pointer will be used by the DMA Transfer Completer interrupt Handler in order to reset the variable to 0. User should check on this variable in order to know if the DMA transfer has been complete or not. */ sEEDataReadPointer = NumByteToRead; /*! While the bus is busy */ sEETimeout = sEE_LONG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BUSY) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Send START condition */ I2C_GenerateSTART(sEE_I2C, ENABLE); /*! Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Send EEPROM address for write */ I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Transmitter); /*! Test on EV6 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); #ifdef sEE_M24C08 /*! Send the EEPROMs internal address to read from: Only one byte address */ I2C_SendData(sEE_I2C, ReadAddr); #elif defined (sEE_M24C64_32) /*! 8); /發(fā)送高位地址 /*! Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Send the EEPROMs internal address to read from: LSB of the address */ I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF); /發(fā)送低位地址 #endif /*! sEE_M24C08 */ /*! Test on EV8 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_BTF) = RESET) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Send STRAT condition a second time */ I2C_GenerateSTART(sEE_I2C, ENABLE); /*! Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_MODE_SELECT) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Send EEPROM address for read */ I2C_Send7bitAddress(sEE_I2C, sEEAddress, I2C_Direction_Receiver); /* If number of data to be read is 1, then DMA couldnt be used */ /* One Byte Master Reception procedure (POLLING) -*/ if (uint16_t)(*NumByteToRead) 2) /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_ADDR) = RESET) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*!SR2; /*! Send STOP Condition */ I2C_GenerateSTOP(sEE_I2C, ENABLE); /* Call User callback for critical section end (should typically re-enable interrupts) */ sEE_ExitCriticalSection_UserCallback(); /* Wait for the byte to be received */ sEETimeout = sEE_FLAG_TIMEOUT; while(I2C_GetFlagStatus(sEE_I2C, I2C_FLAG_RXNE) = RESET) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Read the byte received from the EEPROM */ *pBuffer = I2C_ReceiveData(sEE_I2C); /*!CR1 & I2C_CR1_STOP) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /*! Re-Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(sEE_I2C, ENABLE); else/* More than one Byte Master Reception procedure (DMA) -*/ /*! Test on EV6 and clear it */ sEETimeout = sEE_FLAG_TIMEOUT; while(!I2C_CheckEvent(sEE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) if(sEETimeout-) = 0) return sEE_TIMEOUT_UserCallback(); /* Configure the DMA Rx Channel with the buffer address and the buffer size */ sEE_LowLevel_DMAConfig(uint32_t)pBuffer, (uint16_t)(*NumByteToRead), sEE_DIRECTION_RX); /* Inform the DMA that the next End Of Transfer Signal will be the last one */ I2C_DMALastTransferCmd(sEE_I2C, ENABLE); /* Enable the DMA Rx Channel */ DMA_Cmd(sEE_I2C_DMA_CHANNEL_RX, ENABLE); /* If all operations OK, return sEE_OK (0) */ return sEE_OK;/* * brief Writes more than one byte to the EEPROM with a single WRITE cycle. * * note The number of bytes (combined to write start address) must not * cross the EEPROM page boundary. This function can only write into * the boundaries of an EEPROM page. * This function doesnt check on boundaries condition (in this driver * the function sEE_WriteBuffer() which calls sEE_WritePage() is * responsible

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論