arrgon | Bonjour,
Je dois réaliser un travail ou l'objectif est d'effectuer le comptage de place de parking, et dans ce module je dois implémenter un afficheur permettant d'afficher tel ou tel message.
Spécification :
Afficheur oled Alphanumérique :
Le module dispose d’un afficheur OLED alphanumérique jaune de quatre lignes de vingt caractères (NHD-0420CW-AY3 de Newhaven Display).
Cet afficheur est connecté sur le bus I²C du microcontrôleur (voir documentation pour le protocole de pilotage).
Je dois donc piloter cette afficheur en I²C, voici la doc :
https://www.newhavendisplay.com/spe [...] CW-AY3.pdf
Sur mon schéma de l'afficheur (on peut voir que toute les sorties qui ont besoin d'être à la masse pour un fonctionnement en I²C sont bien à la masse).
On peut également remarquer que BS0 BS1 et BS2 sont configuré de tel manière à ce quel'I²C soit activé :
J'ai récupérer le code de la doc et j'ai voulue l'implémenter.
Bien évidemment j'utilise des variables non reconnues etc.. J'ai donc demander à mon supérieur la possibilité de récuperer les biblothèques de l'afficheur afin d'appeler les fonctions directement et de m'en servir comme je l'entend, mais voilà il m'a répondu : "tu n'en a pas besoin tu le pilote en I²C", je ne comprend donc pas comment je peut faire pour gérer mon afficheur en I²C ?
Je gère l'I²C sur mon µC STM32F10x de cette manière :
Code :
- GPIO_InitTypeDef initStruct;
- GPIO_DeInit(GPIOA);
- GPIO_DeInit(GPIOB);
- ...
- // I2C SCL / SDA
- initStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
- initStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
...
Code :
- void gpio_i2cIoStopCondition(void)
- {
- // B6 -> SCL / B7 -> SDA
- // Stop condition is SDA rising edge while SCL = 1
- GPIO_WriteBit(GPIOB,GPIO_Pin_7, Bit_RESET);
- fnop();
- GPIO_WriteBit(GPIOB,GPIO_Pin_6, Bit_SET);
- fnop();
- GPIO_WriteBit(GPIOB,GPIO_Pin_7, Bit_SET);
- fnop();
- }
|
Pensez vous que je dois utiliser les fonctions des bibliothèques I²C ?
Je vous avoue être perdue quant à la façon d'aborder cette tâche !
Il y a également toute la partie I2C codé par mon collège :
Code :
- /**********************/
- /****** includes ******/
- /**********************/
- #include "i2cMaster.h"
- /*******************/
- /***** globals *****/
- /*******************/
- /** @brief Buffer used to store I2C frames */
- uint8_t i2cBuffer[I2CM_BUFFER_SIZE];
- /** @brief I2C error flag */
- uint8_t i2cIsError;
- /*********************************/
- /****** Function definition ******/
- /*********************************/
- /**
- * @brief Initialize the I2C master
- */
- void i2cmInit(void)
- {
- I2C_InitTypeDef initStruct;
- I2C_DeInit(I2CM_MODULE);
- I2C_StructInit(&initStruct);
- initStruct.I2C_ClockSpeed = 100000;
- I2C_Init(I2CM_MODULE,&initStruct);
- i2cIsError = FALSE;
- I2C_Cmd(I2CM_MODULE,ENABLE);
- }
- /**
- * @brief Write data on the I2C bus
- *
- * @param[in] address The slave address in the 7 least significants bits
- * @param[in] count The number of bytes to write
- * @param[in] bufI2C An byte array containing the data to send
- */
- uint8_t i2cmWrite(uint8_t address, uint16_t count, uint8_t * bufI2C)
- {
- uint32_t temp;
- uint32_t timeout;
- I2C_GenerateSTART(I2CM_MODULE, ENABLE); // Send START condition
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until SB flag is set: EV5
- while ((I2CM_MODULE->SR1&I2C_SR1_SB) != I2C_SR1_SB)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("W - Start timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- I2C_Send7bitAddress(I2CM_MODULE, address, I2C_Direction_Transmitter); // Send slave address
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until ADDR is set: EV6
- while ((I2CM_MODULE->SR1&I2C_SR1_ADDR) != I2C_SR1_ADDR)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("W - ADDR timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- temp = I2CM_MODULE->SR2; // Clear ADDR flag by reading SR2 register
- I2C_SendData(I2CM_MODULE, *bufI2C); // Write the first data in DR register (EV8_1)
- bufI2C++; // Increment the data
- count--; // Decrement the number of bytes to be written
- while (count--) // While there is data to be written
- {
- /*
- * Poll on BTF to receive data because in polling mode we can not guarantee the
- * EV8 software sequence is managed before the current byte transfer completes
- */
- i2cm_waitBtfSet();
- I2C_SendData(I2CM_MODULE, *bufI2C); // Send the current byte
- bufI2C++; // Point to the next byte to be written
- }
- i2cm_waitBtfSet();// EV8_2: Wait until BTF is set before programming the STOP
- I2C_GenerateSTOP(I2CM_MODULE, ENABLE); // Send STOP condition
- // Make sure that the STOP bit is cleared by Hardware
- while ((I2CM_MODULE->CR1&I2C_CR1_STOP) == I2C_CR1_STOP)
- ;
- temp++; // For avoid compiler warning
- return TRUE;
- }
- /**
- * @brief Read data on the I2C bus
- *
- * @param[in] address The slave address in the 7 least significants bits
- * @param[in] count The number of bytes to read
- * @param[out] bufI2C An byte array in which store read data
- */
- uint8_t i2cmRead(uint8_t address, uint16_t count, uint8_t *bufI2C)
- {
- uint32_t temp = 0;
- uint32_t timeout = 0;
- // Enable I2C errors interrupts (used in all modes: Polling, DMA and Interrupts
- I2C_ITConfig(I2CM_MODULE, I2C_IT_ERR,ENABLE);
- if (count == 1)
- {
- I2C_GenerateSTART(I2CM_MODULE, ENABLE); // Send START condition
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until SB flag is set: EV5
- while ((I2CM_MODULE->SR1&0x0001) != 0x0001)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("R-1 - Start timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- // Send slave address
- I2C_Send7bitAddress(I2CM_MODULE, address, I2C_Direction_Receiver);
- /*
- * Wait until ADDR is set: EV6_3, then program ACK = 0, clear ADDR
- * and program the STOP just after ADDR is cleared. The EV6_3
- * software sequence must complete before the current byte end of transfer.
- */
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until ADDR is set
- while ((I2CM_MODULE->SR1&0x0002) != 0x0002)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("R-1 - ADDR timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- I2C_AcknowledgeConfig(I2CM_MODULE, DISABLE); // Clear ACK bit
- /*
- * Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
- * software sequence must complete before the current byte end of transfer
- */
- __disable_irq();
- temp = I2CM_MODULE->SR2; // Clear ADDR flag by reading SR2 register
- I2C_GenerateSTOP(I2CM_MODULE, ENABLE); // Program the STOP
- __enable_irq(); // Re-enable IRQs
- i2cm_waitRxneSet(); // Wait until a data is received in DR register (RXNE = 1) EV7
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read the data
- // Make sure that the STOP bit is cleared by Hardware before CR1 write access
- while ((I2CM_MODULE->CR1&0x200) == 0x200)
- ;
- }
- // ------ For send two bytes
- else if (count == 2)
- {
- I2CM_MODULE->CR1 |= CR1_POS_Set; // Set POS bit
- I2C_GenerateSTART(I2CM_MODULE, ENABLE); // Send START condition
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until SB flag is set: EV5
- while ((I2CM_MODULE->SR1&0x0001) != 0x0001)
- {
- if( timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("R-2 - Start timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- // Send slave address
- I2C_Send7bitAddress(I2CM_MODULE, address, I2C_Direction_Receiver);
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until ADDR is set: EV6
- while ((I2CM_MODULE->SR1&0x0002) != 0x0002)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("R-2 - ADDR timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- /*
- * EV6_1: The acknowledge disable should be done just after EV6,
- * that is after ADDR is cleared, so disable all active IRQs around ADDR clearing and
- * ACK clearing
- */
- __disable_irq();
- temp = I2CM_MODULE->SR2; // Clear ADDR by reading SR2 register
- I2C_AcknowledgeConfig(I2CM_MODULE,DISABLE); // Clear ACK bit
- __enable_irq(); //Re-enable IRQs
- i2cm_waitBtfSet(); // Wait until BTF is set
- // Disable IRQs around STOP programming and data reading because of the limitation ?
- __disable_irq();
- I2C_GenerateSTOP(I2CM_MODULE,ENABLE); // Program the STOP
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read first data
- __enable_irq(); // Re-enable IRQs
- bufI2C++;
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read second data
- /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
- while ((I2CM_MODULE->CR1&0x200) == 0x200)
- ;
- I2CM_MODULE->CR1 &= CR1_POS_Reset; // Clear POS bit
- }
- // ------ For send more than two bytes
- else
- {
- I2C_GenerateSTART(I2CM_MODULE, ENABLE); // Send START condition
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until SB flag is set: EV5
- while ((I2CM_MODULE->SR1&0x0001) != 0x0001)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("R>2 - Start timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- // Send slave address
- I2C_Send7bitAddress(I2CM_MODULE,address,I2C_Direction_Receiver);
- timeout = I2CM_EVENT_TIMEOUT; // Reset timeout
- // Wait until ADDR is set: EV6
- while ((I2CM_MODULE->SR1&0x0002) != 0x0002)
- {
- if (timeout-- == 0)
- {
- #ifdef I2C_DEBUG
- debugSendLine("R>2 - ADDR timeout" );
- #endif
- i2cm_fixFailure();
- return FALSE;
- }
- }
- temp = I2CM_MODULE->SR2; // Clear ADDR by reading SR2 status register
- while (count) // While there is data to be read
- {
- if (count != 3) // Receive bytes from first byte until byte N-3
- {
- /*
- * Poll on BTF to receive data because in polling mode we can not guarantee the
- * EV7 software sequence is managed before the current byte transfer completes
- */
- i2cm_waitBtfSet();
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read data
- bufI2C++;
- count--; // Decrement the read bytes counter
- }
- /* it remains to read three data: data N-2, data N-1, Data N */
- if (count == 3)
- {
- // Wait until BTF is set: Data N-2 in DR and data N -1 in shift register
- i2cm_waitBtfSet();
- I2C_AcknowledgeConfig(I2CM_MODULE,DISABLE); // Clear ACK bit
- /*
- * Disable IRQs around data reading and STOP programming because of the
- * limitation ?
- */
- __disable_irq();
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read Data N-2
- bufI2C++; // Increment
- I2C_GenerateSTOP(I2CM_MODULE,ENABLE); // Program the STOP
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read Data N-1
- __enable_irq(); // Re-enable IRQs
- bufI2C++; // Increment
- i2cm_waitRxneSet(); // Wait until RXNE is set (DR contains the last data)
- *bufI2C = I2C_ReceiveData(I2CM_MODULE); // Read DataN
- count = 0; // Reset the number of bytes to be read by master
- }
- }
- /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
- while((I2CM_MODULE->CR1&0x200) == 0x200)
- ;
- }
- I2C_AcknowledgeConfig(I2CM_MODULE, ENABLE); // Enable Acknowledgment to be ready for another reception
- temp++; // For avoid compiler warning
- return TRUE;
- }
- /**
- * @brief Write and read data on the I2C bus
- *
- * @param[in] address The slave address in the 7 least significants bits
- * @param[in] countWrite The number of bytes to write
- * @param[in] countRead The number of bytes to read
- * @param[in, out] bufI2C An byte array in which store read data
- *
- * @return 1 if there is a problem during write operation, 0 otherwise
- *
- * In a first time, this function write the <tt>writeCount</tt> first bytes of bufI2C array.<br>
- * Then, in a second time, this function read <tt>readCount</tt> bytes on I2C and store them in bufI2C.
- */
- uint8_t i2cmWriteAndRead(uint8_t address, uint16_t countWrite, uint16_t countRead, uint8_t *bufI2C)
- {
- if (i2cmWrite(address, countWrite, bufI2C))
- {
- if (i2cmRead(address, countRead, bufI2C))
- return TRUE;
- }
- return FALSE;
- }
- /**
- * @brief This function handles I2C1 Error interrupt request.
- */
- void I2C1_ER_IRQHandler(void)
- {
- __IO uint32_t SR1Register = 0;
- // Read the I2C1 status register
- SR1Register = I2C1->SR1;
- // If AF = 1
- if ((SR1Register & 0x0400) == 0x0400)
- {
- I2C1->SR1 &= 0xFBFF;
- SR1Register = 0;
- }
- // If ARLO = 1
- if((SR1Register & 0x0200) == 0x0200)
- {
- I2C1->SR1 &= 0xFBFF;
- SR1Register = 0;
- }
- // If BERR = 1
- if((SR1Register & 0x0100) == 0x0100)
- {
- I2C1->SR1 &= 0xFEFF;
- SR1Register = 0;
- }
- // If OVR = 1
- if((SR1Register & 0x0800) == 0x0800)
- {
- I2C1->SR1 &= 0xF7FF;
- SR1Register = 0;
- }
- i2cIsError = TRUE;
- }
- /**
- * @brief Wait for the end of the byte transfer (bit BTF of register SR1)
- */
- void i2cm_waitBtfSet(void)
- {
- i2cm_waitSr1BitSet(I2C_SR1_BTF); // Wait until BTF is set
- }
- /**
- * @brief Wait for the reception of a byte (bit RxNE of register SR1)
- */
- void i2cm_waitRxneSet(void)
- {
- i2cm_waitSr1BitSet(I2C_SR1_RXNE); // Wait until RXNE is set
- }
- /**
- * @brief Wait until the bit <tt>bitToWait</tt> is set in register SR1
- *
- * @param[in] bitToWait The bit to wait
- */
- void i2cm_waitSr1BitSet(uint8_t bitToWait)
- {
- while ((I2C_ReadRegister(I2CM_MODULE,I2C_Register_SR1)&bitToWait) != bitToWait)
- ;
- //softDelay(1);
- }
- /**
- * @brief Fix an I2C failure
- */
- void i2cm_fixFailure(void)
- {
- GPIO_InitTypeDef initStruct;
- I2C_SoftwareResetCmd(I2CM_MODULE, ENABLE);
- initStruct.GPIO_Speed = GPIO_Speed_50MHz;
- initStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
- initStruct.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB, &initStruct);
- GPIO_WriteBit(GPIOB, initStruct.GPIO_Pin, Bit_RESET);
- softDelay(20);
- I2C_SoftwareResetCmd(I2CM_MODULE, DISABLE);
- //initStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
- initStruct.GPIO_Mode = GPIO_Mode_AF_OD;
- GPIO_Init(GPIOB, &initStruct);
- softDelay(20);
- i2cmInit();
- }
|
Merci à vous d'avoir pris le temps, je vous souhaite une excellente journée ! Merci ! |