找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 23820|回復(fù): 47
打印 上一主題 下一主題
收起左側(cè)

STC15W408AS單片機(jī)白光T12控制器,附帶原理圖和源代碼

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:520235 發(fā)表于 2020-11-25 09:27 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
自己設(shè)計(jì)和制作的stc白光,附上原理圖,洞洞板走線圖和源代碼。
只實(shí)現(xiàn)了簡(jiǎn)單的溫控,短按一下編碼器快速設(shè)定溫度為300℃,雙擊一下編碼器快速設(shè)定為10℃(相當(dāng)于短暫休眠












代碼注釋還是很詳細(xì)的,適合初學(xué)者學(xué)習(xí)。


單片機(jī)源程序如下:
  1. /**
  2. 布滿(mǎn)星星的天空 CZS 編寫(xiě)
  3. */
  4. #include <STC15.h>
  5. #include <intrins.h>
  6. #include <math.h>

  7. sbit t12 = P3 ^ 7;         //T12控制
  8. sbit encoderb = P1 ^ 0;    //編碼器的b腳
  9. sbit encodera = P1 ^ 1;    //編碼器的a腳
  10. sbit encoderd = P1 ^ 2;    //編碼器的按鍵d腳
  11. sbit DIO = P3 ^ 3;         // TM1650 數(shù)碼管驅(qū)動(dòng)的sda引腳
  12. sbit CLK = P3 ^ 2;         // TM1650 數(shù)碼管驅(qū)動(dòng)的scl引腳
  13. sbit DO = P5 ^ 5;          //DS18B20數(shù)據(jù)腳
  14. unsigned long VREF = 2390; // 用萬(wàn)用表測(cè)量基準(zhǔn)電壓的真實(shí)值,單位mv

  15. bit lastb = 0;
  16. bit lasta = 0;
  17. unsigned short push_last_time = 0; //記錄按下編碼器按鈕的時(shí)間,短按和長(zhǎng)按

  18. unsigned long t12_voltage;    // 計(jì)算t12熱電偶電壓
  19. unsigned long system_voltage; // 計(jì)算單片機(jī)供電電壓
  20. unsigned long input_voltage;  // 計(jì)算整個(gè)板子的輸入電壓(12~24V)

  21. // PID控制算法
  22. #define KP 1.2f       // 比例系數(shù)
  23. #define KI 0.2f       // 積分系數(shù)
  24. #define KD 0.1f       // 微分系數(shù)
  25. #define MAX_UK 400.0f // 系統(tǒng)允許輸出的最大控制量,這里表現(xiàn)為加熱數(shù),400個(gè)0.5ms加熱周期,最長(zhǎng)連續(xù)加熱時(shí)間為200ms

  26. int ek = 0, ek_1 = 0, ek_2 = 0; // 記錄連續(xù)三次的偏差值(設(shè)定值-實(shí)際測(cè)量值)
  27. float uk_1 = 0.0f, uk = 0.0f;   // 記錄當(dāng)前計(jì)算的PID調(diào)整值和上次計(jì)算的PID調(diào)整值
  28. long integralSum = 0;           // 位置式PID算法的累計(jì)積分項(xiàng)

  29. // 定義一個(gè)數(shù)碼管段碼表,0~F
  30. unsigned char CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0X7C, 0X39, 0X5E, 0X79, 0X71};

  31. unsigned int t12SetTemperature = 10;   // 記錄當(dāng)前設(shè)定的溫度
  32. unsigned int t12ActualTemperature = 0; // 保存T12當(dāng)前的實(shí)際溫度
  33. bit isChangeTemperature = 0;           // 標(biāo)記是否更改過(guò)設(shè)定溫度
  34. unsigned int setTempShowTime = 0;      // 記錄顯示設(shè)置溫度的時(shí)長(zhǎng)

  35. unsigned int need_heat_time = 0;       // 需要加熱的時(shí)長(zhǎng)
  36. unsigned int heat_time_count = 0;      //當(dāng)前已經(jīng)加熱的時(shí)長(zhǎng)
  37. unsigned int actualTempShowTime = 250; //設(shè)定當(dāng)前溫度的顯示時(shí)長(zhǎng),避免采集溫度過(guò)快造成數(shù)碼管亂跳

  38. /*延時(shí)函數(shù),使用STC-ISP自動(dòng)生成的,比較準(zhǔn)確*/
  39. void Delay_ms(unsigned int k) //@12.000MHz
  40. {
  41.   unsigned char i, j;
  42.   for (; k > 0; k--)
  43.   {
  44.     i = 12;
  45.     j = 169;
  46.     do
  47.     {
  48.       while (--j)
  49.         ;
  50.     } while (--i);
  51.   }
  52. }

  53. void Delay_us(unsigned int i)
  54. {
  55.   for (; i > 0; i--)
  56.   {
  57.     _nop_();
  58.     _nop_();
  59.     _nop_();
  60.     _nop_();
  61.   }
  62. }

  63. // 初始化各個(gè)IO口
  64. void initIO()
  65. {
  66.   // 配置各個(gè)端口的輸入模式,M1M0:00普通,01推挽,10高阻輸入,11開(kāi)漏
  67.   /*
  68.         以下列出需要配置的端口,其他端口保持默認(rèn)即可
  69.         t12 = P3^7;             //T12控制  推挽輸出模式
  70.         ADC3:系統(tǒng)輸入電壓檢測(cè) P1^3 輸入模式
  71.         ADC4:T12熱電偶電壓檢測(cè) P1^4 輸入模式
  72.         ADC5:2.5V參考電壓輸入 P1^5 輸入模式
  73.         */

  74.   //P1M0 |= 0x00; //0000 0000
  75.   P1M1 |= 0x38; //0011 1000

  76.   P3M0 = 0x80; //1000 0000
  77.   P3M1 = 0x00; //0000 0000
  78. }

  79. /*初始化ADC*/
  80. void initADC(void)
  81. {
  82.   /*
  83.         開(kāi)啟相應(yīng)ADC口的模擬輸入功能(相應(yīng)位置1)
  84.         ADC3:系統(tǒng)輸入電壓檢測(cè) P1^3
  85.         ADC4:T12熱電偶電壓檢測(cè) P1^4
  86.         ADC5:2.5V參考電壓輸入 P1^5
  87.         */
  88.   P1ASF = 0x38; //0011 1000
  89.   ADC_RES = 0;  // 清楚結(jié)果寄存器
  90.   ADC_RESL = 0;
  91.   /*
  92.         ADC控制寄存器
  93.         ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
  94.         */
  95.   // 這里初始化的時(shí)候,可以先打開(kāi)電源和設(shè)置轉(zhuǎn)換速度
  96.   ADC_CONTR = 0x80; // 1000 0000
  97.   Delay_ms(5);      // 上電之后延時(shí)等待一段時(shí)間
  98. }

  99. // 關(guān)閉ADC電源,在進(jìn)入空閑(休眠)模式的時(shí)候啟用,降低功耗
  100. void closeADC(void)
  101. {
  102.   /*
  103.         ADC控制寄存器
  104.         ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
  105.         */
  106.   ADC_CONTR = 0x00;
  107. }

  108. // 直接插入排序
  109. void insertionSort(unsigned int A[], unsigned int n)
  110. {
  111.   unsigned int i, j;
  112.   for (i = 1; i < n; i++)
  113.   {
  114.     for (j = i; j > 0; j--)
  115.     {
  116.       if (A[j] < A[j - 1])
  117.       {
  118.         // 不使用第三變量交換兩個(gè)數(shù),使用異或運(yùn)算速度快
  119.         A[j - 1] ^= A[j];
  120.         A[j] ^= A[j - 1];
  121.         A[j - 1] ^= A[j];
  122.       }
  123.     }
  124.   }
  125. }

  126. #define ADC_FLAG 0x10  // ADC轉(zhuǎn)換完成標(biāo)志
  127. #define ADC_START 0x08 // ADC開(kāi)始置位
  128. // 獲取某個(gè)ADC通道的轉(zhuǎn)換值
  129. // 為了提高結(jié)果的準(zhǔn)確性,每次測(cè)量,測(cè)5次,并且去掉一個(gè)最高值,一個(gè)最低值,最后取中間3個(gè)的均值返回
  130. unsigned int getADCResult(unsigned int channel)
  131. {
  132.   unsigned int res[5], i, result = 0;
  133.   for (i = 0; i < 5; i++)
  134.   {
  135.     /*
  136.         ADC控制寄存器
  137.         ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0
  138.         */
  139.     ADC_CONTR = (0x80 | channel | ADC_START); // 選擇需要讀取的通道,并開(kāi)啟轉(zhuǎn)換
  140.     Delay_us(1);
  141.     while (!(ADC_CONTR & ADC_FLAG))
  142.       ;                                            //等待ADC轉(zhuǎn)換完成
  143.     res[i] = ((ADC_RES << 2) | (ADC_RESL & 0x03)); // 計(jì)算轉(zhuǎn)換出來(lái)的原始結(jié)果
  144.     ADC_RES = 0x00;
  145.     ADC_RESL = 0x00; // 清零結(jié)果寄存器
  146.   }
  147.   // 對(duì)結(jié)果進(jìn)行排序
  148.   insertionSort(res, 5);
  149.   // 去掉一個(gè)最高值,去掉一個(gè)最低值,剩余三個(gè)求平均值
  150.   result = (res[1] + res[2] + res[3]) / 3;
  151.   return result;
  152. }
  153. /*以下是計(jì)算各種電壓的函數(shù),返回結(jié)果的單位都是mv*/
  154. // 計(jì)算公式(mv) output_voltage = (VREF萬(wàn)用表測(cè)的TL431基準(zhǔn)電壓值(mv) * 待測(cè)通道的ADC值 / TL431基準(zhǔn)通道ADC值)
  155. // 計(jì)算獲取T12的電壓
  156. void getT12Voltage(void)
  157. {
  158.   t12_voltage = (VREF * getADCResult(4) / getADCResult(5)); //計(jì)算t12電壓,單位mV
  159. }

  160. // 計(jì)算獲取單片機(jī)的電源電壓
  161. void getSystemVoltage(void)
  162. {
  163.   system_voltage = (VREF * 1024 / getADCResult(5)); //計(jì)算單片機(jī)的電源電壓,單位mV;
  164. }

  165. // 計(jì)算獲取輸入電源電壓
  166. void getInputVoltage(void)
  167. {
  168.   input_voltage = (VREF * getADCResult(3) / getADCResult(5) * 11); // 計(jì)算下分壓電阻點(diǎn)的電壓,并乘分壓比,獲得實(shí)際的輸入電壓
  169. }

  170. /* 計(jì)算T12熱電偶溫度 */
  171. void getT12Temperature(void)
  172. {
  173.   float x = 0.0f;
  174.   t12 = 0;         //測(cè)溫的時(shí)候,關(guān)閉電烙鐵
  175.   Delay_us(10);    // 等待一段時(shí)間,等電容放完電后再測(cè)量溫度比較準(zhǔn)確
  176.   getT12Voltage(); // 更新T12熱電偶電壓
  177.                    //T12實(shí)際溫度 = (ADC電壓(mV)-失調(diào)電壓(mV))/運(yùn)放增益*熱電偶分度值(℃/mV)+室溫(℃)
  178.                    //t12Temp = 1.0f*getT12Voltage() / 231.0f * 54.0f + 23.0f;

  179.   // 插值函數(shù)計(jì)算T12溫度,上面的算得不夠準(zhǔn)確,自己測(cè)量了t12溫度與熱電偶電動(dòng)勢(shì)的關(guān)系,用matlab擬合出來(lái)的公式
  180.   x = 1.0f * t12_voltage / 231.0f;
  181.   x = -0.9f * x * x + 48.0f * x + 22.0f;
  182.   t12ActualTemperature = (unsigned int)x;
  183. }

  184. /*
  185. // 增量式PID控制算法,該算法用在溫度控制效果不佳,調(diào)參調(diào)了比較久,不是很理想
  186. // 輸入設(shè)定溫度和當(dāng)前溫度
  187. // 返回當(dāng)前應(yīng)該加熱的時(shí)長(zhǎng)
  188. void incrementalPID(unsigned int setTemperature, unsigned int actualTemperature)
  189. {
  190.   float delta_uk = 0.0f;                   // 用于計(jì)算PID增量值
  191.   uk_1 = uk;                               // 記錄上次計(jì)算的PID調(diào)整值
  192.   ek_2 = ek_1;                             // 記錄上上次計(jì)算的偏差值
  193.   ek_1 = ek;                               // 記錄上次計(jì)算的偏差值
  194.   ek = setTemperature - actualTemperature; // 計(jì)算當(dāng)前偏差值
  195.   if (ek < 0)
  196.   {
  197.     // 如果實(shí)際溫度比設(shè)定溫度還要高,那么不執(zhí)行加熱
  198.     need_heat_time = 0;
  199.     return;
  200.   }
  201.   if (abs(ek) > 100)
  202.   {
  203.     // 如果溫差大于100℃,則執(zhí)行系統(tǒng)的動(dòng)態(tài)加速,不管比例項(xiàng)為正還是為負(fù),都取正數(shù)
  204.     delta_uk = KP * abs(ek - ek_1) + KI * ek + KD * (ek - 2 * ek_1 + ek_2); // 計(jì)算PID增量值
  205.   }
  206.   else
  207.   {
  208.     // 當(dāng)快要接近目標(biāo)溫度的時(shí)候,執(zhí)行正常的調(diào)節(jié)
  209.     delta_uk = KP * (ek - ek_1) + KI * ek + KD * (ek - 2 * ek_1 + ek_2); // 計(jì)算PID增量值
  210.   }
  211.   uk = uk_1 + delta_uk; // 計(jì)算當(dāng)前應(yīng)該輸出的PWM值
  212.   // 判斷是否超出了系統(tǒng)控制量的邊界范圍,如果超出,則賦值為邊界
  213.   if (uk < 1e-9)
  214.   {
  215.     uk = 0.0f;
  216.   }
  217.   if (uk > MAX_UK)
  218.   {
  219.     uk = MAX_UK;
  220.   }
  221.   need_heat_time = (unsigned int)uk;
  222. }
  223. */

  224. // 位置式PID控制算法,這個(gè)控制算法運(yùn)行起來(lái)比較理想
  225. void positionalPID(unsigned int setTemperature, unsigned int actualTemperature)
  226. {
  227.   ek_1 = ek;                               // 記錄上次計(jì)算的偏差值
  228.   ek = setTemperature - actualTemperature; // 計(jì)算當(dāng)前偏差值
  229.   if (ek < 0)
  230.   {
  231.     // 如果實(shí)際溫度比設(shè)定溫度還要高,那么不執(zhí)行加熱
  232.     need_heat_time = 0;
  233.     return;
  234.   }
  235.   // 當(dāng)偏差較大時(shí),取消積分作用
  236.   if (abs(ek) > 100)
  237.   {
  238.     integralSum = 0;
  239.   }
  240.   else
  241.   {
  242.     // 否則,根據(jù)情況進(jìn)行累計(jì)積分
  243.     if (integralSum > 100) //積分超過(guò)上限時(shí),只累計(jì)負(fù)的積分量
  244.     {
  245.       if (ek < 0)
  246.       {
  247.         integralSum += ek;
  248.       }
  249.     }
  250.     else if (integralSum < -10) //積分超過(guò)下限時(shí),只累計(jì)正的積分量
  251.     {
  252.       if (ek > 0)
  253.       {
  254.         integralSum += ek;
  255.       }
  256.     }
  257.     else
  258.     {
  259.       integralSum += ek;
  260.     }
  261.   }
  262.   uk = KP * ek + KI * integralSum + KD * (ek - ek_1); // 計(jì)算當(dāng)前應(yīng)該輸出的控制量值
  263.   // 判斷是否超出了系統(tǒng)控制量的邊界范圍,如果超出,則賦值為邊界
  264.   if (uk < 1e-9)
  265.   {
  266.     uk = 0.0f;
  267.   }
  268.   if (uk > MAX_UK)
  269.   {
  270.     uk = MAX_UK;
  271.   }
  272.   need_heat_time = (unsigned int)uk; // 更新當(dāng)前需要加熱的時(shí)間數(shù)
  273. }

  274. /********************************以下是TM1650數(shù)碼管顯示相關(guān)的函數(shù)****************************************************/

  275. void Start1650(void)
  276. { //開(kāi)始信號(hào)
  277.   CLK = 1;
  278.   DIO = 1;
  279.   Delay_us(5);
  280.   DIO = 0;
  281.   Delay_us(5);
  282.   DIO = 0;
  283. }

  284. void Ask1650(void)
  285. { //ACK信號(hào)
  286.   unsigned char timeout = 1;
  287.   CLK = 1;
  288.   Delay_us(5);
  289.   CLK = 0;
  290.   while ((DIO) && (timeout <= 100))
  291.   {
  292.     timeout++;
  293.   }
  294.   Delay_us(5);
  295.   CLK = 0;
  296. }

  297. void Stop1650(void)
  298. { //停止信號(hào)
  299.   CLK = 1;
  300.   DIO = 0;
  301.   Delay_us(5);
  302.   DIO = 1;
  303.   Delay_us(5);
  304. }

  305. void WrByte1650(unsigned char oneByte)
  306. { //寫(xiě)一個(gè)字節(jié),高位在前,低位在后
  307.   unsigned char i;
  308.   CLK = 0;
  309.   Delay_us(1);
  310.   for (i = 0; i < 8; i++)
  311.   {
  312.     oneByte = oneByte << 1;
  313.     DIO = CY;
  314.     CLK = 0;
  315.     Delay_us(5);
  316.     CLK = 1;
  317.     Delay_us(5);
  318.     CLK = 0;
  319.   }
  320. }
  321. /*
  322. unsigned char Scan_Key(void)
  323. { // 按鍵掃描
  324.   unsigned char i;
  325.   unsigned char rekey;
  326.   Start1650();
  327.   WrByte1650(0x49); //讀按鍵命令
  328.   Ask1650();
  329.   //DIO = 1;
  330.   for (i = 0; i < 8; i++)
  331.   {
  332.     CLK = 1;
  333.     rekey = rekey << 1;
  334.     if (DIO)
  335.     {
  336.       rekey++;
  337.     }
  338.     Delay_us(5);
  339.     CLK = 0;
  340.   }
  341.   Ask1650();
  342.   Stop1650();
  343.   return (rekey);
  344. }
  345. */

  346. void Set1650(unsigned char add, unsigned char dat)
  347. { //數(shù)碼管顯示
  348.   //寫(xiě)顯存必須從高地址開(kāi)始寫(xiě)
  349.   Start1650();
  350.   WrByte1650(add); //第一個(gè)顯存地址
  351.   Ask1650();
  352.   WrByte1650(dat);
  353.   Ask1650();
  354.   Stop1650();
  355. }

  356. // 初始化1650,傳入亮度參數(shù),范圍0~7
  357. void init1650(unsigned char light)
  358. {
  359.   Set1650(0x48, ((light << 4) | 0x01));
  360. }

  361. // 數(shù)碼管顯示函數(shù)
  362. void display(signed int num)
  363. {
  364.   // 計(jì)算這個(gè)數(shù)字對(duì)應(yīng)的千百十個(gè)位的數(shù)字
  365.   unsigned int tmpnum, qian, bai, shi, ge;
  366.   if (num < 0)
  367.     num = -num;
  368.   tmpnum = num;
  369.   qian = tmpnum / 1000;
  370.   tmpnum %= 1000;
  371.   bai = tmpnum / 100;
  372.   tmpnum %= 100;
  373.   shi = tmpnum / 10;
  374.   ge = tmpnum % 10;

  375.   Set1650(0x68, CODE[qian]);
  376.   Set1650(0x6A, CODE[bai]);
  377.   Set1650(0x6C, CODE[shi]);
  378.   Set1650(0x6E, CODE[ge]);
  379. }

  380. /************************************************************************************************
  381.     函數(shù)名稱(chēng):Encoder
  382.     函數(shù)功能:編碼器旋轉(zhuǎn)的掃描及處理
  383.     入口參數(shù):無(wú)
  384.     出口參數(shù):char型    0-無(wú)旋轉(zhuǎn)   'R'-正轉(zhuǎn)(向右轉(zhuǎn))   'L'-反轉(zhuǎn)(向左轉(zhuǎn))
  385. ************************************************************************************************/
  386. unsigned char Encoder(void)
  387. {
  388.   static bit Enc0 = 0;
  389.   static unsigned char EncOld, EncX = 0;
  390.   unsigned char EncNow;

  391.   encodera = 1; //PINA置高電平
  392.   encoderb = 1; //PINB置高電平
  393.   if (Enc0 == 0)
  394.   {
  395.     EncOld = (encodera ? 0x02 : 0x00) + (encoderb ? 0x01 : 0x00);
  396.     Enc0 = 1; //記住初次調(diào)用時(shí)編碼器的狀態(tài)
  397.   }
  398.   EncNow = (encodera ? 0x02 : 0x00) + (encoderb ? 0x01 : 0x00); //根據(jù)兩個(gè)IO當(dāng)前狀態(tài)組合成16進(jìn)制的0x00|0x01|0x02|0x03
  399.   if (EncNow == EncOld)
  400.     return (0); //如果新數(shù)據(jù)和原來(lái)的數(shù)據(jù)一樣(沒(méi)有轉(zhuǎn)動(dòng))就直接返回0

  401.   if (EncOld == 0x00 && EncNow == 0x02 || EncOld == 0x03 && EncNow == 0x01)
  402.     EncX = EncNow;                                                                                          //00-10|11-01
  403.   if (EncOld == 0x00 && EncX == 0x02 && EncNow == 0x03 || EncOld == 0x03 && EncX == 0x01 && EncNow == 0x00) //00-10-11|11-01-00右轉(zhuǎn)
  404.   {
  405.     EncOld = EncNow, EncX = 0;
  406.     return ('R'); //兩定位一脈沖
  407.   }

  408.   if (EncOld == 0x00 && EncNow == 0x01 || EncOld == 0x03 && EncNow == 0x02)
  409.     EncX = EncNow;                                                                                          //00-01|11-10
  410.   if (EncOld == 0x00 && EncX == 0x01 && EncNow == 0x03 || EncOld == 0x03 && EncX == 0x02 && EncNow == 0x00) //00-01-11|11-10-00左轉(zhuǎn)
  411.   {
  412.     EncOld = EncNow;
  413.     EncX = 0;
  414.     return ('L'); //兩定位一脈沖
  415.   }
  416.   return (0); //沒(méi)有正確解碼返回0
  417. }

  418. // 編碼器函數(shù),用于設(shè)置t12的設(shè)定溫度
  419. void bianmaqi()
  420. {
  421.   unsigned char enc;
  422.   enc = Encoder(); //掃描編碼器,取得返回值
  423.   if (enc == 'R')
  424.   {
  425.     t12SetTemperature += 5;
  426.     if (t12SetTemperature > 500)
  427.       t12SetTemperature = 500;
  428.     isChangeTemperature = 1;
  429.   }
  430.   else if (enc == 'L')
  431.   {
  432.     t12SetTemperature -= 5;
  433.     if (t12SetTemperature < 10)
  434.       t12SetTemperature = 10;
  435.     isChangeTemperature = 1;
  436.   }

  437.   while (!encoderd)
  438.   {
  439.     push_last_time++;
  440.     Delay_ms(100);
  441.   }
  442.   if (push_last_time > 0 && push_last_time < 8)
  443.   {
  444.     push_last_time = 0;
  445.     Delay_ms(80); // 等待延時(shí)一段時(shí)間,看看有沒(méi)有第二次按下
  446.     while (!encoderd)
  447.     {
  448.       push_last_time++;
  449.       Delay_ms(100);
  450.     }
  451.     if (push_last_time > 0 && push_last_time < 8)
  452.     {
  453.       // 雙擊了編碼器按鈕,關(guān)閉電烙鐵輸出
  454.       t12SetTemperature = 10;
  455.       t12 = 0;
  456.       isChangeTemperature = 1;
  457.     }
  458.     else
  459.     {
  460.       // 短按一次編碼器按鈕,設(shè)定為300℃輸出
  461.       t12SetTemperature = 300;
  462.       isChangeTemperature = 1;
  463.     }
  464.   }
  465.   else if (push_last_time >= 8)
  466.   {
  467.     // 長(zhǎng)按編碼器按鈕,設(shè)定為250℃輸出
  468.     t12SetTemperature = 250;
  469.     isChangeTemperature = 1;
  470.   }
  471.   if (isChangeTemperature)
  472.   {
  473.     // 如果有改變?cè)O(shè)置溫度,那么就要顯示新的設(shè)置溫度
  474.     setTempShowTime = 600;
  475.   }
  476.   push_last_time = 0;
  477. }

  478. // 該定時(shí)器初始化函數(shù)部分使用STC-ISP下載軟件生成,加入開(kāi)啟中斷的寄存器賦值
  479. void Timer0Init(void) //500微秒 0.5ms @12.000MHz
  480. {

  481.   AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
  482.   TMOD &= 0xF0; //設(shè)置定時(shí)器模式
  483.   TL0 = 0x90;   //設(shè)置定時(shí)初值
  484.   TH0 = 0xE8;   //設(shè)置定時(shí)初值
  485.   TF0 = 0;      //清除TF0標(biāo)志
  486.   ET0 = 1;      //開(kāi)啟定時(shí)器0中斷
  487.   TR0 = 1;      //定時(shí)器0開(kāi)始計(jì)時(shí)
  488.   EA = 1;       // CPU總中斷允許控制位
  489. }

  490. //定時(shí)0中斷函數(shù),每隔0.5ms執(zhí)行一次
  491. void timer0(void) interrupt 1
  492. {
  493.   bianmaqi(); // 調(diào)用編碼器函數(shù),獲取編碼器當(dāng)前狀態(tài)(左旋,右旋,短按,長(zhǎng)按)
  494.   if (heat_time_count < need_heat_time)
  495.   {
  496.     // 如果當(dāng)前還沒(méi)完成需要加熱的時(shí)長(zhǎng),就控制t12加熱
  497.     t12 = 1;
  498.     heat_time_count++;
  499.   }
  500.   else
  501.   {
  502.     // 已經(jīng)完成相應(yīng)的加熱時(shí)長(zhǎng),調(diào)用PID函數(shù)獲取下一個(gè)需要的加熱數(shù)
  503.     t12 = 0;
  504.     getT12Temperature();                                    // 獲取當(dāng)前T12的溫度
  505.     positionalPID(t12SetTemperature, t12ActualTemperature); // 更新當(dāng)前需要加熱的時(shí)間計(jì)數(shù)
  506.     heat_time_count = 0;                                    //重新開(kāi)始統(tǒng)計(jì)加熱時(shí)長(zhǎng)
  507.   }

  508.   if (setTempShowTime > 0)
  509.   {
  510.     // 還沒(méi)顯示夠顯示設(shè)置溫度的時(shí)長(zhǎng),需要繼續(xù)顯示,這里用7開(kāi)頭表示顯示設(shè)定溫度
  511.     display(t12SetTemperature + 7000);
  512.     setTempShowTime--;
  513.     // 已經(jīng)顯示了設(shè)置溫度了,那么要把這個(gè)更改過(guò)設(shè)置溫度的標(biāo)志開(kāi)關(guān)關(guān)閉
  514.     isChangeTemperature = 0;
  515.   }
  516.   else
  517.   {
  518.     if (actualTempShowTime < 2)
  519.     {
  520.       display(t12ActualTemperature); // 顯示當(dāng)前的t12實(shí)際溫度
  521.       actualTempShowTime = 250;
  522.     }
  523.     actualTempShowTime--;
  524.   }
  525. }

  526. void main()
  527. {
  528.   initIO(); // 初始化IO口
  529.   t12 = 0;
  530.   init1650(1); // 初始化TM1650顯示
  531.   initADC();   // 初始化ADC

  532.   getSystemVoltage(); //檢測(cè)單片機(jī)電源電壓
  533.   getInputVoltage();  //檢測(cè)輸入電壓

  534.   // 顯示輸入電壓,這里的7123和7456僅僅只是用于標(biāo)識(shí)顯示什么內(nèi)容,畢竟沒(méi)有OLED屏幕這么高大上可以顯示很多內(nèi)容
  535. ……………………

  536. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

壓縮包內(nèi)容

全部資料51hei下載地址:
51hei_T12白光.zip (352.73 KB, 下載次數(shù): 670)

評(píng)分

參與人數(shù) 3黑幣 +95 收起 理由
wpppmlah + 30 共享資料的黑幣獎(jiǎng)勵(lì)!
digger + 15 共享資料的黑幣獎(jiǎng)勵(lì)!
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏53 分享淘帖 頂5 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:328014 發(fā)表于 2020-11-25 16:02 | 只看該作者
好資料,51黑有你更精彩!!!
代碼工程:

程序.7z

39.81 KB, 下載次數(shù): 30, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報(bào)

板凳
ID:723157 發(fā)表于 2020-12-15 21:58 | 只看該作者
一直在找T12 白光制作 單片機(jī) 學(xué)習(xí)!
回復(fù)

使用道具 舉報(bào)

地板
ID:156220 發(fā)表于 2020-12-16 13:39 | 只看該作者
謝謝樓主的資料分享,好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

5#
ID:35873 發(fā)表于 2021-1-4 16:30 | 只看該作者
做的不錯(cuò) 點(diǎn)個(gè)贊  佩服會(huì)寫(xiě)程序的
回復(fù)

使用道具 舉報(bào)

6#
ID:90685 發(fā)表于 2021-1-14 19:02 | 只看該作者
謝謝,等打樣回來(lái)試試在評(píng)論。
回復(fù)

使用道具 舉報(bào)

7#
ID:879141 發(fā)表于 2021-1-31 18:59 來(lái)自手機(jī) | 只看該作者
線路看來(lái)不太複雜,學(xué)習(xí)一下。謝謝分享!
回復(fù)

使用道具 舉報(bào)

8#
ID:353831 發(fā)表于 2021-2-10 17:37 | 只看該作者
樓主你好,程序編譯通不過(guò)
回復(fù)

使用道具 舉報(bào)

9#
ID:95809 發(fā)表于 2021-2-11 08:10 | 只看該作者
wl020807 發(fā)表于 2021-2-10 17:37
樓主你好,程序編譯通不過(guò)

因?yàn)槌绦虺^(guò)了8K,你在輸出選擇變量在XDATA就可以了。

2021-02-11_08-06-17.jpg (69.68 KB, 下載次數(shù): 175)

2021-02-11_08-06-17.jpg
回復(fù)

使用道具 舉報(bào)

10#
ID:232366 發(fā)表于 2021-2-12 13:52 | 只看該作者
樓主您的編程軟件可以共享一下嗎?中文版的?
回復(fù)

使用道具 舉報(bào)

11#
ID:353831 發(fā)表于 2021-2-14 11:54 | 只看該作者
bxyyhan 發(fā)表于 2021-2-11 08:10
因?yàn)槌绦虺^(guò)了8K,你在輸出選擇變量在XDATA就可以了。

謝謝!編譯已成功
回復(fù)

使用道具 舉報(bào)

12#
ID:353831 發(fā)表于 2021-2-14 18:38 | 只看該作者
bxyyhan 發(fā)表于 2021-2-11 08:10
因?yàn)槌绦虺^(guò)了8K,你在輸出選擇變量在XDATA就可以了。

樓主了你好,請(qǐng)問(wèn)15W408AS下載晶振設(shè)置成12M嗎?
回復(fù)

使用道具 舉報(bào)

13#
ID:95809 發(fā)表于 2021-2-15 21:10 | 只看該作者
wl020807 發(fā)表于 2021-2-14 18:38
樓主了你好,請(qǐng)問(wèn)15W408AS下載晶振設(shè)置成12M嗎?

我不是樓主,晶振12M可以,他這個(gè)只有最基本的溫控功能,沒(méi)有其他功能。
回復(fù)

使用道具 舉報(bào)

14#
ID:224125 發(fā)表于 2021-2-16 17:23 | 只看該作者
關(guān)注一下,正好學(xué)習(xí)怎么編程
回復(fù)

使用道具 舉報(bào)

15#
ID:71535 發(fā)表于 2021-2-18 09:35 | 只看該作者
學(xué)習(xí)一下,排序和編碼器實(shí)用價(jià)值好,謝謝分享。
回復(fù)

使用道具 舉報(bào)

16#
ID:137526 發(fā)表于 2021-2-19 12:02 | 只看該作者
謝謝樓主的資料分享 注釋清晰 學(xué)習(xí)起來(lái)很好的資料
回復(fù)

使用道具 舉報(bào)

17#
ID:315554 發(fā)表于 2021-6-3 15:48 | 只看該作者
注解很詳細(xì),學(xué)習(xí)一下,謝謝分享,
回復(fù)

使用道具 舉報(bào)

18#
ID:496247 發(fā)表于 2021-6-14 19:36 | 只看該作者
好評(píng),謝謝分享
回復(fù)

使用道具 舉報(bào)

19#
ID:1008207 發(fā)表于 2022-3-18 09:21 | 只看該作者

謝謝樓主的資料分享,好資料!
回復(fù)

使用道具 舉報(bào)

20#
ID:44459 發(fā)表于 2022-3-24 13:28 | 只看該作者
有個(gè)問(wèn)題需要提醒下,431基準(zhǔn)A、R腳之間的電容不能小于4.7uf 不然自激,建議10uf ,看你程序里基準(zhǔn)電壓測(cè)量出來(lái)是2.39V,距離標(biāo)準(zhǔn)2.5V差異較大,很可能是自激造成的。
回復(fù)

使用道具 舉報(bào)

21#
ID:430492 發(fā)表于 2022-3-26 14:17 | 只看該作者
樓上厲害,細(xì)節(jié)注意得很好!
回復(fù)

使用道具 舉報(bào)

22#
ID:835869 發(fā)表于 2022-6-6 07:33 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

23#
ID:915491 發(fā)表于 2022-6-8 09:06 | 只看該作者
很好的資料,不過(guò)18B20能測(cè)到300度嗎
回復(fù)

使用道具 舉報(bào)

24#
ID:734899 發(fā)表于 2022-7-21 13:56 | 只看該作者
這個(gè)能換成3位數(shù)碼管的嗎?
回復(fù)

使用道具 舉報(bào)

25#
ID:961114 發(fā)表于 2022-7-21 14:39 | 只看該作者
STC 虛擬 調(diào)試接口
回復(fù)

使用道具 舉報(bào)

26#
ID:82809 發(fā)表于 2022-7-21 15:59 | 只看該作者
1.  358的4腳8腳接地?
2.  R9后面不跟分壓電阻?358的7腳輸出不飽和嗎?
回復(fù)

使用道具 舉報(bào)

27#
ID:1039485 發(fā)表于 2022-8-11 13:56 | 只看該作者
學(xué)習(xí)了,感謝分享
回復(fù)

使用道具 舉報(bào)

28#
ID:388000 發(fā)表于 2022-8-17 17:04 | 只看該作者
烙鐵壞了,修復(fù)一下,看電路有點(diǎn)像。
回復(fù)

使用道具 舉報(bào)

29#
ID:1007907 發(fā)表于 2022-8-27 20:59 | 只看該作者
這芯片夠便宜,可以試下
回復(fù)

使用道具 舉報(bào)

30#
ID:579397 發(fā)表于 2022-9-19 18:04 | 只看該作者
請(qǐng)問(wèn)畫(huà)PCB的軟件是啥
回復(fù)

使用道具 舉報(bào)

31#
ID:688460 發(fā)表于 2022-9-19 22:01 | 只看該作者
pfdqwp 發(fā)表于 2022-7-21 15:59
1.  358的4腳8腳接地?
2.  R9后面不跟分壓電阻?358的7腳輸出不飽和嗎?

358的第8腳肯定是接電源的,你看一下他的洞洞板的連接就明白了,他這個(gè)原理圖上應(yīng)該的初心大意連錯(cuò)了地方!
回復(fù)

使用道具 舉報(bào)

32#
ID:53928 發(fā)表于 2023-1-12 00:16 | 只看該作者
這個(gè)片子上oled更好一些    204做數(shù)碼管足夠用了
回復(fù)

使用道具 舉報(bào)

33#
ID:269675 發(fā)表于 2023-3-21 14:18 | 只看該作者
我就想要最基本的控溫, 如果能加上串口通訊多好,那么大神可以弄個(gè),
回復(fù)

使用道具 舉報(bào)

34#
ID:433219 發(fā)表于 2023-8-18 10:30 | 只看該作者
405616736 發(fā)表于 2022-9-19 18:04
請(qǐng)問(wèn)畫(huà)PCB的軟件是啥

一看就是 Protel99
回復(fù)

使用道具 舉報(bào)

35#
ID:1064915 發(fā)表于 2023-8-18 10:51 | 只看該作者
準(zhǔn)備元件,有時(shí)間仿制一個(gè)
回復(fù)

使用道具 舉報(bào)

36#
ID:1065749 發(fā)表于 2023-8-18 14:06 | 只看該作者
電烙鐵輸出插頭有5個(gè)腳,是怎樣定義的,哪兩個(gè)接烙鐵芯,哪兩個(gè)接溫度傳感器,另外一個(gè)腳應(yīng)該是接地。
回復(fù)

使用道具 舉報(bào)

37#
ID:38187 發(fā)表于 2024-2-23 20:04 | 只看該作者
謝謝老師的分享, 正好學(xué)習(xí)一下PID方法
回復(fù)

使用道具 舉報(bào)

38#
ID:857072 發(fā)表于 2024-2-23 22:51 | 只看該作者
gao687 發(fā)表于 2022-6-8 09:06
很好的資料,不過(guò)18B20能測(cè)到300度嗎

18B20是測(cè)量室溫的,烙鐵自帶熱電偶測(cè)溫,但是需要環(huán)境溫度做冷端補(bǔ)償來(lái)校準(zhǔn)烙鐵溫度不是用18B20直接測(cè)烙鐵頭。
回復(fù)

使用道具 舉報(bào)

39#
ID:857072 發(fā)表于 2024-2-23 22:53 | 只看該作者
18689719961 發(fā)表于 2023-8-18 14:06
電烙鐵輸出插頭有5個(gè)腳,是怎樣定義的,哪兩個(gè)接烙鐵芯,哪兩個(gè)接溫度傳感器,另外一個(gè)腳應(yīng)該是接地。

T12烙鐵就只有兩根線,加熱和測(cè)溫串在一起的。
回復(fù)

使用道具 舉報(bào)

40#
ID:67838 發(fā)表于 2024-2-29 12:04 | 只看該作者

謝謝樓主的資料分享
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表