久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機PID溫控源碼,變量值為什么總是不對?
[打印本頁]
作者:
saintsus
時間:
2019-3-27 16:35
標題:
單片機PID溫控源碼,變量值為什么總是不對?
求助論壇大神,為什么我學習改寫別人的PID溫控源碼代碼,其中PWM 和temp_PID.SetPoint 總是不對,用串口調試的結果總是不對。
輸出結果: PWM:100 PWM:12288 PWM_P: 設置溫度:30 實?飾露?2619 temp_s:3000 temp_PID.SetPoint:
按理說我用了這樣的 PWM應該在0到100之間temp_PID.SetPoint:應該是3000才對可是輸出為什么不是,實在查不出原因,請大神指正。
引腳分配 lcd lcddata: P0
lcd_e: P2^7
lcd_rs: P2^6
lcd_rw: P2^5
設置按鍵 limit_choise: P //溫度上下限選擇按鍵
increase_temperature P //增加溫度限值按鍵
reduce_temperature P //減少溫度限值按鍵
蜂鳴器報警 warning P
溫度傳感器 temperature_sensor P
制熱 heatting P
制冷 refrigerating P
LED顯示 normal P //正常溫度指示燈
high_temperature P //高溫指示燈
low_temperature P //低溫指示燈
單片機源程序如下:
/*******************************************************************************
* 包含頭文件
*******************************************************************************/
#include <main.h>
/*******************************************************************************
* 變量聲明
*******************************************************************************/
uint PWM=0;
uint PWM_P;//PWM_P 功率占比顯示
uchar time_value=0;
uchar time_heatting=0;
uint temp_m=0; //實際溫度
uint up_limit_temp=30;
uint temp_s; //設置溫度*100
PID temp_PID;
uchar massage[]=0;
/*******************************************************************************
* 函數名 : void main()
* 函數功能 : 主函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void main()//主函數
{
init();//初始化函數
temp_PID.Proportion =150; // 設置 PID 系數
temp_PID.Integral =5;
temp_PID.Derivative =2;
while(1)
{
temp_s = up_limit_temp*100;
temp_PID.SetPoint = temp_s;
if(time_value==10) //讀取溫度
{
temp_m=get_temp(Ds18b20ReadTemp());
}
if(time_value==50)
{
if(temp_s-temp_m>=100)
{
PWM=100;
}
else
{
PWM = pid_calc(&temp_PID,temp_m);
if( PWM>=100 ) PWM=100;
else if(PWM<=1) PWM=1;
}
}
if(time_value==60) //顯示溫度
{
display_real_temp(temp_m);
}
if(time_value==70)
{
send_string(" PWM:");
DtoA(PWM,massage);
send_string(massage);
/*
PWM_P = PWM;
LcdWriteCom(0x80+0X40+0x0C);
LcdWriteData('0'+PWM_P/100);
LcdWriteCom(0x80+0X40+0x0D);
LcdWriteData('0'+PWM_P%100/10);
LcdWriteCom(0x80+0X40+0x0E);
LcdWriteData('0'+PWM_P%10);
*/
send_string(" PWM:");
DtoA(PWM,massage);
send_string(massage);
send_string(" PWM_P:");
DtoA(PWM_P,massage);
send_string(massage);
send_string(" 設置溫度:");
DtoA(up_limit_temp,massage);
send_string(massage);
send_string(" 實際溫度:");
DtoA(temp_m,massage);
send_string(massage);
send_string(" temp_s:");
DtoA(temp_s,massage);
send_string(massage);
send_string(" temp_PID.SetPoint:");
DtoA(temp_PID.SetPoint,massage);
send_string(massage);
send_string("\n");
}
if(time_value>=100) //指令執行時間,一個單位時間是10ms
{
time_value=0;
}
if(time_heatting >= 500) time_heatting = 0;
if(time_heatting <= PWM*5)
{
heatting=1;
}
else
{
heatting=0;
}
}
}
/*******************************************************************************
* 函數名 : void init()
* 函數功能 : 初始化函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void init()//初始化函數
{
uint i,j;
Ds18b20Init();//Ds18b20初始化
//heatting=0;//不制熱
IT0Init();
IT1Init();
InitUart0();
InitTimer0();//定時器初始化
pid_init (&temp_PID);//PID初始化
LcdInit();//LCD初始化函數
LcdWriteCom(0x80);//第一行顯示
j=strlen(num1);
for(i=0; i<j; i++)
{
LcdWriteData(num1[i]);
delay_ms(1);
}
LcdWriteCom(0x80+0x40);//第二行顯示
j=strlen(num2);
for(i=0; i<j; i++)
{
LcdWriteData(num2[i]);
delay_ms(1);
}
LcdWriteCom(0x04); //關閉寫一個指針加1
}
/*******************************************************************************
* 函數名 : uint get_temp(uint temp)
* 函數功能 : 計算溫度函數
* 輸入 : 溫度
* 輸出 : 溫度
*******************************************************************************/
uint get_temp(uint temp)//計算溫度函數
{
float tp;
tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
//如果溫度是正的那么,那么正數的原碼就是補碼它本身
temp=tp*0.0625*100+0.5;
//留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
//后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
//算加上0.5,還是在小數點后面。
return temp;
}
/*******************************************************************************
* 函數名 : void display_real_temp(uint temp)
* 函數功能 : 實時溫度顯示函數
* 輸入 : 溫度
* 輸出 : 無
*******************************************************************************/
void display_real_temp(uint temp)//實時溫度顯示函數
{
uchar datas[] = {0, 0, 0, 0}; //定義數組
datas[0] = temp % 10000 / 1000;
datas[1] = temp % 1000 / 100;
datas[2] = temp % 100 / 10;
datas[3] = temp % 10;
LcdWriteCom(0x80+0x0a); //寫地址 80表示初始地址
LcdWriteData('0'+datas[0]); //十位
LcdWriteCom(0x80+0x0b); //寫地址 80表示初始地址
LcdWriteData('0'+datas[1]); //個位
LcdWriteCom(0x80+0x0d); //寫地址 80表示初始地址
LcdWriteData('0'+datas[2]); //顯示小數點
LcdWriteCom(0x80+0x0e); //寫地址 80表示初始地址
LcdWriteData('0'+datas[3]); //顯示小數點
}
/*******************************************************************************
* 函數名 : void InitTimer0(void)
* 函數功能 : 定時器初始化函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void InitTimer0(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;//設置定時模式1
TH0 = 0xD8;
TL0 = 0xF0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
/*******************************************************************************
* 函數名 : void Timer0Interrupt(void) interrupt 1
* 函數功能 : 定時器中斷函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void Timer0Interrupt(void) interrupt 1
{
TH0 = 0xD8;
TL0 = 0xF0;
time_value++; //功能計數值+1
time_heatting++; //加熱計數值+1
}
/*******************************************************************************
* 函數名 : void INIT0(void) interrupt 0
* 函數功能 : 外部中斷0執行函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void INIT0(void) interrupt 0
{
delay_ms(5);
if (increase_temperature == 0)
{
while(increase_temperature == 0);
if(up_limit_temp<=110)
{
up_limit_temp=up_limit_temp+5;
LcdWriteCom(0x80+0X40+0x03);
LcdWriteData('0'+up_limit_temp%1000/100);
LcdWriteCom(0x80+0X40+0x04);
LcdWriteData('0'+up_limit_temp%100/10);
LcdWriteCom(0x80+0X40+0x05);
LcdWriteData('0'+up_limit_temp%10);
}
}
}
/*******************************************************************************
* 函數名 : void INIT1(void) interrupt 2
* 函數功能 : 外部中斷1執行函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void INIT1(void) interrupt 2
{
delay_ms(5);
if (reduce_temperature == 0)
{
while(reduce_temperature == 0);
if(up_limit_temp>=20)
{
up_limit_temp=up_limit_temp-5;
LcdWriteCom(0x80+0X40+0x03);
LcdWriteData('0'+up_limit_temp%1000/100);
LcdWriteCom(0x80+0X40+0x04);
LcdWriteData('0'+up_limit_temp%100/10);
LcdWriteCom(0x80+0X40+0x05);
LcdWriteData('0'+up_limit_temp%10);
}
}
}
/*******************************************************************************
* 函數名 : void IT0Init(void)
* 函數功能 : 外部中斷0初始化
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void IT0Init(void)
{
IT0 = 0;//0為電平,1為下降沿
EX0 = 1;//外部中斷1
}
/*******************************************************************************
* 函數名 : void IT1Init(void)
* 函數功能 : 外部中斷1初始化
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void IT1Init(void)
{
IT1 = 0;//0為電平,1為下降沿
EX1 = 1;//外部中斷0
}
/*******************************************************************************
* 函數名 : void InitUart0(void)
* 函數功能 : 串口中斷初始化
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void InitUart0(void)
{//設計波特率:4800bps;實際波特率:4464bps
TMOD&=0x0F;
TMOD|=0x20;
SCON=0x50;
PCON|=0x80;
TH1 = 0xF3;
TL1 = 0xF3;
ES = 1; //使能串口中斷 ,無論是TI/RI出現,只要中斷打開,單片機就進入中斷函數。
TR1 = 1;
//ET1 = 0;//禁止T1中斷
}
/*******************************************************************************
* 函數名 : void IT1Init(void)
* 函數功能 : 串口中斷函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void Usart() interrupt 4
{
//uchar receiveData;
//receiveData=SBUF;//出去接收到的數據
RI = 0;//清除接收中斷標志位
//SBUF=receiveData;//將接收到的數據放入到發送寄存器
//while(!TI); //等待發送數據完成
//TI=0; //清除發送完成標志
//massage[0]=0;
}
/*******************************************************************************
* 函數名 : void send_byte(uchar by)
* 函數功能 : 串口發送字節函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void send_byte(uchar by)
{
SBUF = by;
while(!TI);//當寫下這句的時候,就不要在中斷函數里面在寫TI = 0;這句了,不然進入中斷函數將TI清零之后,程序就會一直卡在這里
TI = 0; //在這里將TI清零
}
/*發送一個字符串*/
/*******************************************************************************
* 函數名 : void send_string(uchar *p)
* 函數功能 : 串口發送字符串函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void send_string(uchar *p)
{
while(*p!= '\0')
{
send_byte(*p);
p++;
}
}
/*******************************************************************************
* 函數名 : void DtoA(unsigned long dat, unsigned char* buffer)
* 函數功能 : 串口發送字符串函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void DtoA(uint dat, unsigned char* buffer)
{
uint tmp = 0;
char length = 0;
tmp = dat;
while(tmp != 0)//求出數字的實際長度
{
tmp = tmp/10;
length++;
}
buffer[length] = '\0';//長度數為字符串截止位
length--;
while(length >= 0)//數字的低位放入數組的高位
{
tmp = dat%10;
buffer[length--] = 0x30|tmp;
dat = dat/10;
}
}
復制代碼
全部資料51hei下載地址:
PID恒溫控制器.zip
(113.68 KB, 下載次數: 20)
2019-3-27 16:34 上傳
點擊文件名下載附件
作者:
ld345649543
時間:
2019-4-25 12:58
沒有看到PID實現的函數呀!
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
丁香六月激情
|
91久久精品日日躁夜夜躁国产
|
精品国产免费一区二区三区五区
|
福利网站在线观看
|
欧美精品久久久
|
中文字幕日韩欧美
|
亚洲精品一区在线观看
|
91久久国产精品
|
热久久性
|
黄色片a级
|
日韩在线综合
|
国产成人精品一区二区三区视频
|
一区二区高清在线观看
|
亚洲手机视频在线
|
亚洲欧洲成人
|
天天色影视综合
|
精品九九九
|
亚洲综合在线一区
|
日韩精品成人一区二区三区视频
|
成人av免费
|
欧美成人一区二区三区片免费
|
黄色在线免费观看
|
国产日韩欧美中文
|
福利片一区二区
|
视频一区在线
|
久久久久久久久久久久亚洲
|
国产在线二区
|
日韩欧美一级
|
天天色av
|
一级黄色在线
|
99中文字幕
|
午夜精品一区
|
99精品一区二区三区
|
亚洲精品白浆高清久久久久久
|
九九在线精品视频
|
国产亚洲一区二区三区在线观看
|
午夜免费福利电影
|
亚洲视频中文字幕
|
精品1区
|
www.99久久.com
|
欧美在线
|