Перейти к содержанию
    

Прошивка для китайского паяльника JDS 908

Давно хотел заняться программированием, но все как-то руки не доходили. А тут(пару тройку месяцев назад), как ни кстати, перестал работать мой паяльник. Если быть точнее, в нем перестала работать коррекция температуры.

Спойлер

 

Максимальная температура до которой он мог нагреть жала была примерно 260 градусов. Нагреватель проверял на аналогичном паяльнике - с ним все в порядке. Предположил, что проблема в прошивке. Поиск прошивки не дал результатов. Тогда я решил написать прошивку самостоятельно. 🙂

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

Данную тему решил создать с целью поиска старших наставников. Ну или может кто-то тоже захочет поучаствовать в этом проекте.

Спойлер

Схема паяльника

Schematic__2023-08-20.thumb.png.1261a9feb2e95dd9305d9b67f14bbf57.png

Разъем для программирования

.thumb.png.fa4cc5db9292db967ca0e3c7647e88c3.png

Таблица выводов для ЖКИ

.thumb.jpg.342529b2094c5cbd981a0c31cb0c210c.jpg

 

 

 

Спойлер

Фото платы паяльника

2.thumb.png.70bf4e6c1d706404745afdc2d6cd32dc.png

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Теперь, после того, как получилось выводить цифры и буквы, нужно написать функцию для вывода цифр и текста (если подразумевается текст).

Допустим, выводиться будут только цифры. Следовательно, нужна универсальная функция, на вход которой будет приходить число, которое будет раскладываться на три разряда (по числу разрядов на индикаторе) и эти три цифры должны передаваться в знакогенератор для получения списка зажигаемых сегментов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 minutes ago, EdgeAligned said:

Допустим, выводиться будут только цифры. 

Егг , On , OFF, SЕt... 🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 10/5/2023 at 5:43 PM, Pjatruha said:

Если быть точнее, в нем перестала работать коррекция температуры.

Чем температура измеряется ?

Может в датчике проблема ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, EdgeAligned сказал:

нужно написать функцию для вывода цифр

По идее это не сложно. По-моему мы в школе(или это было в институте - не помню 🤔) что-то подобное дали. Попробую написать.

2 часа назад, dimka76 сказал:

Чем температура измеряется ?

Может в датчике проблема ?

Как такового датчика температуры нет. Сам нагреватель и есть датчик(если так можно его назвать). При нагреве его сопротивление изменяется.

Изменено пользователем Pjatruha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 часов назад, Pjatruha сказал:

Максимальная температура до которой он мог нагреть жала была примерно 260 градусов. Нагреватель проверял на аналогичном паяльнике - с ним все в порядке. Предположил, что проблема в прошивке.

Странный вывод.... Думаете прошивка поизносилась со временем? :biggrin:

Если со временем какие-то параметры цифро-аналоговой системы постепенно уходят, то очевидно проблему нужно искать в её аналоговой части.

9 часов назад, Pjatruha сказал:

Как такового датчика температуры нет. Сам нагреватель и есть датчик(если так можно его назвать). При нагреве его сопротивление изменяется.

Т.е. - если со временем этот нагреватель выгорает, то сопротивление его соответственно должно расти (при той же температуре) и соответственно - отключаться он должен раньше (недогревать). Вот и наиболее вероятная причина недогрева вашего паяльника.

В качестве коррекции можно попробовать включить параллельно нагревателю корректирующее сопротивление. Это будет быстрее и эффективнее переписывания прошивки...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 минут назад, jcxz сказал:

Думаете прошивка поизносилась со временем?

Возможно проблема в самом МК, т.к не сохраняются корректировки температуры. И кстати, по работе(занимаюсь в том числе установкой ПО на промышленное оборудование) очень часто встречался с тем, что банальная перепрошивка даже той же самой версии решает проблему неисправности оборудования.

27 минут назад, jcxz сказал:

Т.е. - если со временем этот нагреватель выгорает, то сопротивление его соответственно должно расти (при той же температуре) и соответственно - отключаться он должен раньше (недогревать). Вот и наиболее вероятная причина недогрева вашего паяльника

Нагреватель проверял на аналогичном паяльнике - все в порядке. При комнатной температуре сопротивления обоих нагревателей одинаково. Также ставил нагреватель с нового паяльника в старый/неисправный - паяльник так же не догревал и температуру скорректировать не получалось.

А вообще основная цель - научиться немного программировать. Паяльник стал толчком к этому.

 

Изменено пользователем Pjatruha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 05.10.2023 в 21:35, EdgeAligned сказал:

написать функцию для вывода цифр и текста

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

Спойлер
Спойлер
Цитата
#include "IOSTM8S103F3.h"
volatile int x=0, y=260, m=0;
volatile char i=1,j=0,n=0,k=1,L_1,L_2,L_3;
char ZNAK[8] =
{           //0 1  2 3  4 5  6 7
            //1 2  3 4  5 6  7 8
	    //12   11   10   09
             1,0, 1,0, 1,0, 0,1 //7
};

char DIGIT[11][2][8] = 
{
  {       // 0
    //1 2  3 4  5 6  7 8
    //12   11   10   09
      {0,1, 0,1, 0,1, 1,0}, //7 (0)
      {0,1, 1,0, 0,1, 0,1}  //t (1)
  },
  {       // 1
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {1,0, 0,1, 0,1, 1,0}, //7 (0)
     {1,0, 1,0, 1,0, 1,0}  //t (1)
  },
  {       // 2
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 0,1, 1,0, 1,0}, //7 (0)
     {1,0, 0,1, 0,1, 0,1}  //t (1)
  },
  {       // 3
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 0,1, 0,1, 1,0}, //7 (0)
     {1,0, 0,1, 1,0, 0,1}  //t (1)
  },
  {       // 4
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {1,0, 0,1, 0,1, 1,0}, //7 (0)
     {0,1, 0,1, 1,0, 1,0}  //t (1)
  },
  {       // 5
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 1,0, 0,1, 1,0}, //7 (0)
     {0,1, 0,1, 1,0, 0,1} //t (1)
  },
  {       // 6
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 1,0, 0,1, 1,0}, //7 (1)
     {0,1, 0,1, 0,1, 0,1}  //t (0)
  },
  {       // 7
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 0,1, 0,1, 1,0}, //7 (0)
     {1,0, 1,0, 1,0, 1,0}  //t (1)
  },
  {       // 8
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 0,1, 0,1, 1,0}, //7 (0)
     {0,1, 0,1, 0,1, 0,1}  //t (1)
  },
  {       // 9
    //0 1  2 3  4 5  6 7
    //1 2  3 4  5 6  7 8
    //12   11   10   09
     {0,1, 0,1, 0,1, 1,0}, //7 (0)
     {0,1, 0,1, 1,0, 0,1}  //t (1)
  },
  {  // PUSTO
   {1,0, 1,0, 1,0, 1,0}, //13 (0)
   {1,0, 1,0, 1,0, 1,0} //14 (1)
  },
};

void DELENIE()
{
  L_3=y/100;
  L_2=(y-(L_3*100))/10; //260-2*100=60
  L_1=(y-(L_3*100))-(L_2*10); //(260-(2*100))-(6*10) 
}

#pragma vector=TIM1_OVR_UIF_vector
 __interrupt void TIM1_interrupt(void) 
{
    TIM1_SR1_bit.UIF = 0; //Cброс флага прерывания
 k++;
 if (k == 9)
 {
   k=1;
 }
 j=k-1;
 
 if (m > 0)
 {
   m++;
   if (m >= 250)
   {
     if ((PD_IDR_bit.IDR1 == 1) & (PB_IDR_bit.IDR4 == 1))
     {
       m = -250;
     }
   }
 }
 
 if (m < 0)
 {
   m++;
   if (m == -1)
   {
       m = 0;
       PB_CR2_bit.C24 = 1; // разрещаем прерывание
       PD_CR2_bit.C21 = 1; // разрещаем прерывание
   }
 }
}

#pragma vector=EXTI1_vector //Кнопка "+"
 __interrupt void PinB4_interrupt(void)
 {
   PB_CR2_bit.C24 = 0; // запрещаем прерывание
   PD_CR2_bit.C21 = 0; // запрещаем прерывание
   m=1;
   y=y+5;
   if (y >= 500)
   {
     y=500;
   }
   DELENIE();
 }
 
 #pragma vector=EXTI3_vector //Кнопка "-"
 __interrupt void PinD2_interrupt(void)
 {
   PB_CR2_bit.C24 = 0; // запрещаем прерывание
   PD_CR2_bit.C21 = 0; // запрещаем прерывание
   m=1;
   y=y-5;
   if (y <= 100)
   {
     y=100;
   }
   DELENIE();
 }

void com_D12()
{
   if (PC_DDR_bit.DDR3 == 1)
     {
        PC_DDR_bit.DDR3 = 0; // Вход com D9
        PC_CR1_bit.C13 = 0; // Подтягивающий резистор отключен
     }
      
   PC_DDR_bit.DDR6 = 1; // Выход com D12
   PC_ODR_bit.ODR6 = 1; // Высокий уровень на выходе
   PC_CR1_bit.C16 = 1; // push-pull
}

void com_D12_()
{
      PC_ODR_bit.ODR6 = 0; // Низкий уровень на выходе com D12
}

void com_D11()
{
   PC_DDR_bit.DDR5 = 1; // Выход com D11
   PC_ODR_bit.ODR5 = 1; // Высокий уровень на выходе
   PC_CR1_bit.C15 = 1; // push-pull
   
   PC_DDR_bit.DDR6 = 0; // Вход com D12
   PC_CR1_bit.C16 = 0; // Подтягивающий резистор отключен
}

void com_D11_()
{
   PC_ODR_bit.ODR5 = 0; // Низкий уровень на выходе com D11
}

void com_D10()
{
   PC_DDR_bit.DDR4 = 1; // Выход com D10
   PC_ODR_bit.ODR4 = 1; // Высокий уровень на выходе
   PC_CR1_bit.C14 = 1; // push-pull
   
   PC_DDR_bit.DDR5 = 0; // Вход com D11
   PC_CR1_bit.C15 = 0; // Подтягивающий резистор отключен
}

void com_D10_()
{
   PC_ODR_bit.ODR4 = 0; // Низкий уровень на выходе com D10
}

void com_D9()
{
   PC_DDR_bit.DDR3 = 1; // Выход com D9
   PC_ODR_bit.ODR3 = 1; // Высокий уровень на выходе
   PC_CR1_bit.C13 = 1; // push-pull
      
   PC_DDR_bit.DDR4 = 0; // Вход com D10
   PC_CR1_bit.C14 = 0; // Подтягивающий резистор отключен
}

void com_D9_()
{
   PC_ODR_bit.ODR3 = 0; // Низкий уровень на выходе com D9
}

void COM()
{
  switch(k)
    {
      case 1:
        com_D12();
        break;			
      case 2:
        com_D12_();
        break;
        
      case 3:
        com_D11();
        break;
      case 4:
        com_D11_();
        break;
        
      case 5:
        com_D10();
        break;
      case 6:
        com_D10_();
        break;
        
      case 7:
        com_D9();
        break;
      case 8:
        com_D9_();
        break;
    }
}

void SEG()
{
//   DIGIT_1
     i=!i;
     if (n == 1)
     {
       if ((j == 7) ^ (j == 6))
       {
       PD_ODR_bit.ODR2 = ZNAK[j]; // Фаренгейт
       }
     }
     else
     {
       PD_ODR_bit.ODR2 = DIGIT[L_1][i][j]; // seg D14
     }
     i=!i;
     PC_ODR_bit.ODR7 = DIGIT[L_1][i][j]; // seg D13
     
//   DIGIT_2
     i=!i;
     if (n ==2)
     {
       if ((j == 7) ^ (j == 6))
       {
       PD_ODR_bit.ODR6 = ZNAK[j]; // Вилка
       }
     }
     else
     {
     PD_ODR_bit.ODR6 = DIGIT[L_2][i][j]; // seg D5
     }
     i=!i;
     PA_ODR_bit.ODR1 = DIGIT[L_2][i][j]; // seg D6

//   DIGIT_3
        i=!i;
        if (n == 3)
     {
       if ((j == 7) ^ (j == 6))
       {
       PA_ODR_bit.ODR3 = ZNAK[j]; // Цельсий
       }
     }
     else
     {
     PA_ODR_bit.ODR3 = DIGIT[L_3][i][j]; // seg D8
     }
     i=!i;
     PA_ODR_bit.ODR2 = DIGIT[L_3][i][j]; // seg D7
}

int main (void) 
{ 
   PB_DDR_bit.DDR4 = 0; // Вход. Кнопка "+"
   PB_CR1_bit.C14 = 0; //  Подтягивающий резистор отключен
   PB_CR2_bit.C24 = 1; // Прерывая разрещены
   EXTI_CR1_bit.PBIS = 3; //прерывание по спаду фронта
   
   PD_DDR_bit.DDR1 = 0; // Вход. Кнопка "-"
   PD_CR1_bit.C11 = 1; //  Подтягивающий резистор подключен
   PD_CR2_bit.C21 = 1; // Прерывая разрещены
   EXTI_CR1_bit.PDIS = 3; //прерывание по спаду фронта
  
   PC_DDR_bit.DDR3 = 0; // Вход com D9
   PC_CR1_bit.C13 = 0; // Подтягивающий резистор отключен
   PC_CR2_bit.C23 = 0; // Прерывая запрещены   
      
   PC_DDR_bit.DDR4 = 0; // Вход com D10
   PC_CR1_bit.C14 = 0; // Подтягивающий резистор отключен
   PC_CR2_bit.C24 = 0; // Прерывая запрещены 
   
   PC_DDR_bit.DDR5 = 0; // Вход com D11
   PC_CR1_bit.C15 = 0; // Подтягивающий резистор отключен
   PC_CR2_bit.C25 = 0; // Прерывая запрещены 
   
   PC_DDR_bit.DDR6 = 0; // Вход com D12
   PC_CR1_bit.C16 = 0; // Подтягивающий резистор отключен
   PC_CR2_bit.C26 = 0; // Прерывая запрещены
        
   PC_DDR_bit.DDR7 = 1; // Выход SEG D13
   PC_CR1_bit.C17 = 1; // push-pull
   PC_CR2_bit.C27 = 0; // Cкорость переключения 2МГц
   
   PD_DDR_bit.DDR2 = 1; // Выход SEG D14
   PD_CR1_bit.C12 = 1;
   PD_CR2_bit.C22 = 0;
  
   PD_DDR_bit.DDR6 = 1; // Выход SEG D5
   PD_CR1_bit.C16 = 1;  
   PD_CR2_bit.C26 = 0;
  
   PA_DDR_bit.DDR1 = 1; // Выход SEG D6
   PA_CR1_bit.C11 = 1; 
   PA_CR2_bit.C21 = 0;
  
   PA_DDR_bit.DDR2 = 1; // Выход SEG D7
   PA_CR1_bit.C12 = 1; 
   PA_CR2_bit.C22 = 0;
   
   PA_DDR_bit.DDR3 = 1; // Выход SEG D8
   PA_CR1_bit.C13 = 1; 
   PA_CR2_bit.C23 = 0;
   
   PB_DDR_bit.DDR5 = 1; // Настройка 5-го бита порта B на вывод.
   PB_ODR_bit.ODR5 = 1; // Гашение светодиода.
   PB_CR1_bit.C15 = 1; // Переключение порта в режим push-pull. 
   PB_CR2_bit.C25 = 0; // Cкорость переключения до 2 МГц
   
   //Частота переполнений = 2000000Гц / 4 / 500 = 1000 Гц(1 мс)
  TIM1_PSCRH = 0x00;//записываем 2 старших байта числа 3(4-1) в hex формате в регистр предделителя
  TIM1_PSCRL = 0x03;//записываем 2 младших байта числа 3(4-1)в hex формате в регистр предделителя
  TIM1_ARRH = 0x01; //записываем 2 старших байта числа 500 в hex формате в регистр автоперезагруски
  TIM1_ARRL = 0xF4; //записываем 2 младших байта числа 500 в hex формате в регистр автоперезагруски

  TIM1_CR1_bit.DIR = 0; // Cчет вверх
  TIM1_CR1_bit.URS = 1; //Прерывание только по переполнению счетчика
  TIM1_EGR_bit.UG = 1;  //Вызываем Update Event для загрузки предделителя

  TIM1_IER_bit.UIE = 1; //Разрешаем прерывание
  TIM1_CR1_bit.CEN = 1; //Запускаем таймер

  asm("rim");
  DELENIE();
  while(1)
  {
    COM();
    SEG();
  }
}

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, дребезг в самом простейшем случае можно подавить, сделав опрос состояния кнопок по циклическому таймеру, работающему с периодом 5 - 20 мс. И в прерывании таймера сравнивается текущее состояние входов с предыдущим из прошлого интервала, и если есть различия, значит, кнопка была нажата или отпущена. По этому факту выставляется флаг события, а в общем цикле он проверяется, и уже в общем цикле будут выполняться какие-либо действия непосредственно с инкрементом или декрементом числа.

Как правило, дребезг кнопки прекращается в течение максимум 20 мс, а зачастую и меньше. Поэтому, опрос состояния кнопок через интервал 20 мс будет фиксировать переход состояния. Бывают и другие способы с интегрирующим счетчиком, который прибавляет или убавляет переменную в зависимости от состояния входа кнопки, и когда переменная достигает порогового значения, фиксируется факт смены состояния.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, EdgeAligned сказал:

сделав опрос состояния кнопок по циклическому таймер

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такой метод тоже используется, но в основном в случаях, когда между нажатиями кнопок микроконтроллер находится в режиме пониженного энергопотребления. Например, некий пульт дистанционного управления, питаемый от батареек. 

В основном цикле программы мониторится не сама кнопка, а лишь флаг события от кнопки, а сама кнопка читается и определяется ее состояние в обработчике прерывания таймера. Поэтому, если нет этого флага, то в основном цикле операция от кнопок будет пропущена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...