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

Кто любит RISC в жизни, заходим, не стесняемся.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

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 */
 }
Достаточно установленных бит?
Реклама
ivan dimir
Мучитель микросхем
Сообщения: 440
Зарегистрирован: Вс дек 29, 2019 08:05:21

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

Сообщение ivan dimir »

Я понял что проблема в коде . И банально .Заменил 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++;
}
}
Реклама
Ответить

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