STM32F030K6 настройка программы

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030K6 настройка программы

Сообщение oleg110592 »

service47 писал(а):Каким образом можно сохранять пять переменных...
см. AN4061 Application note EEPROM emulation in STM32F0xx microcontrollers.
Для 5 переменных можно использовать EEPROM 1-Wire типа DS2430A.
Реклама
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: STM32F030K6 настройка программы

Сообщение HHIMERA »

Танунаф... Или 24LC01B-I/SN... или 24AA08T-I/OT в SOT23-5L... или 93LC56A-I/SN...
Дёшево и сердито...
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Возможно ли заменить Page size на 0xF для эмуляции eeprom?

Код: Выделить всё

#define PAGE_SIZE             ((uint32_t)0x0400)  /* Page size = 1KByte */
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030K6 настройка программы

Сообщение oleg110592 »

Page size is 1KB for STM32F030x4/6/8 devices and 2KB for STM32F030xC devices
Реклама
Эиком - электронные компоненты и радиодетали
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

В даташите на STM32F030 указано:
Flash memory endurance and data retention 1 kcycles
В AN4061 Application note EEPROM emulation in STM32F0xx microcontrollers указано:
In the STM32F0xx on-chip Flash memory, each page can be programmed or erased reliably
around 10 000 times.
Какое количество раз можно перезаписывать FLASH блоком по 1кБ?
Реклама
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: STM32F030K6 настройка программы

Сообщение HHIMERA »

Сын конфы... начни уже, наконец, читать даташит и референс... и думать, хоть чуть-чуть, своей головой...
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
a5021
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Re: STM32F030K6 настройка программы

Сообщение a5021 »

Плюсую предложение химеры. Лучше напаять сот23, чем терзать флеш МК.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030K6 настройка программы

Сообщение oleg110592 »

service47 писал(а):Какое количество раз можно перезаписывать FLASH блоком по 1кБ?
да, видимо не дочитали AN4061 Application note до конца - там есть формула (см. п. 3.4.2 Flash page allocation)
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

STM32F0xx_EEPROM_Emulation, eeprom.h и eeprom.c подключены, при записи во FLASH зависает.
Спойлер

Код: Выделить всё

/* Virtual address defined by the user: 0xFFFF value is prohibited */
uint16_t VirtAddVarTab[NB_OF_VAR] = {0x6000, 0x6005, 0x6010};

static void Writetoflash2(void)
{
  FLASH_Unlock();
  EE_Init();
  EE_WriteVariable(0x6000, timer);
  FLASH_Lock(); 
}


static void flash_read2(void)
{
  uint16_t* Data1;
  // read the last stored variables data
  EE_ReadVariable(0x6000, Data1);
  timer=(unsigned int)Data1;
}
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030K6 настройка программы

Сообщение oleg110592 »

Код: Выделить всё

/* Virtual address defined by the user: 0xFFFF value is prohibited */
uint16_t VirtAddVarTab[NB_OF_VAR] = {0x6000, 0x6005, 0x6010};
EE_WriteVariable(0x6000, timer); !!!!!!!!!!!!!!!!!!!!!!! 0x6000 что это?
в примере:
/* Store 0x1000 values of Variable1 in EEPROM */
for (VarValue = 1; VarValue <= 0x64; VarValue++)
{
EE_WriteVariable(VirtAddVarTab[0], VarValue);
}
.........
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Нужно пять переменных типа unsigned int записать в эмулируемую EEPROM. 900 раз в один блок, при превышении в следующий, заодно записывать переменные writenum и flashpagenum. А при чтении из EEPROM сначала считывать flashpagenum и далее эти пять переменных.
В примере же задан массив:

Код: Выделить всё

  uint16_t VirtAddVarTab[NB_OF_VAR] = {0x5555, 0x6666, 0x7777};
  uint16_t VarDataTab[NB_OF_VAR] = {0, 0, 0};
  uint16_t VarValue = 0;
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030K6 настройка программы

Сообщение oleg110592 »

на примере, имхо, надо вначале попробовать, есть ли зависание
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Зависаний в примере нет. Пробовал так:
Спойлер

Код: Выделить всё

unsigned int FLASH_USER_START_ADDR = ((uint32_t)0x08006000);
unsigned int FLASH_USER_END_ADDR = ((uint32_t)0x08006400);

static void flash_read2(void)
{
  Address = FLASH_USER_START_ADDR;
  MemoryProgramStatus = PASSED;
  
    flashpagenum = *(__IO uint32_t *)Address;
    Address = (((uint32_t)0x08006000)+(flashpagenum*FLASH_PAGE_SIZE));
    FLASH_USER_END_ADDR = (((uint32_t)0x08006400)+(flashpagenum*FLASH_PAGE_SIZE));
    if(flashpagenum>=230) Address=FLASH_USER_START_ADDR;
    
  while (Address < FLASH_USER_END_ADDR)
  {
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    writenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    timer = *(__IO uint32_t *)Address;
    Address = Address + 4;
    programma = *(__IO uint32_t *)Address;
    Address = Address + 4;
    power = *(__IO uint32_t *)Address;
    Address = Address + 4;
    melodiya = *(__IO uint32_t *)Address;
    Address = Address + 4;
            break;
  }
}

static void Writetoflash2(void)
{
  
    MemoryProgramStatus = PASSED;
    Address = FLASH_USER_START_ADDR;
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    FLASH_USER_START_ADDR = (((uint32_t)0x08006000)+(flashpagenum*FLASH_PAGE_SIZE));
    FLASH_USER_END_ADDR = (((uint32_t)0x08006400)+(flashpagenum*FLASH_PAGE_SIZE));
    
    writenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    writenum++;
    if(writenum>=900)
    {
      flashpagenum++;
      writenum=0;
    }
    
  // Unlock the Flash to enable the flash control register access 
  FLASH_Unlock();
    
  // Erase the user Flash area
   // (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  // Clear pending flags (if any)   
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); 

  // Define the number of page to be erased 
  NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;

  // Erase the FLASH pages 
  for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  {
    if (FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter))!= FLASH_COMPLETE)
    {
     // Error occurred while sector erase. 
        // User can add here some code to deal with this error  
      while (1)
      {
      }
    }
  }
  // Program the user Flash area word by word
    //(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  Address = FLASH_USER_START_ADDR;

  while (Address < FLASH_USER_END_ADDR)
  {
    if (FLASH_ProgramWord(Address, flashpagenum) == FLASH_COMPLETE)
    {
        Address = Address + 4;
        if (FLASH_ProgramWord(Address, writenum) == FLASH_COMPLETE)
        {
              Address = Address + 4;
              if (FLASH_ProgramWord(Address, timer) == FLASH_COMPLETE)
              {
                Address = Address + 4;
                if (FLASH_ProgramWord(Address, programma) == FLASH_COMPLETE)
                {
                  Address = Address + 4;
                  if (FLASH_ProgramWord(Address, power) == FLASH_COMPLETE)
                  {
                    Address = Address + 4;
                    if (FLASH_ProgramWord(Address, melodiya) == FLASH_COMPLETE)
                    {
                      Address = Address + 4;
                      break;
                    }
                  }
                }
              }
        }
    }
    else
    { 
      // Error occurred while writing data in Flash memory. 
        // User can add here some code to deal with this error 
      while (1)
      {
      }
    }
  }

}
После вызова функции записи зависает.
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Еще пробовал так, не зависает, но и не сохраняет:

Код: Выделить всё

  uint16_t VirtAddVarTab[NB_OF_VAR] = {0x5555, 0x6666, 0x7777};
  uint16_t VarDataTab[NB_OF_VAR] = {0, 0, 0};
  uint16_t VarValue = 0;
  
static void Writetoflash2(void)
{
  FLASH_Unlock();
  /* EEPROM Init */
  EE_Init();
  
  /* Store 0x1000 values of Variable1 in EEPROM */
  for (VarValue = 1; VarValue <= 0x64; VarValue++)
  {
    EE_WriteVariable(VirtAddVarTab[0], timer);
  }
}

static void flash_read2(void)
{
  /* read the last stored variables data*/
  EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
  timer = (unsigned int)&VarDataTab[0];
}
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

При чтении timer=0, а записываются от 1 до 9. 900 раз записывается в одну страницу в 1кБ, после чего увеличивается номер страницы на 1 и так до 230 раз.
Спойлер

Код: Выделить всё

 #define FLASH_PAGE_SIZE         ((uint32_t)0x00000400)   /* FLASH Page Size */
unsigned int FLASH_USER_START_ADDR = ((uint32_t)0x08006000);
unsigned int FLASH_USER_END_ADDR = ((uint32_t)0x08006400);

uint32_t EraseCounter = 0x00, Address = 0x00;
uint32_t NbrOfPage = 0x00;
__IO FLASH_Status FLASHStatus = FLASH_COMPLETE;
__IO TestStatus MemoryProgramStatus = PASSED;


static void Writetoflash2(void)
{
  
    MemoryProgramStatus = PASSED;
    Address = FLASH_USER_START_ADDR;
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    flashpagenum2=0;
    while(flashpagenum==0)
    {
      flashpagenum2++;
      if(flashpagenum2>=230) break;
      FLASH_USER_START_ADDR = (((uint32_t)0x08006000)+(flashpagenum2*FLASH_PAGE_SIZE));
      flashpagenum = *(__IO uint32_t *)FLASH_USER_START_ADDR;
    }
    FLASH_USER_START_ADDR = (((uint32_t)0x08006000)+(flashpagenum*FLASH_PAGE_SIZE));
    FLASH_USER_END_ADDR = (((uint32_t)0x08006400)+(flashpagenum*FLASH_PAGE_SIZE));
    Address = FLASH_USER_START_ADDR + 4;
    writenum = *(__IO uint32_t *)Address;
    Address = Address - 4;
    writenum++;
    if(writenum>=900)
    {
      goto ab;
      bc:
  // Unlock the Flash to enable the flash control register access 
  FLASH_Unlock();    
  // Erase the user Flash area
   // (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  // Clear pending flags (if any)   
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); 

  // Define the number of page to be erased 
  NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;

  // Erase the FLASH pages 
  for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  {
    if (FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter))!= FLASH_COMPLETE)
    {
     // Error occurred while sector erase. 
        // User can add here some code to deal with this error  
      while (1)
      {
      }
    }
  }
      if (FLASH_ProgramWord(Address, flashpagenum) == FLASH_COMPLETE)
      {
        flashpagenum++;
        writenum=0;
        FLASH_USER_START_ADDR = (((uint32_t)0x08006000)+(flashpagenum*FLASH_PAGE_SIZE));
        FLASH_USER_END_ADDR = (((uint32_t)0x08006400)+(flashpagenum*FLASH_PAGE_SIZE));
        goto cd;
      }
    }
    
  ab:
  // Unlock the Flash to enable the flash control register access 
  FLASH_Unlock();
    
  // Erase the user Flash area
   // (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  // Clear pending flags (if any)   
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); 

  // Define the number of page to be erased 
  NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;

  // Erase the FLASH pages 
  for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  {
    if (FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter))!= FLASH_COMPLETE)
    {
     // Error occurred while sector erase. 
        // User can add here some code to deal with this error  
      while (1)
      {
      }
    }
  }
  if(writenum>=900) goto bc;
  cd:
  // Program the user Flash area word by word
    //(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  Address = (((uint32_t)0x08006000)+(flashpagenum*FLASH_PAGE_SIZE));

  while (Address < FLASH_USER_END_ADDR)
  {
    if (FLASH_ProgramWord(Address, flashpagenum) == FLASH_COMPLETE)
    {
      Address = Address + 4;
        Address = Address + 4;
        if (FLASH_ProgramWord(Address, writenum) == FLASH_COMPLETE)
        {
              Address = Address + 4;
              if (FLASH_ProgramWord(Address, timer) == FLASH_COMPLETE)
              {
                Address = Address + 4;
                if (FLASH_ProgramWord(Address, programma) == FLASH_COMPLETE)
                {
                  Address = Address + 4;
                  if (FLASH_ProgramWord(Address, power) == FLASH_COMPLETE)
                  {
                    Address = Address + 4;
                    if (FLASH_ProgramWord(Address, melodiya) == FLASH_COMPLETE)
                    {
                      Address = Address + 4;
                      break;
                    }
                  }
                }
              }
        }
    }
    else
    { 
      // Error occurred while writing data in Flash memory. 
        // User can add here some code to deal with this error 
      while (1)
      {
      }
    }
  }
  // Lock the Flash to disable the flash control register access (recommended
   //  to protect the FLASH memory against possible unwanted operation) 
  FLASH_Lock();
}

 


static void flash_read2(void)
{
    MemoryProgramStatus = PASSED;
    Address = FLASH_USER_START_ADDR;
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    flashpagenum2=0;
    while(flashpagenum==0)
    {
      flashpagenum2++;
      if(flashpagenum2>=230) break;
      FLASH_USER_START_ADDR = (((uint32_t)0x08006000)+(flashpagenum2*FLASH_PAGE_SIZE));
      flashpagenum = *(__IO uint32_t *)FLASH_USER_START_ADDR;
    }
    FLASH_USER_START_ADDR = (((uint32_t)0x08006000)+(flashpagenum*FLASH_PAGE_SIZE));
    FLASH_USER_END_ADDR = (((uint32_t)0x08006400)+(flashpagenum*FLASH_PAGE_SIZE));
    Address = FLASH_USER_START_ADDR;

    
  while (Address < FLASH_USER_END_ADDR)
  {
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    writenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    timer = *(__IO uint32_t *)Address;
    Address = Address + 4;
    programma = *(__IO uint32_t *)Address;
    Address = Address + 4;
    power = *(__IO uint32_t *)Address;
    Address = Address + 4;
    melodiya = *(__IO uint32_t *)Address;
    Address = Address + 4;
            break;
  }
}
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Сделал запись постранично во FLASH так, 16кБ свободно, 16 занято прошивкой:
Спойлер

Код: Выделить всё

typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

 #define FLASH_PAGE_SIZE         ((uint32_t)0x00000400)   /* FLASH Page Size */

uint32_t EraseCounter = 0x00, Address = 0x00;
uint32_t NbrOfPage = 0x00;
__IO FLASH_Status FLASHStatus = FLASH_COMPLETE;
__IO TestStatus MemoryProgramStatus = PASSED;

static void Writetoflash2(void)
{
    int bc=0;
    MemoryProgramStatus = PASSED;
    Address = FLASH_USER_START_ADDR;
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    
    flashpagenum2=0;
    while(flashpagenum==0)
    {
      flashpagenum2++;
      if(flashpagenum2>=9) 
      {
        flashpagenum=1;
        writenum=0;
        FLASH_USER_START_ADDR = (((uint32_t)0x08005000)+(flashpagenum*FLASH_PAGE_SIZE));
        FLASH_USER_END_ADDR = (((uint32_t)0x08005400)+(flashpagenum*FLASH_PAGE_SIZE));
        Address = Address - 4;
        goto ab;
      }
      FLASH_USER_START_ADDR = (((uint32_t)0x08005000)+(flashpagenum2*FLASH_PAGE_SIZE));
      flashpagenum = *(__IO uint32_t *)FLASH_USER_START_ADDR;
    }
    FLASH_USER_START_ADDR = (((uint32_t)0x08005000)+(flashpagenum*FLASH_PAGE_SIZE));
    FLASH_USER_END_ADDR = (((uint32_t)0x08005400)+(flashpagenum*FLASH_PAGE_SIZE));
    Address = FLASH_USER_START_ADDR + 4;
    writenum = *(__IO uint32_t *)Address;
    Address = Address - 4;
    
    writenum++;
    if(writenum>=5)
    {
      goto ab;
      bc:
      if (FLASH_ProgramWord(Address, 0) == FLASH_COMPLETE)  //flashpagenum
      {
        Address = Address + 4;
        if (FLASH_ProgramWord(Address, 0) == FLASH_COMPLETE)  //writenum
        {
          flashpagenum++;
          Address = (((uint32_t)0x08005000)+(flashpagenum*FLASH_PAGE_SIZE));
          FLASH_USER_START_ADDR = (((uint32_t)0x08005000)+(flashpagenum*FLASH_PAGE_SIZE));
          FLASH_USER_END_ADDR = (((uint32_t)0x08005400)+(flashpagenum*FLASH_PAGE_SIZE));
          goto ab;
          dd:
          bc=0;
          writenum=0;
          goto cd;
        }
      }
    }
    
    //Address = FLASH_USER_START_ADDR;
  ab:
  // Unlock the Flash to enable the flash control register access 
  FLASH_Unlock();
    
  // Erase the user Flash area
   // (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  // Clear pending flags (if any)   
  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); 

  // Define the number of page to be erased 
  NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;

  // Erase the FLASH pages 
  for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  {
    if (FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter))!= FLASH_COMPLETE)
    {
     // Error occurred while sector erase. 
        // User can add here some code to deal with this error  
      while (1)
      {
      }
    }
  }
  if(writenum>=5) 
  {
    bc++;
    if(bc==1) goto bc;
    else  goto dd;
  }
  cd:
  // Program the user Flash area word by word
    //(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) 

  Address = (((uint32_t)0x08005000)+(flashpagenum*FLASH_PAGE_SIZE));

  while (Address < FLASH_USER_END_ADDR)
  {
    if (FLASH_ProgramWord(Address, flashpagenum) == FLASH_COMPLETE)
    {
      Address = Address + 4;
        if (FLASH_ProgramWord(Address, writenum) == FLASH_COMPLETE)
        {
          Address = Address + 4;
              if (FLASH_ProgramWord(Address, timer) == FLASH_COMPLETE)
              {
                Address = Address + 4;
                if (FLASH_ProgramWord(Address, programma) == FLASH_COMPLETE)
                {
                  Address = Address + 4;
                  if (FLASH_ProgramWord(Address, power) == FLASH_COMPLETE)
                  {
                    Address = Address + 4;
                    if (FLASH_ProgramWord(Address, melodiya) == FLASH_COMPLETE)
                    {
                      Address = Address + 4;
                      break;
                    }
                  }
                }
              }
        }
    }
    else
    { 
      // Error occurred while writing data in Flash memory. 
        // User can add here some code to deal with this error 
      while (1)
      {
      }
    }
  }
    // Lock the Flash to disable the flash control register access (recommended
   //  to protect the FLASH memory against possible unwanted operation) 
  FLASH_Lock(); 
}


static void flash_read2(void)
{
    MemoryProgramStatus = PASSED;
    Address = FLASH_USER_START_ADDR;
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    flashpagenum2=0;
    while(flashpagenum==0)
    {
      flashpagenum2++;
      if(flashpagenum2>=9) break;
      FLASH_USER_START_ADDR = (((uint32_t)0x08005000)+(flashpagenum2*FLASH_PAGE_SIZE));
      flashpagenum = *(__IO uint32_t *)FLASH_USER_START_ADDR;
    }
    FLASH_USER_START_ADDR = (((uint32_t)0x08005000)+(flashpagenum*FLASH_PAGE_SIZE));
    FLASH_USER_END_ADDR = (((uint32_t)0x08005400)+(flashpagenum*FLASH_PAGE_SIZE));
    Address = FLASH_USER_START_ADDR;
    
  while (Address < FLASH_USER_END_ADDR)
  {
    flashpagenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    writenum = *(__IO uint32_t *)Address;
    Address = Address + 4;
    timer = *(__IO uint32_t *)Address;
    Address = Address + 4;
    programma = *(__IO uint32_t *)Address;
    Address = Address + 4;
    power = *(__IO uint32_t *)Address;
    Address = Address + 4;
    melodiya = *(__IO uint32_t *)Address;
    Address = Address + 4;
            break;
  }
}
Теперь когда работает ШИМ от TIM14 слышен писк из звукоизлучателя, подключенного к TIM3, настроенного на ШИМ.
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Если закоментировать:
if (SysTick_Config(SystemCoreClock/2000-1))
{ while(1){;} }
перед while(1), то STM32 входит в спящий режим.
Если разкоментировать и перед WFE сделать:
SysTick->CTRL = 0; //disable systick
То STM32 не входит в спящий режим.

Как сделать, чтобы STM32 входил в спящий режим?

Если сделать:
if (SysTick_Config(0))
{ while(1){;} }
то в спящий режим входит, но по нажатию кнопки с пина РА0 не выходит из спящего режима.
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Необходимо сделать постоянным уровень напряжения 4В на пине VDDA у STM32F030F4P6, независимо от изменения уровня напряжения питания от 4,1В до 3,6В. Через делитель напряжения на STM32 подается 3,6В. Ставить стабилизатор TL431 и после транзистор, чтобы уровень напряжения был 4В. Или еще возможны варианты в корпусе SOT23.
a5021
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Re: STM32F030K6 настройка программы

Сообщение a5021 »

Вы никогда в даташит не заглядывали, на предмет, какие напряжения вообще допустимы для stm32f0xx ?
service47
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт мар 12, 2013 16:05:45

Re: STM32F030K6 настройка программы

Сообщение service47 »

Настроил АЦП с DMA на 2 канала (пины РА1, РА2). Вопрос как читать данные, записываемые по адресу ADC_array для каждого канала по отдельности.

Спойлер

Код: Выделить всё


#define NUMBER_OF_ADC_CHANNEL 2
uint16_t ADC_array[NUMBER_OF_ADC_CHANNEL]; //Array to store the values coming from the ADC and copied by DMA

void  ConfigureGPIO3(void)
{  
  /* (1) Enable the peripheral clock of GPIOA */
  /* (2) Select output mode (01) on GPIOA pin 1 and 2 */
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* (1) */  
  GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER1|GPIO_MODER_MODER2)) \
               | (GPIO_MODER_MODER1_0|GPIO_MODER_MODER2_0); /* (2) */  
}


void  ConfigureGPIOforADC3(void)
{
  /* (1) Enable the peripheral clock of GPIOA, GPIOB and GPIOC */
  /* (2) Select analog mode for PA1 */
  /* (3) Select analog mode for PA2 */
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* (1) */
  GPIOA->MODER |= GPIO_MODER_MODER1; /* (2) */
  GPIOA->MODER |= GPIO_MODER_MODER2; /* (3) */
}


void SetClockForADC3(void)
{
  /* (1) Enable the peripheral clock of the ADC */
  /* (2) Set peripheral prescaler to /2 so PCLK = HCLK/2 = 24MHz */ 
  RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; /* (1) */
  RCC->CFGR |= RCC_CFGR_PPRE_2; /* (2) */  
}


void  CalibrateADC3(void)
{
  /* (1) Ensure that ADEN = 0 */
  /* (2) Clear ADEN */ 
  /* (3) Launch the calibration by setting ADCAL */
  /* (4) Wait until ADCAL=0 */
  if ((ADC1->CR & ADC_CR_ADEN) != 0) /* (1) */
{
    ADC1->CR &= (uint32_t)(~ADC_CR_ADEN);  /* (2) */  
  }
  ADC1->CR |= ADC_CR_ADCAL; /* (3) */
  while ((ADC1->CR & ADC_CR_ADCAL) != 0) /* (4) */
  {
    /* For robust implementation, add here time-out management */
  }
}


/**
  * @brief  This function configures the ADC to convert sequentially 2 channels
            in continuous mode.
  *         The conversion frequency is 12MHz PCLK/2 and PCLK is 24MHz
  *         The interrupt on overrun is enabled and the NVIC is configured
  * @param  None
  * @retval None
  */
void ConfigureADC3(void)
{
  /* (1) Select PCLK/2 by writing 01 in CKMODE */ 
  /* (2) Select the continuous mode */
  /* (3) Select CHSEL1, CHSEL2 */
  /* (4) Select a sampling mode of 111 i.e. 239.5 ADC clk to be greater than 17.1us */
  /* (5) Enable interrupts on overrrun */
  /* (6) Wake-up the VREFINT (only for VBAT, Temp sensor and VRefInt) */
  ADC1->CFGR2 |= 0x40000000; //ADC_CFGR2_CKMODE_0; /* (1) */ 
  ADC1->CFGR1 |= ADC_CFGR1_CONT; /* (2)*/
  ADC1->CHSELR = ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL2; /* (3)*/
  ADC1->SMPR |= 0x7;//ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2; /* (4) */
  ADC1->IER = ADC_IER_OVRIE; /* (5) */
  ADC->CCR |= ADC_CCR_VREFEN; /* (6) */

  /* Configure NVIC for ADC */
  /* (7) Enable Interrupt on ADC */
  /* (8) Set priority for ADC */
  NVIC_EnableIRQ(ADC1_COMP_IRQn); /* (7) */
  NVIC_SetPriority(ADC1_COMP_IRQn,0); /* (8) */
}


/**
  * @brief  This function configures the DMA to store the result of an ADC sequence.
  *         The conversion results are stored in N-items array.
  * @param  None
  * @retval None
  */
void ConfigureDMA3(void)
{
  /* (1) Enable the peripheral clock on DMA */
  /* (2) Enable DMA transfer on ADC and circular mode */ 
  /* (3) Configure the peripheral data register address */ 
  /* (4) Configure the memory address */
  /* (5) Configure the number of DMA tranfer to be performs on DMA channel 1 */
  /* (6) Configure increment, size, interrupts and circular mode */
  /* (7) Enable DMA Channel 1 */
  RCC->AHBENR |= RCC_AHBENR_DMA1EN; /* (1) */
  ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG; /* (2) */
  DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); /* (3) */
  DMA1_Channel1->CMAR = (uint32_t)(ADC_array); /* (4) */
  DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNEL; /* (5) */
  DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 \
                      | DMA_CCR_TEIE | DMA_CCR_CIRC; /* (6) */  
  DMA1_Channel1->CCR |= DMA_CCR_EN; /* (7) */
 
  /* Configure NVIC for DMA */
  /* (8) Enable Interrupt on DMA */
  /* (9) Set priority for DMA */
  NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* (8) */
  NVIC_SetPriority(DMA1_Channel1_IRQn,0); /* (9) */
}


void EnableADC3(void)
{
  /* (1) Enable the ADC */
  /* (2) Wait until ADC ready */
  do 
  {
    /* For robust implementation, add here time-out management */
		ADC1->CR |= ADC_CR_ADEN; /* (1) */
  }while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) /* (2) */;
}


void DisableADC3(void)
{
  /* (1) Ensure that no conversion on going */
  /* (2) Stop any ongoing conversion */
  /* (3) Wait until ADSTP is reset by hardware i.e. conversion is stopped */
  /* (4) Disable the ADC */
  /* (5) Wait until the ADC is fully disabled */
  if ((ADC1->CR & ADC_CR_ADSTART) != 0) /* (1) */
  {
    ADC1->CR |= ADC_CR_ADSTP; /* (2) */
  }
  while ((ADC1->CR & ADC_CR_ADSTP) != 0) /* (3) */
  {
     /* For robust implementation, add here time-out management */
  }
  ADC1->CR |= ADC_CR_ADDIS; /* (4) */
  while ((ADC1->CR & ADC_CR_ADEN) != 0) /* (5) */
  {
    /* For robust implementation, add here time-out management */
  }  
}


void DMA1_Channel1_IRQHandler(void)
{
  if ((DMA1->ISR & DMA_ISR_TEIF1) != 0) /* Test if transfer error on DMA channel 1 */
  {
    //error |= ERROR_DMA_XFER; /* Report an error */
    DMA1->IFCR |= DMA_IFCR_CTEIF1; /* Clear the flag */
    adc0 = *(__IO uint32_t *)ADC_array;
  }
  else
  {
    //error |= ERROR_UNEXPECTED_DMA_IT; /* Report unexpected DMA interrupt occurrence */
  }
}

void ADC1_COMP_IRQHandler(void)
{
  if ((ADC1->ISR & ADC_ISR_OVR) != 0)  /* Check OVR has triggered the IT */
  {
    ADC1->ISR |= ADC_ISR_OVR; /* Clears the pending bit */
    //ADC1->CR |= ADC_CR_ADSTP; /* Stop the sequence conversion */
    //error |= ERROR_ADC_OVERRUN; /* Report an error */
  }
  else
  {
    //error |= ERROR_UNEXPECTED_ADC_IT; /* Report unexpected ADC interrupt occurrence */
  }
}

void main(void)
{

  ConfigureGPIO3();
  SetClockForADC3();
  CalibrateADC3(); 
  ConfigureGPIOforADC3();
  EnableADC3();
  ConfigureADC3();
  ConfigureDMA3();

  ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversions */

while (1)
  {
	//...
  }
}

Ответить

Вернуться в «ARM»