×
单片机 > 单片机程序设计 > 详情

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

发布时间:2020-08-25 发布时间:
|

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;                //设置定时初值

TH


关键字:单片机  PID算法  MAX6675  热电偶温控

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址