Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Дребезг кнопки pic12f1501

Чт мар 25, 2021 15:31:42

Имеется код, но при подключении питания немного помигивает, как убрать этот дребезг? может кто знает

RA0-вход
RA2-выход

Обработка срабатывания при нажатии в функции interrupt isr.

Проблема в том, что при подаче питания без нажатия кнопки еле еле помигивает на выходе светодиод. А должен формироваться шим-сигнал только по нажатию и ничего кроме него.

Код:
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <stdint.h>

#pragma config FOSC = INTOSC  //???????? ?????????? ?????????
#define _XTAL_FREQ 16000000      // Declare crystal frequency to be 16MHZ (for delay functions)
#pragma config WDTE = 00         //????????? ??????
//#pragma config LVP = OFF         // Low-Voltage Programming Enable (Low-voltage programming enabled)
//#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
/*#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = HI        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
*/
uint8_t countMode=0;            //????? ?????????? ??????
uint8_t reqChangeMode=0;        //????, ???????????? ????? ????????? ???????? ?????

void InitTimer2(void)           //??????? ????????? ??????? 2
{   
  //static uint8_t statButton;
  TOUTPS3 = 1; //Prescaler Out 10
  TOUTPS2 = 0;
  TOUTPS1 = 0;
  TOUTPS0 = 1;
  T2CKPS0 = 1;//Postcaler In 16
  T2CKPS1 = 0;
  PR2 = 0b01111100;     //???????????? ???????? ???????
  TMR2IE = 1;
  TMR2ON = 1;
}

void interrupt isr(void)
{
static uint8_t statButton;          //?????????? ????????? ??????
if(TMR2IE&&TMR2IF)                //???? ????? ?? ??????????
  {
    if (RA0)                      //???? ?????? ????????
  {
    statButton = ((statButton << 1)|0)&0x3;     //??????????? ???????? ?????????? 0
    } else                                      //?????
    {
    statButton = ((statButton << 1)|1)&0x3;     //????? 1
    }
    }
    if (statButton == 0b01)                     //????? ????????? ????????? ??????
    {
    countMode = (countMode+1)&0x3;              //????? ??????
    reqChangeMode = 1;                          //?????? ????????? ??????
    }
    TMR2IF = 0;
  }

/*
 *
 */
int main(int argc, char** argv) {

    ANSA2  = 0x00;       // Set ports as digital I/O, not analog input
    ANSA0 = 0x00;
   ADCON0 = 0x00;       // Shut off the A/D Converter
   TRISA0 = 1;       // GP0 input
    TRISA2 = 0;      // GP2 output
    PEIE = 1;
    GIE = 1;
    PWM1EN = 1;         //???????? ?????? PWM
    PWM1OE = 1;
    PWM1POL = 1;
    InitTimer2();       //????????? ?????? 2
   while(1)
   {
    LATAbits.LATA2 = 0;
    if (reqChangeMode) {        //???? ????????? ???????? ?????
    reqChangeMode = 0;          //???????? ?????????
    switch (countMode) {        //?????????? ????? ??????
    case 0:
    {
        PWM1DCH = 0x00;        //??? ????????
        PWM1DCL = 0x0;
        PWM1CON = 0xC0;
    }
    break;
    case 1:
    {
       PWM1DCH = 0x29;          //1/3 ????? ????????
       PWM1DCL = 0x80;
       PWM1CON = 0xC0;
    }
    break;
    case 2:
    {
       PWM1DCH = 0x53;         //2/3 ????? ????????
       PWM1DCL = 0x0;
       PWM1CON = 0xC0;
    }
    break;
    case 3:
    {
       PWM1DCH = 0x7C;        //?????? ?????????? 1
       PWM1DCL = 0xC0;
       PWM1CON = 0xC0;
    }   
    break;
    }   
    }
}
    }
Последний раз редактировалось Bondosha Чт мар 25, 2021 19:09:20, всего редактировалось 2 раз(а).

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 15:45:57

Что помигивает ? Какой дребезг ? ...
Весь Ваш код анализировать и вникать в его суть ? :facepalm:

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 15:53:05

Аlex, светодиод, который на выходе RA2 сразу при подаче питания еще до нажатия кнопки еле заметно мигает

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 17:10:34

А не должен ?

Добавлено after 58 seconds:
Ваше предложение звучит как претензия пользователя к разработчику.

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 17:15:02

Аlex, без нажатия кнопки не должен как бы, поэтому и спрашиваю тут как это исправить

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 17:21:07

Какой кнопки ? На клавиатуре ? На пульте от телека ? ....

Bondosha писал(а):поэтому и спрашиваю тут как это исправить
Спросите у автора этого кода. Он быстрей ответит на этот вопрос.

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 17:21:47

Аlex, на ножке RA0, хватит издеваться

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 17:31:21

Bondosha писал(а):на ножке RA0
Об этом мы должны догадаться ?

Bondosha писал(а):хватит издеваться
Кто издевается тут, так это Вы единственный.

Или Вы считаете, что Вам лень выкинуть всё г... из кода, оставив только то, что относится к вопросу, выложив это сюда, хорошо откомментировав и нормально, корректно, внятно задать вопрос; а нам ковыряться в этом г... не лень ? Анализируя всю логику этого г..кода, выискивая проблему ... При всём при этом, ещё догадываться, что у Вас там за сопли напаяны, что куда подключено, и т.д...

PS: Уважайте тех, к кому обращаетесь за помощью.

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 18:09:56

Аlex, ну извините, что мне казалось понятным, ибо там назначены только один вход и один выход, а оказалось нет

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 20:14:37

Так не включайте ШИМ до нажатия кнопки:
PWM1EN = 1; //???????? ?????? PWM

Добавлено after 53 minutes 54 seconds:
Еще не понятно зачем проверять нажатие кнопки в прерывании по переполнению таймера? Дребезг не так обычно фильтруют.

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 21:18:08

А как ? Не паузу же делать для основного цикла программы при обнаружении нажатия кнопки ? Именно в прерывании счётчик времени нажатия кнопки, и флаг отпускания кнопки ...

Добавлено after 12 minutes 37 seconds:
В прерывании срабатывает флаг отпуска кнопки, а счётчик времени нажатия оной считает . А в основном цикле уловив что флаг отпуска изменился, проверяем время нажатия , и думаем что делать дальше ...

Re: Дребезг кнопки pic12f1501

Чт мар 25, 2021 22:17:32

А кто мешает прерывание по смене уровня включить? Кто мешает запускать таймер когда надо только? Кто мешает в основном цикле считать без ожидания в конце концов?
Ну да ладно, у вас там ошибок предостаточно. Взять хотя бы это:
Код:

  TOUTPS3 
= 1; //Prescaler Out 10
  TOUTPS2 = 0;
  TOUTPS1 = 0;
  TOUTPS0 = 1;
  T2CKPS0 = 1;//Postcaler In 16
  T2CKPS1 = 0;
  PR2 = 0b01111100;     //???????????? ???????? ???????
 

С комментариями ну совсем не совпадает. Pre и post перепутали местами. Pre выствален в 1:4, а не 1:16 как написано у вас. Ну да ладно. Прерывание, форматирую только сразу в читаемый вид:
Код:

void interrupt isr
(void) {
  static uint8_t statButton;
  if (TMR2IE && TMR2IF) {
    if (RA0) {
      statButton = ((statButton << 1) | 0) & 0x3;
    } else {
      statButton = ((statButton << 1) | 1) & 0x3;
    }
  }
  if (statButton == 0b01) {
    countMode = (countMode + 1) & 0x3;
    reqChangeMode = 1;
  }
  TMR2IF = 0;
}

Ну во-первых ваш таймер с таким PR2 и делителями переполняется примерно раз в 1мс. Может для фильтра помех и достаточно, но для дребезга самой кнопки очень мало.
А во-вторых подумайте чему изначально у вас равно statButton? Если вы не инициализировали значение, то там будут нули изначально. Это Си, компилятор так сделает. Вы тут же впихнете туда 1 из-за не нажатой кнопки и тут же сработает условие statButton == 0b01.
Ну и плюс зачем вы дергаете постоянно в цикле LATA2 ? Не мешайте ШИМу работать.

Добавлено after 4 minutes 16 seconds:
Это если у вас кнопка к + прижимает при нажатии. Если к земле, то отпускания вы не ждете получается...

Добавлено after 5 minutes 12 seconds:
Можно как-то так на скорую руку если по вашему:
Код:

void interrupt isr
(void) {
  static 
uint8_t statButton;
  if (
TMR2IE && TMR2IF) {
    if (
RA0) {
      if (
statButton 255)
        
statButton++;
    } else {
      if (
statButton 0)
        
statButton--;
      if (
statButton >= 50) { // кнопка была нажата > ~51мс
        
countMode = (countMode 1) & 0x3;
        
reqChangeMode 1;
        
statButton 0// сбросим
      
}
    }
  }

  
TMR2IF 0;
}

Re: Дребезг кнопки pic12f1501

Пн мар 29, 2021 21:36:51

А как ? Не паузу же делать...

Нудануда, нужно бросить все ресурсы МК на бедную кнопку. Нужно наворотить кучу кода в прерываниях. Это по нашему, по-бразильски... :music:
А если кнопок несколько и их количество превышает количество пинов с внешними прерываниями? :tea:

Re: Дребезг кнопки pic12f1501

Вт мар 30, 2021 15:12:20

NStorm, благодарю, все пошло
Ответить