找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1280|回复: 1
打印 上一主题 下一主题
收起左侧

显示屏要显示加了卡尔曼滤波和没加2个温度,怎么结合2个代码,一直只显示没加卡滤...

[复制链接]
跳转到指定楼层
楼主
#include<reg52.h>

#include <intrins.h>
typedef unsigned char uint8;
#define uint unsigned int
#define uchar unsigned char
sbit DQ = P3^3;                // 定义DQ引脚为P3.3
uchar code  Bw[10]= {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//百位编码
ucharcodeXsw[16]={0x30,0x31,0x31,0x32,0x33,0x33,0x34,0x34,0x35,0x36,0x36,0x37,0x38,0x38,0x39,0x39};//小数位编码
sbit RS = P2^0 ;
sbit RW = P2^1 ;
sbit EN = P2^2 ;
sbit BUSY = P0^7;
uchar wendu;
uchar temp_g,temp_d;
unsigned char code word1[]={"Temperature:"};
void delay(uint xms)
{
uint i,j;
for(i=xms;i>0;--i)
for(j=110;j>0;--j);   
}
void Delayus(int t) //在11.059MHz的晶振条件下调用本函数需要24μs ,然后每次计数需16μs
{
int s;
for (s=0; s<t;s++);
}
void wait(void)// 等待繁忙标志
{
P0 = 0xFF;
do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}while (BUSY == 1);
EN = 0;
}
void w_dat(uint8 dat)// 写数据
{
wait();
EN = 0;
P0 = dat;
RS = 1;
RW = 0;
EN = 1;
EN = 0;
}
void w_cmd(uint8 cmd)// 写命令
{
wait();
EN = 0;
P0 = cmd;
RS = 0;
RW = 0;
EN = 1;
EN = 0;
}
void w_string(uint8 addr_start, uint8 *p)// 发送字符串到LCD
{
w_cmd(addr_start);
while (*p != '\0')
{
w_dat(*p++);
}
}
void Init_LCD1602(void)// 初始化1602
{
w_cmd(0x38);  // 16*2显示,5*7点阵,8位数据接口
w_cmd(0x0c);  // 显示器开、光标开、光标允许闪烁
w_cmd(0x06);  // 文字不动,光标自动右移
w_cmd(0x01);  // 清屏
}
uchar Reset()//完成单总线的复位操作。
{
uchar d;
DQ = 0;          // 将 DQ 线拉低
Delayus(29);     // 保持 480μs .复位时间为480μs,因此延时时间为(480-24)/16 = 28.5,取29μs。
DQ = 1;         // DQ返回高电平
Delayus(3);     // 等待存在脉冲.经过70μs之后检测存在脉冲,因此延时时间为(70-24)/16 = 2.875,取3μs。
d = DQ;         // 获得存在信号
Delayus(25);     // 等待时间隙结束
return(d);     // 返回存在信号,0 = 器件存在, 1 = 无器件
}
void write_bit(uchar bitval)//向单总线写入1位值:bitval
{
DQ = 0;     // 将DQ 拉低开始写时间隙
if(bitval==1)
DQ =1;     // 如果写1,DQ 返回高电平
Delayus(5);// 在时间隙内保持电平值,
DQ = 1;     // Delayus函数每次循环延时16μs,因此Delayus(5)=5*16+24=104μs
}   
void ds18write_byte(char val)//向单总线写入一个字节值:val
{
uchar i;
uchar temp;
for (i=0; i<8; i++)// 写入字节, 每次写入一位
{   
temp = val>>i;        
temp &= 0x01;        
write_bit(temp);
}
Delayus(5);
}
uchar read_bit()//从单总线上读取一位信号,所需延时时间为15μs,因此无法调用前面定义
{                    //的Delayus()函数,而采用一个for()循环来实现延时。
uchar i;
DQ = 0;            //将DQ 拉低开始读时间隙
DQ = 1;             // 然后返回高电平
for (i=0; i<3; i++);     // 延时15μs
return(DQ);             // 返回 DQ 线上的电平值
}
uchar ds18read_byte()//从单总线读取一个字节的值
{
uchar i;
uchar value = 0;
for (i=0;i<8;i++)
{                  // 读取字节,每次读取一个字节
if(read_bit())
value|=0x01<<i;     // 然后将其左移
Delayus(6);                    
}
return(value);
}
int Readtemperature()//如果单总线节点上只有一个器件则可以直接掉用本函数。如果节点上有多个器
{                    //件,为了避免数据冲突,应使用Match ROM函数来选中特定器件。
uchar temp_d,temp_g,k,get[2],temp;
Reset();
ds18write_byte(0xcc);                     // 跳过 ROM
ds18write_byte(0x44);                     // 启动温度转换
Delayus(5);
Reset();
ds18write_byte(0xcc);                     // 跳过 ROM
ds18write_byte(0xbe);                     // 读暂存器
for (k=0;k<2;k++)
{
get[k]=ds18read_byte();
}
temp_d = get[0];//低位
temp_g = get[1];//高位
if((temp_g&0xf0)==0xf0) //正负号判断
{
temp_d=~temp_d;
if(temp_d==0xff) //保证-48(1111110100000000)、-32和-16显示正常
{
temp_d=temp_d+0x01;//00000000
temp_g=~temp_g;//00000010
temp_g=temp_g+0x01;//00000011
}
else
{
temp_d=temp_d+0x01;
temp_g=~temp_g;      
}      
w_cmd(0xc5);
w_dat(Xsw[temp_d&0x0f]);    //查表得小数位的值
temp=((temp_d&0xf0)>>4)|((temp_g&0x0f)<<4);
w_cmd(0xc1);
w_dat(0x2d);//负号            
}
else  //正数
{
w_cmd(0xc5);
w_dat(Xsw[temp_d&0x0f]);    //查表得小数位的值
temp=((temp_d&0xf0)>>4)|((temp_g&0x0f)<<4);
w_cmd(0xc1);
w_dat(Bw[temp/100]);      
}
return temp;
}   
main()
{
Init_LCD1602();
w_string(0x80,word1);   
while (1)
{
wendu=Readtemperature();
temp_g=wendu%100/10+'0';
temp_d=wendu%10+'0';
w_cmd(0xc2);
delay(2);
w_dat(temp_g);
delay(2);
w_dat(temp_d);
delay(2);
w_cmd(0xc4);
delay(2);
w_dat(0x2e);//小数点
delay(2);
w_cmd(0xc6);
delay(2);
w_dat(0xdf);//温度符号
delay(2);
w_dat(0x43);
}
}




卡尔曼滤波部分代码
#include "KalmanFilter.h"
float R=0.999f;
float Q=0.001f;
float x0=0.0f;
float p0=1555.0f;
float k,x,p;
float KalmanFilter(float Measure)
{
x=x0;
p=p0+Q;
k=p/(p+R);
x=x+k*(Measure-x);
p=(1-k)*p;
p0=p;
x0=x;
return x;
}
#include "KalmanFilter.h"
float R=0.999f;
float Q=0.001f;
float x0=0.0f;
float p0=1555.0f;
float k,x,p;
float KalmanFilter(float Measure)
{
x=x0;
p=p0+Q;
k=p/(p+R);
x=x+k*(Measure-x);
p=(1-k)*p;
p0=p;
x0=x;
return x;
}

仿真图.png (26.88 KB, 下载次数: 71)

仿真图.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2020-1-7 11:19 | 只看该作者
用DS18b20测温,这样处理数据有画蛇添足之嫌。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表