Jump to content
Ivan Rusev

stm32f EEPROM

Recommended Posts

Уже не один день  сижу думаю как  запустить stm32  с eeprom для сохранения данных.И в кубе такая же история.Записую функцию чтения в майн и контролер  садится ничего не работает ? В чём дело ? Сталкивались с таким чудом.Записывал без функции тоже самое одна сторока  его убивает.

#include"main.h"
#define I2C_REQUEST_WRITE                       0x00//0
#define I2C_REQUEST_READ                        0x01
#define EEPROM_ADDRESS                   0b1010000
#define I2C_OWNADDRESS1_7BIT             0x00004000U
void i2c1_AF_init(void)
{
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL7_0;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL7_1;
  GPIOB->AFR[0]|=GPIO_AFRL_AFSEL7_2    ;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL7_3;

  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL6_0;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL6_1;
  GPIOB->AFR[0]|=GPIO_AFRL_AFSEL6_2;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL6_3;
}

void i2c1_init(void)
{
    GPIOB->MODER|=GPIO_MODER_MODE7_1;
    GPIOB->MODER&=~GPIO_MODER_MODE7_0;
    GPIOB->OTYPER|=GPIO_OTYPER_OT7;
    GPIOB->MODER|=GPIO_MODER_MODE6_1;
    GPIOB->MODER&=~GPIO_MODER_MODE6_0;
    GPIOB->OTYPER|=GPIO_OTYPER_OT6;
    RCC->APB1ENR|=RCC_APB1ENR_I2C1EN;

    I2C1->CR2&=~I2C_CR2_FREQ_2  ;
    I2C1->TRISE=9;
    I2C1->CCR&=~I2C_CCR_FS;
    //I2C1->OAR1|=I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE;
     I2C1->OAR1|= I2C_OWNADDRESS1_7BIT;
    //I2C1->CR1|=I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP;


    I2C1->CR1|=I2C_CR1_ACK;
    I2C1->OAR2|=I2C_OAR2_ADD2;
    I2C1->CR1|=I2C_CR1_PE;
}
void I2C1_SendByteByADDR1(uint16_t adres,uint8_t  data)
{

    //uint8_t data2;
    I2C1->CR1|=I2C_CR1_ACK;
    I2C1->CR1|=I2C_CR1_START;
      while(!(I2C1->SR1&I2C_SR1_SB))
      {
      }
    (void) I2C1->SR1;
    I2C1->DR|=  EEPROM_ADDRESS |I2C_REQUEST_WRITE;
    //I2C1->DR|= addr | I2C_REQUEST_WRITE;//
     while (!(I2C1->SR1& I2C_SR1_ADDR))
     {
     }
     (void) I2C1->SR1;
     (void) I2C1->SR2;
     I2C1->DR|=(uint8_t)adres;//
     while (!(I2C1->SR1& I2C_SR1_TXE))
     {

     }
     I2C1->DR|=(uint8_t) (adres>>8) ;//
     while (!(I2C1->SR1 & I2C_SR1_TXE))
     {

     }

     I2C1->DR|=data;
     while (!(I2C1->SR1 & I2C_SR1_BTF))
     {
     }
     I2C1->CR1|=I2C_CR1_STOP;
}
void I2C1_readByteByADDR1(uint16_t adres,uint8_t data)
{

    //uint8_t data2;
    //uint8_t data1;
    I2C1->CR1|=I2C_CR1_ACK;
      I2C1->CR1|= I2C_CR1_START;

      while (!(I2C1->SR1& I2C_SR1_SB)){}

      (void) I2C1->SR1;
      I2C1->DR|=  EEPROM_ADDRESS |I2C_REQUEST_WRITE;
     // I2C1->DR|= SLAVE_OWN_ADDRESS | I2C_REQUEST_WRITE;

      while (!(I2C1->SR1& I2C_SR1_ADDR)){}
      (void) I2C1->SR1;
      (void) I2C1->SR2;
      //Transmit Address begin EEPROM
      I2C1->DR|=  (uint8_t) adres;
     while (!(I2C1->SR1& I2C_SR1_TXE)){}
     I2C1->DR|=(uint8_t) (adres>>8);
      while (!(I2C1->SR1& I2C_SR1_TXE)){}

      I2C1->CR1 |= I2C_CR1_START;
       while (!(I2C1->SR1 & I2C_SR1_SB)){}
       (void) I2C1->SR1;
       I2C1->DR = EEPROM_ADDRESS|I2C_REQUEST_READ;
       while (!(I2C1->SR1 & I2C_SR1_ADDR)){}
        (void) I2C1->SR1;
        (void) I2C1->SR2;
        I2C1->CR1 &= ~I2C_CR1_ACK;
                while (!(I2C1->SR1 & I2C_SR1_RXNE)){}


                 data= I2C1->DR;
            //    while (!(I2C1->SR1 & I2C_SR1_RXNE)){}
                 //data2 =I2C1->DR;
              I2C1->CR1 |= I2C_CR1_STOP;
            //   return data;
            //    Delay(5);
}

void i2c2_AF_init(void)
{
    GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL10_0;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL10_1;
      GPIOB->AFR[1]|=GPIO_AFRH_AFSEL10_2    ;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL10_3;

      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL11_0;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL11_1;
      GPIOB->AFR[1]|=GPIO_AFRH_AFSEL11_2;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL11_3;
}

void i2c2_init(void)
{
    GPIOB->MODER|=GPIO_MODER_MODE10_1;
        GPIOB->MODER&=~GPIO_MODER_MODE10_0;
        GPIOB->OTYPER|=GPIO_OTYPER_OT10;
        GPIOB->MODER|=GPIO_MODER_MODE11_1;
        GPIOB->MODER&=~GPIO_MODER_MODE11_0;
        GPIOB->OTYPER|=GPIO_OTYPER_OT11;
        //RCC->APB1ENR|=RCC_APB1ENR_I2C2EN;

}
 

Скрытый текст
Скрытый текст

#include"main.h"
#define I2C_REQUEST_WRITE                       0x00//0
#define I2C_REQUEST_READ                        0x01
#define EEPROM_ADDRESS                   0b1010000
#define I2C_OWNADDRESS1_7BIT             0x00004000U
void i2c1_AF_init(void)
{
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL7_0;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL7_1;
  GPIOB->AFR[0]|=GPIO_AFRL_AFSEL7_2    ;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL7_3;

  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL6_0;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL6_1;
  GPIOB->AFR[0]|=GPIO_AFRL_AFSEL6_2;
  GPIOB->AFR[0]&=~GPIO_AFRL_AFSEL6_3;
}

void i2c1_init(void)
{
    GPIOB->MODER|=GPIO_MODER_MODE7_1;
    GPIOB->MODER&=~GPIO_MODER_MODE7_0;
    GPIOB->OTYPER|=GPIO_OTYPER_OT7;
    GPIOB->MODER|=GPIO_MODER_MODE6_1;
    GPIOB->MODER&=~GPIO_MODER_MODE6_0;
    GPIOB->OTYPER|=GPIO_OTYPER_OT6;
    RCC->APB1ENR|=RCC_APB1ENR_I2C1EN;

    I2C1->CR2&=~I2C_CR2_FREQ_2  ;
    I2C1->TRISE=9;
    I2C1->CCR&=~I2C_CCR_FS;
    //I2C1->OAR1|=I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE;
     I2C1->OAR1|= I2C_OWNADDRESS1_7BIT;
    //I2C1->CR1|=I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP;


    I2C1->CR1|=I2C_CR1_ACK;
    I2C1->OAR2|=I2C_OAR2_ADD2;
    I2C1->CR1|=I2C_CR1_PE;
}
void I2C1_SendByteByADDR1(uint16_t adres,uint8_t  data)
{

    //uint8_t data2;
    I2C1->CR1|=I2C_CR1_ACK;
    I2C1->CR1|=I2C_CR1_START;
      while(!(I2C1->SR1&I2C_SR1_SB))
      {
      }
    (void) I2C1->SR1;
    I2C1->DR|=  EEPROM_ADDRESS |I2C_REQUEST_WRITE;
    //I2C1->DR|= addr | I2C_REQUEST_WRITE;//
     while (!(I2C1->SR1& I2C_SR1_ADDR))
     {
     }
     (void) I2C1->SR1;
     (void) I2C1->SR2;
     I2C1->DR|=(uint8_t)adres;//
     while (!(I2C1->SR1& I2C_SR1_TXE))
     {

     }
     I2C1->DR|=(uint8_t) (adres>>8) ;//
     while (!(I2C1->SR1 & I2C_SR1_TXE))
     {

     }

     I2C1->DR|=data;
     while (!(I2C1->SR1 & I2C_SR1_BTF))
     {
     }
     I2C1->CR1|=I2C_CR1_STOP;
}
void I2C1_readByteByADDR1(uint16_t adres,uint8_t data)
{

    //uint8_t data2;
    //uint8_t data1;
    I2C1->CR1|=I2C_CR1_ACK;
      I2C1->CR1|= I2C_CR1_START;

      while (!(I2C1->SR1& I2C_SR1_SB)){}

      (void) I2C1->SR1;
      I2C1->DR|=  EEPROM_ADDRESS |I2C_REQUEST_WRITE;
     // I2C1->DR|= SLAVE_OWN_ADDRESS | I2C_REQUEST_WRITE;

      while (!(I2C1->SR1& I2C_SR1_ADDR)){}
      (void) I2C1->SR1;
      (void) I2C1->SR2;
      //Transmit Address begin EEPROM
      I2C1->DR|=  (uint8_t) adres;
     while (!(I2C1->SR1& I2C_SR1_TXE)){}
     I2C1->DR|=(uint8_t) (adres>>8);
      while (!(I2C1->SR1& I2C_SR1_TXE)){}

      I2C1->CR1 |= I2C_CR1_START;
       while (!(I2C1->SR1 & I2C_SR1_SB)){}
       (void) I2C1->SR1;
       I2C1->DR = EEPROM_ADDRESS|I2C_REQUEST_READ;
       while (!(I2C1->SR1 & I2C_SR1_ADDR)){}
        (void) I2C1->SR1;
        (void) I2C1->SR2;
        I2C1->CR1 &= ~I2C_CR1_ACK;
                while (!(I2C1->SR1 & I2C_SR1_RXNE)){}


                 data= I2C1->DR;
            //    while (!(I2C1->SR1 & I2C_SR1_RXNE)){}
                 //data2 =I2C1->DR;
              I2C1->CR1 |= I2C_CR1_STOP;
            //   return data;
            //    Delay(5);
}

void i2c2_AF_init(void)
{
    GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL10_0;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL10_1;
      GPIOB->AFR[1]|=GPIO_AFRH_AFSEL10_2    ;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL10_3;

      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL11_0;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL11_1;
      GPIOB->AFR[1]|=GPIO_AFRH_AFSEL11_2;
      GPIOB->AFR[1]&=~GPIO_AFRH_AFSEL11_3;
}

void i2c2_init(void)
{
    GPIOB->MODER|=GPIO_MODER_MODE10_1;
        GPIOB->MODER&=~GPIO_MODER_MODE10_0;
        GPIOB->OTYPER|=GPIO_OTYPER_OT10;
        GPIOB->MODER|=GPIO_MODER_MODE11_1;
        GPIOB->MODER&=~GPIO_MODER_MODE11_0;
        GPIOB->OTYPER|=GPIO_OTYPER_OT11;
        //RCC->APB1ENR|=RCC_APB1ENR_I2C2EN;

}
 

#include"main.h"
#include<stdio.h>
#define button1    // GPIOA->IDR  &GPIO_IDR_ID6
#define button2   //  GPIOA->IDR  &GPIO_IDR_ID7
//#include"#include"main.h"lcd2.h"
volatile unsigned int pauza=0;
volatile unsigned int pauza_1=0;
volatile unsigned char flag1=0;
volatile unsigned char flag=0;
volatile unsigned char flag2=0;
volatile   unsigned int b,c;
volatile   unsigned char b1,b2,c1,c2,t1,t2;
volatile   unsigned int t,m;
volatile unsigned char menu=0;
volatile unsigned char menu_en=0;
volatile unsigned char menu_eep=0;
volatile unsigned int adc_data1=0;
volatile   unsigned int adc_data2=0;
volatile   unsigned int adc_data3=0;
volatile unsigned int adc_data4=0;
char bufer1[16]={};


 char bufer2[16];
 char bufer3[16];
 uint16_t temp;
uint16_t ADC_Data[4];
//#define z 0xB1//Я
typedef unsigned char byte; //переопределяем тип
void delay_ms(int a)
{
    int i = 0;
    int f = 0;
   while(f < a)
    {
        while(i<60)
            {i++;}
        f++;
    }
}


uint8_t bii [8]=
{
         0B00000,
          0B00000,
          0B01010,
          0B00100,
          0B00100,
          0B00100,
          0B00100,
          0B00000
};
uint8_t bk [8]=
{
        0B00000,
          0B00000,
          0B01001,
          0B01010,
          0B01100,
          0B01010,
          0B01001,
          0B00000
};
uint8_t bj [8]=
{
         0B00000,
          0B00000,
          0B10101,
          0B01110,
          0B00100,
          0B01110,
          0B10101,
          0B00000
};
uint8_t bm[]=
{


            0B00000,
           0B00000,
           0B10001,
           0B11011,
           0B10101,
           0B10001,
           0B10001,
           0B00000
};
uint8_t bn[]=
{
        0B00000,
          0B00000,
          0B10010,
          0B10010,
          0B11110,
          0B10010,
         0B10010,
          0B00000
};
uint8_t biu[]=
{
        0B00000,
          0B00000,
          0B10111,
          0B10101,
          0B11101,
          0B10101,
          0B10111,
          0B00000

};
uint8_t iorp[]=
{
        0b00000,
            0b01100,
            0b11110,
            0b11110,
            0b01111,
            0b00111,
            0b00011,
            0b00001
};
uint8_t ior2p[]=
{
        0b00000,
            0b00110,
            0b01111,
            0b01110,
            0b11110,
            0b11100,
            0b11000,
            0b10000
};

  void init_IWDGtimer(void)
  {
      RCC->CSR|= RCC_CSR_LSION;

         IWDG->KR = 0x5555; // Access to registers
         IWDG->PR&= ~(IWDG_PR_PR_0 | IWDG_PR_PR_1 | IWDG_PR_PR_2); // 4096
         IWDG->RLR =250;//0x7FF;
         while (!((IWDG->SR & IWDG_SR_PVU) && (IWDG->SR & IWDG_SR_RVU))){} // wait while bist of PVU and RVU will be set.
         IWDG->KR = 0xCCCC; // Start count down;
  }
  void program1(void)
  {

      if(pauza==1)
      {
          lcd_clear();
         lcd_set_xy(0, 0);
        // IWDG->KR = 0xAAAA;
      }
              if(pauza==20)
         {

               //PORTC13_ON;
         lcd_clear();
         lcd_set_xy(0, 0);
         lcd_send(2,DATA);

         }

       if(pauza==35)
       {
        //   PORTC13_OF;
           lcd_clear();
           lcd_set_xy(0, 0);
           lcd_send('a',DATA);
           lcd_send(2,DATA);


        // pauza=0;
       }

       if(pauza==50)
       {
           lcd_clear();
          lcd_set_xy(0, 0);
         // lcd_set_user_char(0, bii);
         // lcd_set_user_char(1, bj);
         lcd_send(1,DATA);
         lcd_send('a',DATA);
         lcd_send(2,DATA);
       }

        if(pauza==65)
         {
            lcd_clear();
            //lcd_set_user_char(0, bii);
         // lcd_set_user_char(1, bj);
          lcd_set_xy(0, 0);
          lcd_send(0,DATA);
          lcd_send(1,DATA);
          lcd_send('a',DATA);
          lcd_send(2,DATA);
          //pauza=0;
          }

        if(pauza==80)
        {
                  lcd_clear();

                 lcd_set_xy(0, 0);
                 lcd_send(' ' ,DATA);
                 lcd_send( 0 ,DATA);
                 lcd_send(1,DATA);
                 lcd_send('a',DATA);
                 lcd_send(2,DATA);
                 //pauza=0;
         }

        if(pauza==95)
         {
                       lcd_clear();
                      // lcd_set_xy(0, 0);

                     //  lcd_set_user_char(0, bii);
                     //      lcd_set_user_char(1, bj);
                         lcd_set_xy(0, 0);
                         lcd_send(' ',DATA);
                         lcd_send(' ',DATA);
                         lcd_send( 0 ,DATA);
                         lcd_send(1,DATA);
                         lcd_send('a',DATA);
                         lcd_send(2,DATA);
                         lcd_set_xy(0, 1);
                         lcd_send(3,DATA);
                         lcd_send('e',DATA);
                         lcd_send(4,DATA);
                         lcd_send(5,DATA);
                         lcd_send(' ',DATA);
                         lcd_send( 3 ,DATA);
                         lcd_send('a',DATA);
                         lcd_send( 3 ,DATA);
                         lcd_send('a',DATA);
                        // lcd_out("mama");
                      //   pauza=0;

             }

       // IWDG->KR = 0xAAAA;
     }

  void program2(void)
  {

           // TIM3->CNT=0;

               // lcd_clear();

       lcd_set_xy(0, 0);
       lcd_send(' ',DATA);
       lcd_send(' ',DATA);
       lcd_send( 0 ,DATA);
       lcd_send(1,DATA);
       lcd_send('a',DATA);
       lcd_send(2,DATA);
       lcd_send(' ',DATA);
       lcd_send(3,DATA);
       lcd_send('e',DATA);
       lcd_send(4,DATA);
       lcd_send(5,DATA);

        lcd_set_xy(0, 1);
       // lcd_send(' ',DATA);
       // lcd_send('b',DATA);
      //  lcd_send('=',DATA);
      //  lcd_send(b/10+0x30,DATA);
        //lcd_send(b%10+0x30,DATA);
        //lcd_send(b%100+0x30,DATA);
       // b1=b/256;
        // b2=b%256;
              //TIM3->CNT=b;
             // t=0;
        lcd_send(' ',DATA);
        lcd_send(' ',DATA);
               sprintf(bufer1,"b=%4d",b);
              lcd_out(bufer1);
         //    lcd_send(' ',DATA);
        //     flag2=1;
             b2=b/256;
              b1=b%256;

             // Delay(40);
             // IWDG->KR = 0xAAAA;
         // }
  }
  void program3(void)
    {//
      //   lcd_clear();
          lcd_set_xy(0, 0);
          lcd_send(' ',DATA);
            lcd_send(' ',DATA);
            lcd_send( 0 ,DATA);
            lcd_send(1,DATA);
            lcd_send('a',DATA);
            lcd_send(2,DATA);
            lcd_send(' ',DATA);
           lcd_send(3,DATA);
           lcd_send('e',DATA);
           lcd_send(4,DATA);
           lcd_send(5,DATA);
         // t=700;
      //    t=TIM3->CNT;
                 lcd_set_xy(0,1);
               //lcd_send(' ',DATA);
           //    lcd_send('t',DATA);
               //lcd_send('=',DATA);
               //lcd_send(t/10+0x30,DATA);
               //lcd_send(t%10+0x30,DATA);
           //    lcd_send(t%100+0x30,DATA);
               //t1=t/256;
           //    t2=t%256;
               lcd_send(' ',DATA);
              lcd_send(' ',DATA);
                 sprintf(bufer2,"t=%4d",t);
                 lcd_out(bufer2);
               //IWDG->KR = 0xAAAA;

    }
  void program4(void)
  {
     // lcd_clear();
      lcd_set_xy(0, 0);
              lcd_send(' ',DATA);
                lcd_send(' ',DATA);
                lcd_send( 0 ,DATA);
                lcd_send(1,DATA);
                lcd_send('a',DATA);
                lcd_send(2,DATA);
                lcd_send(' ',DATA);
               lcd_send(3,DATA);
               lcd_send('e',DATA);
               lcd_send(4,DATA);
               lcd_send(5,DATA);
             // t=700;
        //      c=TIM3->CNT;

              lcd_set_xy(0,1);
          //    lcd_send(' ',DATA);
              //lcd_send('c',DATA);
          //    lcd_send('=',DATA);

            //lcd_send(c/10+0x30,DATA);
              // lcd_send(c%10+0x30,DATA);
              // lcd_send(c%100+0x30,DATA);
          //    c1=c/256;
          //    c2=c%256;
          //    TIM3->CNT=c;
              lcd_send(' ',DATA);
            lcd_send(' ',DATA);
              sprintf(bufer3,"c=  %4d",c);
              lcd_out(bufer3);
  }
void Calbac (void)
{
    ADC_Data[0]=ADC1->JDR1;
    ADC_Data[1]=ADC1->JDR2;
    ADC_Data[2]=ADC1->JDR3;
    ADC_Data[3]=ADC1->JDR4;

    //TIM4->CCR3=ADC_Data[2];
   // TIM4->CCR3=ADC_Data[0];
    //TIM4->CCR3=ADC_Data[2];
}
int main(void)
{

    //I2C1_readByteByADDR1(1,0);
    //char bufer1[16];
    //lcd_delay();
    //int b;
    //init_IWDGtimer(); ./
    AHB1ER_init();
    i2c1_AF_init();
        i2c1_init();
        // lcd_clear();

//    I2C1_readByteByADDR1(0x02,b);
    I2C1_readByteByADDR1(0x11,b1);
    PORT_init();
     timer1_init();
    timer2_init();
    AFR_init_time3();
    timer3_init();
    AFR_init_time4();
    time4_init();
    time5_init();
    timer6_init();
    adc3_init_regular();
    adc1_init_inject();

    //lcd_init_GPIO();
    // str_lcd("string");
    //I2C1_readByteByADDR1(1,0);
    //I2C1_readByteByADDR1(3,2);
    //I2C1_readByteByADDR1(5,4);
//    I2C1_readByteByADDR1(7,6);
    //I2C1_readByteByADDR1(9,8);
    //I2C1_readByteByADDR1(11,10);
    // LCD_Clear();
    ADC1->CR1|= ADC_CR1_JEOCIE;

       ADC1->CR2 |=  ADC_CR2_ADON;
    NVIC_EnableIRQ ( ADC_IRQn);
    ADC3->CR2|=ADC_CR2_EXTSEL_2 |ADC_CR2_EXTSEL_1;
    ADC1->CR2|=ADC_CR2_JEXTSEL_1 |ADC_CR2_JEXTSEL_0;
    //ADC1->CR2|=ADC_CR2_JSWSTART;
    //LCD_init1();
    lcd_init();
    //();
     //lcd_set_state(LCD_ENABLE, CURSOR_ENABLE, BLINK);

    lcd_set_user_char(0, bii);
    lcd_set_user_char(1, bj);
    lcd_set_user_char(2, bk);
    lcd_set_user_char(3, bm);
    lcd_set_user_char(4, bn);
    lcd_set_user_char(5, biu);
    // Наша рыба это символ номер ноль
     // lcd_out("This is fish"); //Выводим надпись в нулевую строку
     // lcd_set_xy(0,1); //переводим курсор в первую строку
      //lcd_send(0,DATA);
     // lcd_send(1,DATA);
      //lcd_send('a',DATA);
      //Выводим символ номер ноль
     // lcd_set_state(LCD_ENABLE, CURSOR_ENABLE, BLINK);
    //lcd_set_state(LCD_ENABLE,CURSOR_ENABLE,NO_BLINK);
    //lcd_clear();
    //lcd_set_state(LCD_ENABLE,CURSOR_ENABLE,NO_BLINK);
    //InitialLCD();
    //ClearLCD();
    //Cursor(0,2);
    //lcd_out("mama");
    //PrintStr("MAMA");

    //lcd_set_xy(0, 1);
    //lcd_out("mama");
    //lcd_set_xy(6, 6);
    //lcd_out("papa");
    //lcd_send('X',DATA);
//    lcd_send('y',DATA);
    //lcd_send('e',DATA);
//    clearlcd();
//     str_lcd("string");
    // delay_ms(50);
    init_IWDGtimer();
     b=((unsigned int) b1<<8)|b2;
      c=((unsigned int )c1<<8)|c2;
      t=((unsigned int) t1<<8)|t2;
    while(1)
    {


      if(menu==0)
      {
          program1();

      }

     if(menu==1)
       {

          program2();
          Delay(5);
       }


      if(menu==2)
       {

          program3();

              Delay(5);

       }

      if(menu==3)
       {
          program4();
          Delay(5);

       }
      if(menu==4)
      {
          menu=0;
      }
       if(menu_en==1)
      {

          if(!(GPIOC->IDR  &GPIO_IDR_ID1))
         {

                if(b>4095)
                {
                   b=0;
                }
                 b++;

          }
       }
        if(menu_en==2)
       {

         if(!(GPIOC->IDR &GPIO_IDR_ID1))
         {


            if(t>4095)
            {
                 t=0;
            }
              t++;

          }


      }
       if(menu_en==3)
       {
           if(!(GPIOC->IDR &GPIO_IDR_ID1))
           {
              if(c>4095)
              {
                  c=0;
              }
              c++;
           }

       }
       if(menu_en==4)
       {
           menu_en=0;
       }

    }
}
 

 

3 минуты назад, Ivan Rusev сказал:

 while (!(I2C1->SR1& I2C_SR1_ADDR)){}

вот на  этой строчке

Share this post


Link to post
Share on other sites

Вебинар «МЭМС-датчики ST для работы со звуком – новые возможности» (28.10.2020)

28 октября все желающие приглашаются для участия в вебинаре, посвященном семейству МЭМС-датчиков STMicroelectronics для акустических приложений. Предметом детального рассмотрения на вебинаре станут микрофоны, их топологии применения и возможности. Вы услышите о новых мультирежимных широкодиапазонных микрофонах с нижним портом и PDM-интерфейсом для систем с батарейным питанием.

Подробнее

F4 я не программировал,  вот сдесь посмотри:  STM32F40x and STM32F41x Errata sheet

Share this post


Link to post
Share on other sites

STM32L562E-DK – первая отладочная платформа ST на ядре ARM Cortex-M33

STMicroelectronics представляет демонстрационно-отладочную платформу на базе ядра Cortex-M33 – STM32L562E-DK. Данная платформа основана на микроконтроллере нового семейства – STM32L5. STM32L562E-DK позволяет разработчику в полной мере раскрыть и опробовать новые возможности микроконтроллеров STM32L5 с тщательно проработанным функционалом для обеспечения высокого уровня безопасности и защиты.

Подробнее

я тоже об этой Errata sheet второй раз слышу.Вы имеете ввиду обратить внимание на настройку I2C в этой документации?

Share this post


Link to post
Share on other sites

Тест уровня кондуктивной помехи электронного устройства

Электромагнитная совместимость (ЭМС) является важным параметром электронных устройств, особенно это актуально в современном мире, насыщенном разнообразными гаджетами. Специалисты компании Mornsun подготовили видеоролик по тестированию одной из составляющих ЭМС – кондуктивной помехи.

Подробнее

Да похоже, что одна и та же. В errata stm32 f1 более подробно написано на странице 26.

2.14.7 I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry

Share this post


Link to post
Share on other sites
4 часа назад, leshasoft сказал:

2.14.7 I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry

нужно включить аналоговый филтр.Даже в кубе нет такой возможности.А в cmsis я пишу I2C1 -> ? там такого регистра нет как его включить?

Share this post


Link to post
Share on other sites

Скачайте себе эту документацию:

STM32F10xx8 STM32F10xxB Errata sheet
https://www.st.com/resource/en/errata_sheet/cd00190234-stm32f101x8-b-stm32f102x8-b-and-stm32f103x8-b-medium-density-device-limitations-stmicroelectronics.pdf
Errata sheet - STM32F40x and STM32F41x - STM32F405
https://www.st.com/resource/en/errata_sheet/dm00037591-stm32f405-407xx-and-stm32f415-417xx-device-limitations-stmicroelectronics.pdf
 

Скрытый текст

 

2.14.7 I2C analog filter may provide wrong value, locking BUSY flag and
preventing master mode entry

Description

The I2C analog filters embedded in the I2C I/Os may be tied to low level, whereas SCL and
SDA lines are kept at high level. This can occur after an MCU power-on reset, or during
ESD stress. Consequently, the I2C BUSY flag is set, and the I2C cannot enter master mode
(START condition cannot be sent). The I2C BUSY flag cannot be cleared by the SWRST
control bit, nor by a peripheral or a system reset. BUSY bit is cleared under reset, but it is
set high again as soon as the reset is released, because the analog filter output is still at low
level. This issue occurs randomly.
Note: Under the same conditions, the I2C analog filters may also provide a high level, whereas
SCL and SDA lines are kept to low level. This should not create issues as the filters output is
correct after next SCL and SDA transition.
 
Workaround

The SCL and SDA analog filter output is updated after a transition occurs on the SCL and
SDA line respectively. The SCL and SDA transition can be forced by software configuring
the I2C I/Os in output mode. Then, once the analog filters are unlocked and output the SCL
and SDA lines level, the BUSY flag can be reset with a software reset, and the I2C can enter
master mode. Therefore, the following sequence must be applied:
1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level
(Write 1 to GPIOx_ODR).
3. Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to
GPIOx_ODR).
9. Check SCL High level in GPIOx_IDR.
10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
11. Check SDA High level in GPIOx_IDR.
12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
13. Set SWRST bit in I2Cx_CR1 register.
14. Clear SWRST bit in I2Cx_CR1 register.
15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.

 

 

Share this post


Link to post
Share on other sites

При работе с i2c нельзя использовать чистый while, нужно вводить timeout
вы можете ожидать ACK от устройства и прождать вечность, думаю что у вас завис алгоритм

К тому же есть регистры ошибок.

Если бы вышли из While, могли бы его посмотреть или же смотреть его в режиме отладки

 

Хоть у вас нет желания использовать HAL, но заглядывать в него иногда полезно, чтобы не тратить свое время

Мне не стыдно заглядывать и в код Arduino или портировать его для новых устройств

Edited by hasl

Share this post


Link to post
Share on other sites

В кубе тоже самое только не в HAL а LL.Это не моя библиотека я её здёр у спецов

2 часа назад, hasl сказал:

й while, нужно вводить timeout

и куда его прописывать я первый раз об этом читаю

 

2 часа назад, hasl сказал:

К тому же есть регистры ошибок

Это в коде есть регистры ошибок или есть ошибки?

3 часа назад, leshasoft сказал:

Скачайте себе эту документацию:

STM32F10xx8 STM32F10xxB Errata sheet
https://www.st.com/resource/en/errata_sheet/cd00190234-stm32f101x8-b-stm32f102x8-b-and-stm32f103x8-b-medium-density-device-limitations-stmicroelectronics.pdf
Errata sheet - STM32F40x and STM32F41x - STM32F405
https://www.st.com/resource/en/errata_sheet/dm00037591-stm32f405-407xx-and-stm32f415-417xx-device-limitations-stmicroelectronics.pdf
 

  Скрыть содержимое

 

2.14.7 I2C analog filter may provide wrong value, locking BUSY flag and
preventing master mode entry

Description

The I2C analog filters embedded in the I2C I/Os may be tied to low level, whereas SCL and
SDA lines are kept at high level. This can occur after an MCU power-on reset, or during
ESD stress. Consequently, the I2C BUSY flag is set, and the I2C cannot enter master mode
(START condition cannot be sent). The I2C BUSY flag cannot be cleared by the SWRST
control bit, nor by a peripheral or a system reset. BUSY bit is cleared under reset, but it is
set high again as soon as the reset is released, because the analog filter output is still at low
level. This issue occurs randomly.
Note: Under the same conditions, the I2C analog filters may also provide a high level, whereas
SCL and SDA lines are kept to low level. This should not create issues as the filters output is
correct after next SCL and SDA transition.
 
Workaround

The SCL and SDA analog filter output is updated after a transition occurs on the SCL and
SDA line respectively. The SCL and SDA transition can be forced by software configuring
the I2C I/Os in output mode. Then, once the analog filters are unlocked and output the SCL
and SDA lines level, the BUSY flag can be reset with a software reset, and the I2C can enter
master mode. Therefore, the following sequence must be applied:
1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level
(Write 1 to GPIOx_ODR).
3. Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to
GPIOx_ODR).
9. Check SCL High level in GPIOx_IDR.
10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
11. Check SDA High level in GPIOx_IDR.
12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
13. Set SWRST bit in I2Cx_CR1 register.
14. Clear SWRST bit in I2Cx_CR1 register.
15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.

 

 

Я скачал уже.Спасибо буду думать

3 часа назад, leshasoft сказал:

Скачайте себе эту документацию:

STM32F10xx8 STM32F10xxB Errata sheet
https://www.st.com/resource/en/errata_sheet/cd00190234-stm32f101x8-b-stm32f102x8-b-and-stm32f103x8-b-medium-density-device-limitations-stmicroelectronics.pdf
Errata sheet - STM32F40x and STM32F41x - STM32F405
https://www.st.com/resource/en/errata_sheet/dm00037591-stm32f405-407xx-and-stm32f415-417xx-device-limitations-stmicroelectronics.pdf
 

  Показать содержимое

 

2.14.7 I2C analog filter may provide wrong value, locking BUSY flag and
preventing master mode entry

Description

The I2C analog filters embedded in the I2C I/Os may be tied to low level, whereas SCL and
SDA lines are kept at high level. This can occur after an MCU power-on reset, or during
ESD stress. Consequently, the I2C BUSY flag is set, and the I2C cannot enter master mode
(START condition cannot be sent). The I2C BUSY flag cannot be cleared by the SWRST
control bit, nor by a peripheral or a system reset. BUSY bit is cleared under reset, but it is
set high again as soon as the reset is released, because the analog filter output is still at low
level. This issue occurs randomly.
Note: Under the same conditions, the I2C analog filters may also provide a high level, whereas
SCL and SDA lines are kept to low level. This should not create issues as the filters output is
correct after next SCL and SDA transition.
 
Workaround

The SCL and SDA analog filter output is updated after a transition occurs on the SCL and
SDA line respectively. The SCL and SDA transition can be forced by software configuring
the I2C I/Os in output mode. Then, once the analog filters are unlocked and output the SCL
and SDA lines level, the BUSY flag can be reset with a software reset, and the I2C can enter
master mode. Therefore, the following sequence must be applied:
1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level
(Write 1 to GPIOx_ODR).
3. Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to
GPIOx_ODR).
9. Check SCL High level in GPIOx_IDR.
10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
11. Check SDA High level in GPIOx_IDR.
12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
13. Set SWRST bit in I2Cx_CR1 register.
14. Clear SWRST bit in I2Cx_CR1 register.
15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.

 

 

эта операция для STM32F10xx8 STM32F10xxB.А для STM32F40x and STM32F41x - STM32F405? Как там по другому7

Share this post


Link to post
Share on other sites
16 часов назад, hasl сказал:

При работе с i2c нельзя использовать чистый while, нужно вводить timeout
вы можете ожидать ACK от устройства и прождать вечность, думаю что у вас завис алгоритм

К тому же есть регистры ошибок.

Если бы вышли из While, могли бы его посмотреть или же смотреть его в режиме отладки

 

Хоть у вас нет желания использовать HAL, но заглядывать в него иногда полезно, чтобы не тратить свое время

Мне не стыдно заглядывать и в код Arduino или портировать его для новых устройств

вы были правы почти везде где while процессор перестаёт работать но почему? ведь в нете только такие есть примеры.

19.09.2020 в 22:08, Ivan Rusev сказал:

  while (!(I2C1->SR1 & I2C_SR1_SB)){}

кроме вот  этой строчки.

тут контроллер работает.

Share this post


Link to post
Share on other sites

Запустил Это сама микросхема памяти садит по шине данных процессор.Я глубоко извиняюсь.Включил другую протёр от канифоли.Заработало.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения


  • Набор надфилей

  • Similar Content

    • By BonTens86
      Доброго времени суток господа!) Вопрос к знатокам, начал изучать С++, писать начал на PIC16F628A, по мере изучения столкнулся с несколькими проблемами, первая это нужна помощь с подключением тактовой кнопки к PIC, суть проблемы в том, что при нажатии кнопки светодиод загорается, если нажать еще раз, то ничего не происходит.... Вопрос в том, как сделать выключение на эту же кнопку???? 
      unsigned char CheckButton(void) { unsigned char result=0; unsigned int butcount=0; while(!RB2) { if(butcount < 10000) { butcount++; } else { result = 1; break; } } return result; } void kkk2 (void) { if(CheckButton ()) { RB3 = 1; { //__delay_ms(100); } return; } }  
    • By Arseniy Popov
      Добрый день! Необходимо подобрать микроконтроллер, который будет получать команды по serial от esp8266 и димировать RGBW светодиод по следующему алгоритму: 
      https://docs.google.com/document/d/1FkPLiIgxleuDQn8pjihICQGRrMPXbwFzqCt6StQZjhU/edit?usp=sharing
      а также написать для него прошивку на си.
      Отвечать можете в телеграм arsenicum32 или сюда.
      Пишите цену / сроки, находитесь ли в МСК и/или в области.
    • By butyavk
      Компания "Диаконт" приглашает на собеседование по вакансии инженер-программист микроконтроллеров.
      Мы производим и поставляем современные приборы управления электроприводами для различных отраслей отечественной промышленности.
      Пополняем нашу команду программистов (готовы принять 2-3 кандидатов с различным опытом работы)!

      Основные обязанности:
      Разработка программного обеспечения для блоков управления приводами и др. вычислительных систем.
      Программирование на C++ микроконтроллеров фирмы Texas Instruments и НИИЭТ на базе ядра ARM Cortex-M4.
      Поддержка и доработка существующего программного обеспечения.
      Участие в научно-исследовательских и опытно-конструкторских работах.
      Участие во внедрении систем на объектах (редкие командировки).

      Требования к кандидатам:
      Хорошее знание схемотехники;
      Знание методов разработки и проектирования ПО для микроконтроллеров и опыт работы с их периферией;
      Знание основ управления электроприводами и ТАУ;
      Знание языков программирования высокого уровня (C++, C);
      Знание современных методов разработки ПО (ООП, ...);
      Знание английского языка (чтение технической документации);
      Приветствуется знание Python, Matlab/Octave;
      Дополнительным плюсом будет опыт автоматизированного тестирования встроенного ПО.

      Условия:
      Оплата полностью белая (на руки в зависимости от знаний и опыта от 50 000 руб до 100000 руб). Но, готовы обсуждать!;
      Карьерный и профессиональный рост;
      Предприятие с комфортными условиями труда на севере города;
      ДМС;
      График работы понедельник - пятница 9:00-17:40;
      Плавающее начало работы с 8:00-10:00;
      Льготное питание в столовой на территории предприятия;...

      Ключевые навыки
      Программирование микроконтороллеров
      C/C++
      Управление электродвигателями

      Адрес
      Санкт-Петербург, ул. Учительская 2, м. Гражданский проспект

      Тип занятости
      Полная занятость, полный день

      Резюме лучше отправлять на rykov@diakont.com 
    • By cppjob
      В облачный сервис требуется разработчик С++ для разработки клиентской программы под ОС Windows.
      Место работы - крупная современная IT-компания, офисы в городах:
      Москва Санкт-Петербург Нижний Новгород Екатеринбург Минск График - строго офис, время начала рабочего дня обговаривается индивидуально.
      Заработная плата «в рынке» (для каждого города своя вилка), определяется по результатам собеседования.
      Необходимые знания:
      Уверенное знание C++, опыт работы с ним от двух лет, в том числе с библиотекой STL; Опыт работы с ATL/WTL или MFC от года; Опыт работы с библиотекой Boost от года, в том числе с компонентом Boost.Asio - вам предстоит много работать с сетью; Знание базовых алгоритмов и структур данных; Опыт разработки многопоточных приложений. Ваше портфолио - гарантия оперативного рассмотрения Вашей кандидатуры!
      Вместе с резюме просьба сразу указать контактный телефон (или скайп, если Вы не из Москвы) и удобное время для звонка, чтобы оперативно обсудить детали (разговор займет не более 10-ти минут).
      Резюме направлять на адрес: cppjob@inbox.ru
      Спасибо за внимание!
    • By cppjob
      Место работы: производственное предприятие в г. Москва, часть заказов - оборонного назначения. Удаленка, как Вы, наверное, уже понимаете, невозможна - строго офис.
      Главное условие на эту(!) вакансию: вы уже разрабатывали драйвера под PCI-E на C++ под платформу Windows и у вас есть, чем это подтвердить.
      Ваши плюсы (не обязательно, но желательно - влияет на итоговую сумму оффера):
      1. Практический опыт с ПЛИС Altera и САПР Quartus II;
      2. Знание Verilog;
      3. Опыт разработки драйверов для USB, Ethernet, FW и прочих протоколов;
      4. Опыт работы с SolidWorks;
      5. Опыт разработки графических интерфейсов.
      Если Вы не имеете опыта PCIe+Win+Cpp, но считаете, что можете быть интересны этой компании (см. блок "Ваши плюсы"), Ваше резюме, вполне возможно, тоже сможет заинтересовать компанию - есть и другие вакансии (все они НЕ публичные). Вместе с резюме просьба сразу указать контактный телефон и удобное время для звонка, чтобы оперативно обсудить детали (разговор займет не более 10-ти минут).
      Резюме направлять на адрес: cppjob@inbox.ru
      Спасибо за внимание!
×
×
  • Create New...