单片机PID算法MAX6675热电偶温控项目

发布者:Coboro最新更新时间:2019-10-21 来源: 51hei关键字:单片机  PID算法  MAX6675  热电偶温控 手机看文章 扫描二维码
随时随地手机看文章

0.jpg (58.35 KB, 下载次数: 24)

下载附件  保存到相册

2018-3-14 05:20 上传

单片机源程序如下:

#include

#include//包含 rand() 这样的随机函数


#include "STC12C5A60S2.h"

#include "zcy.h"

#include "s_12864.h"




////////////////////////////////////////////////////////

//全局变量


volatile long time0_temp1 = 0;

volatile long time0_temp2 = 0;


volatile long global_sec = 0;


int key_counter = 0 ;

int led_flash_mode_index = 2 ;//led闪灯模式 1--8 从1开始 最多8种模式   ssssssssss


volatile int time0_10ms_flag = 0;

int time0_10ms_counter = 0;

int led_active_flag = 0;


typedef void (*led_fun_str)(void);//定义一个函数指针的数据类型

//之后用该数据类型定义一个数组

led_fun_str led_fun_bufffer[29+29];


void (*led_flash_fun_str)(void);


int led_index = 1;


int k_off = 0;

int k_on  = 0;


uchar temp_random = 0;

uchar now_temp_random = 0;

uchar last_temp_random = 0;

uchar temp_diff        = 0;


uchar temp_buffer_random[29];


int k_extern = 0;

int loop_temp = 0;


uchar temp_buffer_16_16_comm[32];//必须设计成全局变量才不会显示错乱

uchar temp_buffer_8_16_comm[16];//必须设计成全局变量才不会显示错乱


int refer_fun_flag = 0;

int key_perss_counter  = 0;

int key_once_active_flag = 0;//key动作一次

int key_value = 0 ;


float now_temp              = 0.0;

long dis_now_temp           = 0;

float wenkong_now_temp      = 0.0;//用于温度控制的当前温度


volatile int global_sec_flag = 0;

int temp_zero_below_flag = 1 ;//1说明是0及正温度  0说明是负温度


char temp_dis_num_buffer[10];//必须定义成全局变量 否则出错 原因不详

char *temp_str;


uint them = 0;

int  ds_18b20_reset_ok_flag = 0;


//pid

float           SV_value           = 50.0; //设定温度值

float           PV_value           = 0.0;  //用于参与计算的当前温度值

volatile float  P_value            = 0.0;  //比例带 比如56.3代表56.3%  0.0--200.0

int             I_value            = 0;  //积分时间  秒  0-3600

int             D_value            = 0;   //微分时间  秒  0-900


int comm_dis_once_flag    = 1; //初始为1

volatile int special_dis_once_flag = 1; //初始为1

int pid_tune_flag         = 0;//初始为0 即pid阶段 采用默认的值    1 为自整定过程


int three_dot_dis_flag    = 0;


float  Proportion  = 0.0;           //  比例常数 Proportional Const

float  Integral    = 0.0;           //  积分常数 Integral Const        

float  Derivative  = 0.0;           //  微分常数 Derivative Const

float  LastError   = 0.0;           //  Error[-1]

float  PrevError   = 0.0;           //  Error[-2]

float  SumError    = 0.0;           //  Sums of Errors

float  dError      = 0.0;

float  Error       = 0.0;


int   pid_result = 0;

float T_Hight = 0.0;

float T_LOW   = 100.0; //温度

long TIME_Hight = 0;

long TIME_LOW   = 0;        //具体的秒

int pid_con_10ms_flag = 0;

int pid_con_counter        = 0;


float  KC = 1.0;  //临界比例系数  初始默认的值

int    TC = 40;   //振荡周期      初始默认的值


int temp_pid  =  0;//设定成全局变量  


volatile int get_now_temp_flag   = 0;

volatile int enable_pid_sec_flag = 0;

volatile int pid_self_sec_flag   = 0;


//uint pid_self_calc_buffer[200] _at_ 0xF000;        //0xffff 对应flash的最顶端


int zero_across_counter = 0;

int pid_self_first_status_flag = 0;


long pid_self_time_sec = 0;


float max_temp  = 0.0 ;  //初始温度等于0

float min_temp  = 100.0 ;//初始温度等于100

float sum_temp  = 0.0 ;  //初始温度等于0

float aver_temp        = 0.0 ;


int cool_ack_counter    = 0;

int hot_ack_counter     = 0;

int once_add_1_flag     = 0;


float pid_self_calc_buffer[4];

int k_pid_self_counter = 0;


int enable_calc_min_max_flag = 0;

int k_max_min = 0;

int dis_tune_once_flag = 1;


int k_cut_off_flag = 0;//断k偶标志

long k_reou_value = 0; 


int soft_dis_flag = 1;

int soft_counter  = 0;

int soft_end_counter = 0;


int pwm_con_time_flag = 0;


//qqqqqqqqqqqqqq

////////////////////////////////////////////////////////

//函数定义

void SendByte(uchar Dbyte); //发送字节数据

void write_cmd(uchar Cbyte);//写指令

void write_data(uchar Dbyte);//写数据

void PUTchar8x8(int row,int col,int count,uchar *put);

void PUTchar8x16(int row,int col,int count,uchar *put);

void PUTchar16x16(int row,int col,int count,uchar *put);//32个字节表示1个汉字

void PUTchar24x24(int row,int col,int count,uchar *put);

void PUTBMP(void);//图片

void PUTREVERSEBMP(void);//图片反显

void LcmClear(void);//清屏

void LcmSet(void);//显示所有  即满屏都是黑色的

void LcmInit(void);//初始化

void ohengxian(void);//O横线程序

void jihengxian(void);//奇横线程序

void oshuxian(void);//O竖线程序

void jishuxian(void);//奇竖线程序

void dianxian(void);//点显示程序 满屏都是点

void zifu8x16xian(void);//可以显示数字及英文

void zifu16x16xian(void);//可以显示特定的汉字

void lcd_dis_position_16_16(int line,int column,uchar zifu_16_16[2]);// 1行 1列 具体的字符 

void lcd_dis_position_8_16(int line,int column,uchar zifu_8_16);// 1行 1列 具体的字符 

void lcd_s_12864_dis_8_16_str(int dis_line,int start_position,char *dis_str);//显示一行的8*16的字符

void ds_18b20_DelayXus(int n);

void ds_18b20_init(void);//DS18B20的初始化

uchar ds_18b20_read_date(void);  //读一个字节

void ds_18b20_write_date(uchar date);//写一个字节

float read_18b20_temp(void);//读出18b20的温度值 实际温度值返回 同时改变temp_zero_below_flag的值 如果是0 说明是0度以下

void key_pro(void);

void display_pro(void);

void pid_pro(void);

void dis_4_line_as_null(void);

void dis_pid_self_value(void);

float read_max6675_temper(void);// 利用max6675读k探头的温度 返回最终温度的1倍

void PWM_clock(uchar clock);

void PWM_start(uchar module,uchar mode);

void set_pwm_value(uchar value);//0--255之间         value越大,占空比越高 输出电压也越大 40-->0.8v 237-->4.6v 




//hhhhhhhhhhhhhhhhhhhhhhhhhhh

////////////////////////////////////////////////////////

//中断函数ttttttttttttttttttttttttttttt

void tm0_isr(void) interrupt 1 using 1  //1ms

{


TL0 = 0x20;                //设置定时初值

TH0 = 0xD1;                //设置定时初值

        

time0_temp1++;

if(time0_temp1 % 2 == 0 )//2ms

        {

        

        pid_con_10ms_flag = 1;

        

        }

if(time0_temp1 >= 10 )//10ms

        {

        time0_temp1 = 0;

        time0_10ms_flag = 1;

        

        }


time0_temp2++;


if(time0_temp2 % 200  == 0)//200ms

        {

        get_now_temp_flag   = 1;

        }


if(time0_temp2 % 200  == 0)//200ms

        {

        //get_now_temp_flag   = 1;

        

        pid_self_sec_flag   = 1;

        

        pwm_con_time_flag   = 1;

        enable_pid_sec_flag = 1;

        special_dis_once_flag = 1;

        

        }


if(time0_temp2 >= 1000 )//1s         如果要想1000对应1s 那么中间不能有关中断的行为发生

        {

        time0_temp2 = 0;

        global_sec++;

        global_sec_flag = 1;

        

        three_dot_dis_flag  ^= 1;

    

        soft_dis_flag = 1;//软启动

        

        //ssr_con_1;delay_ms(10);ssr_con_0;//test

        

        }


}



void PCA_Intrrpt(void) interrupt 7 //pwm 的中断

{

if(CCF0) CCF0=0;

if(CCF1) CCF1=0;   //软件清零 

if(CF)   CF=0;     //软件清零 

}




////////////////////////////////////////////////////////

//函数


void Timer0Init(void)                //1毫秒@12.000MHz  定时器0

{

        AUXR |= 0x80;        //定时器时钟1T模式

        TMOD &= 0xF0;        //设置定时器模式

        TMOD |= 0x01;        //设置定时器模式

        TL0 = 0x20;                //设置定时初值

        TH0 = 0xD1;                //设置定时初值

        TF0 = 0;                //清除TF0标志

        TR0 = 1;                //定时器0开始计时

        ET0 = 1;        //enable timer0 interrupt   

}



void io_init(void)

{


P3M0 = 0x00 ;   //  0000  0000  

P2M0 = 0xf0 ;   //  1111  0000  低四位为按键 

P1M0 = 0xff ;   //  1111  1111  强推挽输出          lcd 及 ssr驱动

P0M0 = 0x00 ;   //  0000  0000  强推挽输出


key_1_in;

key_2_in;

key_3_in;

key_4_in;


ssr_con_out;


lcd_s_12864_cs_out;

lcd_s_12864_reset_out;

lcd_s_12864_rs_out;

lcd_s_12864_sda_out;

lcd_s_12864_sck_out;

lcd_s_12864_light_out;


lcd_s_12864_cs_0; 

lcd_s_12864_reset_0; 

lcd_s_12864_rs_0; 

lcd_s_12864_sda_0; 

lcd_s_12864_sck_0;

lcd_s_12864_light_0;


max6675_so_in;

max6675_sck_out;

max6675_cs1_out;

cs1_1;


pwm_con_out;

pwm_con_0;


}




void power_on_event(void)//eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ..[12]
关键字:单片机  PID算法  MAX6675  热电偶温控 引用地址:单片机PID算法MAX6675热电偶温控项目

上一篇:两路学习型风扇遥控开关带自然风 单片机源程序+电路
下一篇:请工程化,定制化你的单片机代码

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved