cancel
Showing results for 
Search instead for 
Did you mean: 

what is the reason I2C peripheral does not work in master transmit mode in this program ?

AZaki
Associate

i did not use standard peripheral library or cubemx to write this program . and i did it programming registers.

as you know when data in TXDR register is sent the TXE flag in ISR register become one .

i have checked ISR while no data is writen in TXDR and TXE=1 ( i have done this by debugger ).

after that i write data in TXDR , TXE becomes '0' but never becomes '1' , means that data will not send.

i have used counter. the code is inserted below .

i do not know if this helps you answering me but one of the reserved bits of the register ISR becomes '1' by hardware after i write data into TXDR , i don't know if this shows an error .

I hope you can help me .

#include "stm32f0xx.h"
 
uint8_t acc[7],data[2],contr1;
uint16_t acc_x,acc_y,acc_z;
uint32_t status,cr2;
void i2c1_conf (void);
void i2c_write( uint8_t nby , uint8_t *data ,uint8_t addr);
void i2c_read( uint8_t nby , uint8_t *data, uint8_t addr);
void delay_ms(uint16_t delay_m);                        
//void I2C1_IRQHandler (void);;
 
int main()
{
  i2c1_conf();
  data[0]=0;
  i2c_write( 1 , data,0x6c);
  //I2C1->CR2 |= I2C_CR2_START;
  //status=I2C1->ISR;
  while(1)
  {
    i2c_read( 6,acc,0x3b);
    acc_x = (acc[1] + acc[0]<<8);
    acc_y = (acc[3] + acc[2]<<8);
    acc_z = (acc[5] + acc[4]<<8);
  }
  //return 0;
}
 
void i2c1_conf (void)
{
  RCC->AHBENR |=RCC_AHBENR_GPIOAEN;
  GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR9|GPIO_OSPEEDR_OSPEEDR10;
  GPIOA->PUPDR |= GPIO_PUPDR_PUPDR9_0|GPIO_PUPDR_PUPDR10_0;//A9=>SCL A10=>SDA
  GPIOA->AFR[1] |= (4<<((9-8)*4)|4<<((10-8)*4));
  RCC->CFGR3 |= (1<<4);// I2C1SW SYSCLK
  RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  I2C1->CR1 &= ~ I2C_CR1_PE;
  
   
  I2C1->TIMINGR =0x50330309;//400KHZ ANALOG FILTER ON   //or 0X00801CAB OR 0x00C31845 OR 0x00C31C45(BEST I THINK) or 0x00C01A4B;
  I2C1->CR1 &= ~( I2C_CR1_ANFOFF|I2C_CR1_DFN );//ANALOG FILTER ENABLE DIGITAL fILTER OFF
   delay_ms(10);
   I2C1->CR1 |= I2C_CR1_PE;//|I2C_CR1_TXIE ;
  I2C1->CR2 &= ~(I2C_CR2_ADD10|I2C_CR2_RELOAD|I2C_CR2_AUTOEND);
  I2C1->CR2 |= 0X69<<1;
 // NVIC_EnableIRQ(I2C1_IRQn );
  
 
}
 
void i2c_write( uint8_t nby , uint8_t *data ,uint8_t addr)
 
{
  
  
  I2C1->CR2 &= ~I2C_CR2_RD_WRN; //WRITE MODE
  I2C1->CR2 |= (nby<<16);
  I2C1->CR2 |= I2C_CR2_START;
  status = I2C1->ISR;
  //while( ((I2C1->CR2 & I2C_CR2_START)==I2C_CR2_START));
  while (!((I2C1->ISR & I2C_ISR_TXE) == I2C_ISR_TXE));//can be removed
  I2C1->TXDR = addr;
  //I2C1->CR2 |= I2C_CR2_START;
  for(uint8_t contr =0; contr<nby ;contr++)
  { 
    while (!((I2C1->ISR & I2C_ISR_TXIS) == I2C_ISR_TXIS))
    {
      status=I2C1->ISR;
      contr1=contr;
    }
    status=I2C1->ISR;
    cr2=I2C1->CR2;
    I2C1->TXDR = data[contr];
   
  }
  while ( !((I2C1->ISR & I2C_ISR_TC)==I2C_ISR_TC));
  I2C1->CR2 |= I2C_CR2_STOP;
}
 
void i2c_read( uint8_t nby , uint8_t *data, uint8_t addr)
{
  I2C1->CR2 &= ~I2C_CR2_RD_WRN; //WRITE MODE
  I2C1->CR2 |= (1<<16);
  I2C1->CR2 |= I2C_CR2_START;
  while (!((I2C2->ISR & I2C_ISR_TXE) == I2C_ISR_TXE));
  I2C1->TXDR = addr;
  while ( !((I2C1->ISR & I2C_ISR_TC)==I2C_ISR_TC));
  
  I2C1->CR2 |= I2C_CR2_RD_WRN;//READ MODE
  for(uint8_t contr =0; contr<nby ;contr++)
  {
    
    while (!((I2C2->ISR & I2C_ISR_RXNE) == I2C_ISR_RXNE));
    data[contr] =I2C1->RXDR;
  }
  while ( !((I2C1->ISR & I2C_ISR_TC)==I2C_ISR_TC));
  I2C1->CR2 |= I2C_CR2_STOP;
 
}
 
void delay_ms(uint16_t delay_m)
{
  RCC->APB1ENR |= RCC_APB1ENR_TIM14EN;
  TIM14->CR1 &= ~(TIM_CR1_CEN|TIM_CR1_UDIS);
  TIM14->PSC =48000;
  TIM14->CNT=0;
  TIM14->DIER &= ~ TIM_DIER_UIE;
  TIM14->ARR=delay_m;
  TIM14->CR1 |= TIM_CR1_CEN;
  while(!(TIM_SR_UIF & TIM14->SR));
  TIM14->SR &= ~TIM_SR_UIF;
  TIM14->CR1 &= ~TIM_CR1_CEN;
  
}
/*
  void I2C1_IRQHandler (void)
  {
    if ((I2C2->ISR & I2C_ISR_RXNE) == I2C_ISR_RXNE)
  {
  
    data_r = I2C2->RXDR; 
  
  }
  }
*/

0 REPLIES 0