Гхм. Соль/перец по вкусу 
Не надо делать мне как лучше, оставьте мне как хорошо
// настройки Option Bytes #ifdef NDEBUG # define STM_OB_RDP 0xAA55 # define STM_OB_USER 0xC03F # define STM_OB_WRP0 0x01FE #else # define STM_OB_RDP 0x55AA # define STM_OB_USER 0x807F # define STM_OB_WRP0 0x00FF #endif // NDEBUG
// включает защиту от записи и чтения
void flash_protect(void)
{
    // проверим, не было ли прошито раньше?
    if ( (OB->RDP == STM_OB_RDP)   &&
         (OB->USER == STM_OB_USER) &&
         (OB->WRP0 == STM_OB_WRP0)
       )
    {
        return;
    }
    if (FLASH->CR & FLASH_CR_LOCK)
    {
        FLASH->KEYR = FLASH_FKEY1;
        __DSB();
        FLASH->KEYR = FLASH_FKEY2;
        __DSB();
    }
    if (!(FLASH->CR & FLASH_CR_OPTWRE))
    {
        FLASH->OPTKEYR = FLASH_FKEY1;
        __DSB();
        FLASH->OPTKEYR = FLASH_FKEY2;
        __DSB();
    }
    while (FLASH->SR & FLASH_SR_BSY)
    {
        __ISB();
    }
    FLASH->CR |= FLASH_CR_OPTER;
    __DSB();
    FLASH->CR |= FLASH_CR_STRT;
    __DSB();
    while (FLASH->SR & FLASH_SR_BSY)
    {
        __ISB();
    }
    if (FLASH->SR & FLASH_SR_EOP)
    {
        FLASH->SR = FLASH_SR_EOP;
    }
    __DSB();
    FLASH->CR &= ~FLASH_CR_OPTER;
    __DSB();
    FLASH->CR |= FLASH_CR_OPTPG;
    __DSB();
    OB->RDP = STM_OB_RDP;
    __DSB();
    while (FLASH->SR & FLASH_SR_BSY)
    {
        __ISB();
    }
    FLASH->SR = FLASH_SR_EOP;
    __DSB();
    OB->USER = STM_OB_USER;
    __DSB();
    while (FLASH->SR & FLASH_SR_BSY)
    {
        __ISB();
    }
    FLASH->SR = FLASH_SR_EOP;
    __DSB();
    OB->WRP0 = STM_OB_WRP0;
    __DSB();
    while (FLASH->SR & FLASH_SR_BSY)
    {
        __ISB();
    }
    FLASH->SR = FLASH_SR_EOP;
    __DSB();
    FLASH->CR &= ~FLASH_CR_OPTPG;
    __DSB();
    FLASH->CR |= FLASH_CR_LOCK;
}