STC15W408AS MCU White Light T12 Controller

Publisher:温馨幸福Latest update time:2020-11-25 Source: 51heiKeywords:STC15W408AS Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

I designed and made the stc white light by myself, with the schematic diagram, perforated board wiring diagram and source code attached.
Only simple temperature control is implemented. Short press the encoder to quickly set the temperature to 300℃, double click the encoder to quickly set it to 10℃ (equivalent to short sleep)












The code comments are very detailed and suitable for beginners to learn.

The microcontroller source program is as follows:

/**

A sky full of stars Written by CZS

*/

#include <STC15.h>

#include

#include


sbit t12 = P3 ^ 7; //T12 control

sbit encoderb = P1 ^ 0; // encoder b pin

sbit encodera = P1 ^ 1; // encoder pin a

sbit encoderd = P1 ^ 2; // encoder key d pin

sbit DIO = P3 ^ 3; // TM1650 digital tube driver sda pin

sbit CLK = P3 ^ 2; // TM1650 digital tube driver scl pin

sbit DO = P5 ^ 5; //DS18B20 data pin

unsigned long VREF = 2390; // Use a multimeter to measure the true value of the reference voltage, in mv


bit lastb = 0;

bit lasta = 0;

unsigned short push_last_time = 0; //Record the time the encoder button is pressed, short press and long press


unsigned long t12_voltage; // Calculate t12 thermocouple voltage

unsigned long system_voltage; // Calculate the microcontroller supply voltage

unsigned long input_voltage; // Calculate the input voltage of the entire board (12~24V)


//PID control algorithm

#define KP 1.2f // proportional coefficient

#define KI 0.2f // Integral coefficient

#define KD 0.1f // differential coefficient

#define MAX_UK 400.0f // The maximum control amount allowed by the system, here expressed as the number of heatings, 400 0.5ms heating cycles, and the longest continuous heating time is 200ms


int ek = 0, ek_1 = 0, ek_2 = 0; // Record three consecutive deviation values ​​(set value - actual measured value)

float uk_1 = 0.0f, uk = 0.0f; // Record the currently calculated PID adjustment value and the last calculated PID adjustment value

long integralSum = 0; // Cumulative integral term of position PID algorithm


// Define a digital tube segment code table, 0~F

unsigned char CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0X7C, 0X39, 0X5E, 0X79, 0X71};


unsigned int t12SetTemperature = 10; // Record the current set temperature

unsigned int t12ActualTemperature = 0; // Save the current actual temperature of T12

bit isChangeTemperature = 0; // Mark whether the set temperature has been changed

unsigned int setTempShowTime = 0; // Record the duration of displaying the set temperature


unsigned int need_heat_time = 0; // Duration of heating required

unsigned int heat_time_count = 0; //Current heating time

unsigned int actualTempShowTime = 250; //Set the display time of the current temperature to avoid the digital tube jumping due to too fast temperature collection


/*Delay function, automatically generated by STC-ISP, more accurate*/

void Delay_ms(unsigned int k) //@12.000MHz

{

  unsigned char i, j;

  for (; k > 0; k--)

  {

    i = 12;

    j = 169;

    do

    {

      while (--j)

        ;

    } while (--i);

  }

}


void Delay_us(unsigned int i)

{

  for (; i > 0; i--)

  {

    _nop_();

    _nop_();

    _nop_();

    _nop_();

  }

}


// Initialize each IO port

void initIO()

{

  //Configure the input mode of each port, M1M0: 00 normal, 01 push-pull, 10 high impedance input, 11 open drain

  /*

        The following lists the ports that need to be configured, and other ports can remain default

        t12 = P3^7; //T12 controls push-pull output mode

        ADC3: System input voltage detection P1^3 input mode

        ADC4: T12 thermocouple voltage detection P1^4 input mode

        ADC5: 2.5V reference voltage input P1^5 Input mode

        */


  //P1M0 |= 0x00; //0000 0000

  P1M1 |= 0x38; //0011 1000


  P3M0 = 0x80; //1000 0000

  P3M1 = 0x00; //0000 0000

}


/*Initialize ADC*/

void initADC(void)

{

  /*

        Enable the analog input function of the corresponding ADC port (corresponding position 1)

        ADC3: System input voltage detection P1^3

        ADC4: T12 thermocouple voltage detection P1^4

        ADC5: 2.5V reference voltage input P1^5

        */

  P1ASF = 0x38; //0011 1000

  ADC_RES = 0; // Clear result register

  ADC_RESL = 0;

  /*

        ADC Control Register

        ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0

        */

  // When initializing here, you can turn on the power and set the conversion speed

  ADC_CONTR = 0x80; // 1000 0000

  Delay_ms(5); // Delay and wait for a while after power on

}


// Turn off the ADC power supply and enable it when entering idle (sleep) mode to reduce power consumption

void closeADC(void)

{

  /*

        ADC Control Register

        ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0

        */

  ADC_CONTR = 0x00;

}


// Direct insertion sort

void insertionSort(unsigned int A[], unsigned int n)

{

  unsigned int i, j;

  for (i = 1; i < n; i++)

  {

    for (j = i; j > 0; j--)

    {

      if (A[j] < A[j - 1])

      {

        // Do not use a third variable to swap two numbers, using XOR operation is fast

        A[j - 1] ^= A[j];

        A[j] ^= A[j - 1];

        A[j - 1] ^= A[j];

      }

    }

  }

}


#define ADC_FLAG 0x10 // ADC conversion completed flag

#define ADC_START 0x08 //ADC starts setting

// Get the conversion value of an ADC channel

// To improve the accuracy of the results, measure 5 times each time, remove the highest value and the lowest value, and finally take the average of the middle 3 and return it

unsigned int getADCResult(unsigned int channel)

{

  unsigned int res[5], i, result = 0;

  for (i = 0; i < 5; i++)

  {

    /*

        ADC Control Register

        ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0

        */

    ADC_CONTR = (0x80 | channel | ADC_START); // Select the channel to be read and start the conversion

    Delay_us(1);

    while (!(ADC_CONTR & ADC_FLAG))

      ; //Wait for ADC conversion to complete

    res[i] = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // Calculate the original result of the conversion

    ADC_RES = 0x00;

    ADC_RESL = 0x00; // Clear result register

  }

  // Sort the results

  insertionSort(res, 5);

  // Remove the highest value, remove the lowest value, and find the average of the remaining three

  result = (res[1] + res[2] + res[3]) / 3;

  return result;

}

/*The following are functions for calculating various voltages. The units of the returned results are all mv*/

// Calculation formula (mv) output_voltage = (TL431 reference voltage value measured by VREF multimeter (mv) * ADC value of the channel to be measured / ADC value of TL431 reference channel)

// Calculate and obtain the voltage of T12

void getT12Voltage(void)

{

  t12_voltage = (VREF * getADCResult(4) / getADCResult(5)); //Calculate t12 voltage, unit: mV

}


// Calculate and obtain the power supply voltage of the microcontroller

void getSystemVoltage(void)

{

  system_voltage = (VREF * 1024 / getADCResult(5)); //Calculate the power supply voltage of the MCU, in mV;

}


// Calculate the input power supply voltage

void getInputVoltage(void)

{

  input_voltage = (VREF * getADCResult(3) / getADCResult(5) * 11); // Calculate the voltage at the lower voltage divider resistor point and multiply it by the voltage divider ratio to get the actual input voltage

}


/* Calculate T12 thermocouple temperature*/

void getT12Temperature(void)

{

  float x = 0.0f;

  t12 = 0; //When measuring temperature, turn off the soldering iron

  Delay_us(10); // Wait for a while, and measure the temperature more accurately after the capacitor is fully discharged

  getT12Voltage(); // Update T12 thermocouple voltage

                   //T12 actual temperature = (ADC voltage (mV) - offset voltage (mV)) / op amp gain * thermocouple graduation value (℃/mV) + room temperature (℃)

                   //t12Temp = 1.0f*getT12Voltage() / 231.0f * 54.0f + 23.0f;


  // The interpolation function calculates the T12 temperature. The above calculation is not accurate enough. I measured the relationship between the t12 temperature and the thermocouple electromotive force and used the formula fitted by matlab

  x = 1.0f * t12_voltage / 231.0f;

  x = -0.9f * x * x + 48.0f * x + 22.0f;

  t12ActualTemperature = (unsigned int)x;

}


/*

// Incremental PID control algorithm. This algorithm has poor effect on temperature control. It took a long time to adjust the parameters, but it is not very ideal.

// Input the set temperature and current temperature

// Return the current heating time

void incrementalPID(unsigned int setTemperature, unsigned int actualTemperature)

{

  float delta_uk = 0.0f; // used to calculate PID increment value

  uk_1 = uk; // Record the last calculated PID adjustment value

  ek_2 = ek_1; // Record the deviation value calculated last time

  ek_1 = ek; // Record the deviation value calculated last time

  ek = setTemperature - actualTemperature; // Calculate the current deviation value

  if (ek < 0)

  {

    // If the actual temperature is higher than the set temperature, heating will not be performed

    need_heat_time = 0;

    return;

  }

  if (abs(ek) > 100)

  {

    // If the temperature difference is greater than 100°C, the system will be dynamically accelerated. Regardless of whether the proportional term is positive or negative, it will be a positive number.

    delta_uk = KP * abs(ek - ek_1) + KI * ek + KD * (ek - 2 * ek_1 + ek_2); // Calculate PID increment value

  }

  else

  {

    // When approaching the target temperature, perform normal adjustment

    delta_uk = KP * (ek - ek_1) + KI * ek + KD * (ek - 2 * ek_1 + ek_2); // Calculate PID increment value

  }

  uk = uk_1 + delta_uk; // Calculate the current PWM value that should be output

  // Determine whether it exceeds the boundary range of the system control quantity. If it exceeds, assign the value to the boundary

  if (uk < 1e-9)

  {

    uk = 0.0f;

  }

  if (uk > MAX_UK)

  {

    uk = MAX_UK;

  }

  need_heat_time = (unsigned int)uk;

}

*/


// Position PID control algorithm, this control algorithm runs ideally

void positionalPID(unsigned int setTemperature, unsigned int actualTemperature)

{

  ek_1 = ek; // Record the deviation value calculated last time

  ek = setTemperature - actualTemperature; // Calculate the current deviation value

[1] [2]
Keywords:STC15W408AS Reference address:STC15W408AS MCU White Light T12 Controller

Previous article:Assembly language program debugging of LED light controller based on C8051F310 single chip microcomputer
Next article:51 single chip simple waveform generator (sine wave, sawtooth wave, triangle wave)

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号