Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: stm32 I2C и прерывания

Ср окт 07, 2020 21:12:44

ivan dimir писал(а):Так что вы мне посоветуете ?.Что и какой бит установить?
Этот код
Спойлер
Код:
void TIM3_IRQHandler(void)
{
  /* USER CODE BEGIN TIM3_IRQn 0 */
   if(TIM3->SR & TIM_SR_UIF)
   {
      TIM3->SR &= ~ TIM_SR_UIF;
      pauza++;
    //  GPIOA->ODR^=GPIO_ODR_ODR3 ;
      //GPIOC->ODR|=GPIO_ODR_ODR13 ;
     // GPIOC->ODR|=GPIO_ODR_ODR13 ;
     // GPIOC->BSRR|= GPIO_BSRR_BS13;

     // if(!(LL_GPIO_ReadInputPort(GPIOB)&GPIO_IDR_IDR0))
      if(!(GPIOB->IDR&GPIO_IDR_IDR0))
       {

         //     LL_mDelay(10);
              flag=1;

         }

           //if(flag==1&&LL_GPIO_ReadInputPort(GPIOB)&GPIO_IDR_IDR0)
              if(flag==1&&GPIOB->IDR&GPIO_IDR_IDR0)
           {
             // LL_mDelay(10);
              flag=0;
              menu++;
             // program++;
           }
           if(menu==1)
           {
            if(pauza>60)
            {
             GPIOC->BSRR|= GPIO_BSRR_BS13;



             }
              if(pauza>100)
             {
             GPIOC->BSRR|= GPIO_BSRR_BR13;
             pauza=0;
             }
             // GPIOC->BSRR|= GPIO_BSRR_BR13;
              // I2C1->CR1|=I2C_CR1_PE;
            //  I2C1->CR1=0;
             // GPIOC->ODR|=GPIO_ODR_ODR3 ;
             // menu++;
          }
           if(menu==2)
           {
              menu=0;
           }
   //GPIOA->ODR^=GPIO_ODR_ODR3 ;
    //GPIOA->BSRR|= GPIO_BSRR_BS3;
   }

   //GPIOA->ODR^=GPIO_ODR_ODR3 ;
  /* USER CODE END TIM3_IRQn 0 */
  /* USER CODE BEGIN TIM3_IRQn 1 */

  /* USER CODE END TIM3_IRQn 1 */
}
не верен, его переписывать надо.
У вас хоть прерывание срабатывает? С прерыванием сами разберетесь.

И так имеем какую-то кнопку на порту GPIOB.0

Библиотека обработки кнопок (взята на просторах инета, меня устраивает) состоит из двух файлов
Спойлерbutton_lib.h
Код:
//#######################################################################################################################
//#
//# БИБЛИОТЕКА РАБОТЫ С КНОПКАМИ
//#
//#######################################################################################################################
 
#ifndef __BUTTON_LIB_INCLUDED__
#define __BUTTON_LIB_INCLUDED__

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"

   //настройки параметров библиотеки
   #define BTN_LOCK_TIME   50                  /* время обработки дребезга в милисекундах (10-100) */
   #define BTN_LONG_TIME   1000               /* время фиксации длинного нажатия в милисекундах (1000 - 2500) */
 
   //настройка портов и линий             
   #define BTN_PIN        GPIOB->IDR   /* порт кнопок */
      
      #define BTN_LINE1      GPIO_Pin_0   //(1<<0)            /* линии кнопок */
      //#define BTN_LINE2      (1<<1)
      //#define BTN_LINE3      (1<<2)
      //#define BTN_LINE4      (1<<3)                         

   //определения флагов кнопок
   #define BTN_SHRT1      (1<<0)               /* флаги короткого нажатия кнопок */
   //#define BTN_SHRT2      (1<<1)
   //#define BTN_SHRT3      (1<<2)
   //#define BTN_SHRT4      (1<<3)
   
   //#define BTN_LONG1      (1<<4)               /* флаги длинного нажатия кнопок */
   //#define BTN_LONG2      (1<<5)
   //#define BTN_LONG3      (1<<6)
   //#define BTN_LONG4      (1<<7)
 
 
   //объявления функций
   void BtnInit (void);   //инициализация библиотеки
   unsigned char BtnGet (void);   //функция чтения маски нажатой кнопки
   void BtnExe (void);      //функция циклического опроса кнопок (вызывать с частотой 100Гц, например из прерывания)

 
#endif /* __BUTTON_LIB_INCLUDED__ */

//#######################################################################################################################
//#
//# END
//#
//#######################################################################################################################
Спойлерbutton_lib.c
Код:
//#######################################################################################################################
//#
//# БИБЛИОТЕКА ОБРАБОТКИ НАЖАТИЙ КЛАВИШ
//#
//#######################################################################################################################

#include "button_lib.h"

//----------
//глобальные переменные
volatile unsigned char BtnFlags;                        //регистр флагов нажатых кнопок
 
 
//----------
//функция инициализации портов (вызвать перед использованием библиотеки)
void BtnInit (void)                             
{   

   RCC-> APB2ENR |=RCC_APB2ENR_IOPBEN;

   //Вывод GPIOB.0
    // настройка вывода PB0 на режим входа с подтягивающим резистором
    // не знаю как для F103, этот пример для F100    
   GPIOB->CRL &= ~GPIO_CRL_MODE0;      //очистить разряды MODE
   GPIOB->CRL &= ~GPIO_CRL_CNF0;       //очистить разряды CNF
   GPIOB->CRL |=  GPIO_CRL_CNF0_1;     //дискретный вход с подтягивающим резистором
   GPIOB->BSRR =  GPIO_BSRR_BS0;       //подтяжка к плюсу

}
 
 
//----------
//функция чтения маски нажатых кнопок 
//возвращает маску нажатых кнопок (биты 0-3 - коротк нажат, биты 4-7 - длинн нажат)
unsigned char BtnGet (void)                               
{   
   __disable_irq ();
    unsigned char temp = BtnFlags;
    BtnFlags = 0;
   __enable_irq ();
    return temp;
}
 
 
//----------
//функция циклического опроса кнопок (вызывать с частотой 100Гц, например в прерывании)
void BtnExe (void)                                 
{   
   static unsigned char BtnLockBit;                  //защелка (защита от дребезга)
   static unsigned char BtnLockCoun;                 //счетчик защелки (защита от дребезга)
   static unsigned char BtnLongCoun;                 //счетчик длинного нажатия
   static unsigned char BtnMascLast;                 //запомнить маску нажатой кнопки для анализа после отжатия кнопки

   //формирование маски нажатых кнопок
   unsigned char BtnMask = 0; 
   if (~BTN_PIN & BTN_LINE1)    BtnMask = BTN_SHRT1;
   //if (~BTN_PIN_F & BTN_LINE2)    BtnMask = BTN_SHRT2;
   //if (~BTN_PIN_F & BTN_LINE3)    BtnMask = BTN_SHRT3;
   //if (~BTN_PIN & BTN_LINE4)    BtnMask = BTN_SHRT4;

   //основной алгоритм обработки событий кнопки
   if (BtnMask){                               //клавиша нажата
      BtnMascLast = BtnMask;                  //запоминаем для использования после отпускания кнопки

      if (BtnLockCoun < (BTN_LOCK_TIME/10)){
         BtnLockCoun++;                      //обработка дребезга
         return;
      }

      BtnLockBit=1;                           //нажатие зафиксировано     
      if (BtnLongCoun >= (BTN_LONG_TIME/10))                               
         return;
      
      if (++BtnLongCoun >= (BTN_LONG_TIME/10))
         BtnFlags |= (BtnMask << 4);         //установка бита длинного нажатия (старшие 4 бита флагов ButtonByte)
   }

   else{                                       //клавиша отжата             
      if (BtnLockCoun){                       //обработка дребезга
         BtnLockCoun --;
         return;
      }

      if (! BtnLockBit)                        //отжатие зафиксировано
         return;

      BtnLockBit =0;
      if (BtnLongCoun < (BTN_LONG_TIME/10))
         BtnFlags |= BtnMascLast;            //установка бита короткого нажатия (младшие 4 бита флагов ButtonByte)
      
      BtnLongCoun = 0;
   }
}
 
 
//#######################################################################################################################
//#
//# THE END!
//#
//#######################################################################################################################
само прерывание
Спойлер
Код:
void TIM3_IRQHandler(void)   //частота 100Гц
{
  /* USER CODE BEGIN TIM3_IRQn 3 */
   if(TIM3->SR & TIM_SR_UIF)
   {
      TIM3->SR &= ~ TIM_SR_UIF;
     BtnExe();
   }
}
и кусок кода main
Спойлер
Код:
volatile uint8_t button;

BtnInit();

LCD_Clear();

  while (1)
  {

   button = BtnGet();            //читаем значение кнопок
   
        if (button == BTN_SHRT1) {   // кнопка
         menu++; 
         if(menu==2) menu=0;
         LCD_Clear();
      }

    if(menu==0)
     {
        LCD_SetPos(0,0);
        LCD_SendChar(0xA4);
        LCD_SendChar('a');
        LCD_SendChar(0x65);
        LCD_SendChar(0xE5);
        LCD_SendChar(0xC4);
    }

     if(menu==1)
     {
     if(a++>4095) a=0;
      
     LCD_SetPos(0,1);
     sprintf(bufer,"a= %4d",a);
     LCD_String(bufer);
    }

    /* USER CODE BEGIN 3 */
 }
Достаточно установленных бит?

Re: stm32 I2C и прерывания

Чт окт 08, 2020 20:41:05

Я понял что проблема в коде . И банально .Заменил volatile unsigned char menu=0,menu_k=0,flag=0; на uint8_t menu=0,menu_k=0,flag=0;И заработало.Спасибо.if(a++>4095) a=0;Я немного по другому пишу код if(menu_k==1)
{
if(!(GPIOC->IDR&GPIO_IDR_ID1))
{

if(a>4095)
{
a=0;
}
a++;
}
}
Ответить