找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机检测4~20mA PT100传感器程序

[复制链接]
跳转到指定楼层
楼主
ID:731890 发表于 2024-1-1 20:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本例程采用宏晶的STC8G1K08单片机来检测输出类型为4~20mA PT100传感器的程序,在检测中使用XPT2046作为AD的检测芯片,XPT2046具有4路12位的AD检测输入端,因此最大可检测4路传感器,本例程中我们只使用了其中1路。检测时使用了中值滤波算法。先看一下XPT2046的驱动程序:

/****************************************************************************
*函数名:SPI_Write
*输  入:dat:写入数据
*输  出:无
*功  能:使用SPI写入数据
****************************************************************************/

void SPI_Write(uchar dat)
{
        uchar i;
        CLK = 0;
        delay_us(2);
        for(i=0; i<8; i++)
        {
                DIN = dat >> 7;          //放置最高位
                dat <<= 1;
                CLK = 0;                        //上升沿放置数据
                delay_us(2);
                CLK = 1;
    delay_us(2);
        }
}
/****************************************************************************
*函数名:SPI_Read
*输  入:无
*输  出:dat:读取 到的数据
*功  能:使用SPI读取数据
****************************************************************************/

uint SPI_Read(void)
{
        uint i, dat=0;
        CLK = 0;
        delay_us(2);
        for(i=0; i<12; i++)                //接收12位数据
        {
                dat <<= 1;
                CLK = 1;
                delay_us(2);
                CLK = 0;
    delay_us(2);
                dat|= DOUT;

        }
        return dat;        
}

/****************************************************************************
*函数名:Read_AD_Data
*输  入:cmd:读取的X或者Y
*输  出:endValue:最终信号处理后返回的值
*功  能:读取触摸数据
****************************************************************************/
uint Read_AD_Data(uchar cmd)
{
        uint AD_Value;
        CS  = 0;
        delay_us(2);
        CLK = 0;
        delay_us(2);
        SPI_Write(cmd);
        delay_us(6);//延时等待转换结果        
        CLK = 1;          //发送一个时钟周期,清除BUSY
        delay_us(2);
        CLK = 0;
        delay_us(2);
        AD_Value=SPI_Read();
        CS = 1;
        return AD_Value;        
}

下面是它的头文件:
#ifndef          __XPT2046_H_
#define   __XPT2046_H_

#include        "STC8G.H"
#include "delay.h"
#include<intrins.h>


//---定义使用的IO口---//
sbit DOUT = P1^0;          //输出
sbit CLK  = P3^4;          //时钟
sbit DIN  = P3^6;          //输入
sbit CS   = P3^5;          //片选

uint Read_AD_Data(uchar cmd);
uint SPI_Read(void);
void SPI_Write(uchar dat);

#endif


以下是主程序:
#include "STC8G.H"
#include "delay.h"
#include "uart1.h"
#include "XPT2046.h"

#define voltage 5.00
#define ncnt   127                             //采集次数必须为奇数

float sum=0;                                                                //浮点型温度值
float val=0;                                                                //AD采集到的电压值
unsigned int temd;                                                                                //排序中间转换变量
unsigned int temp;                                                                                //用取取缓存中的中间值
xdata unsigned int value_buf[ncnt];                          //AD采集存储缓存
int wendu;                                                                   //整数型温度变量
char count, i,j;                                                //排序计数变量
unsigned char puf[6];


void main()
{

        P_SW1 = 0x10;//RXD/P3.0, TXD/P3.1
        Uart1_Init();
  P1M0 = 0x00;                 //设置为准双向口
        P1M1 = 0X00;
        P3M0 = 0x70;                 //设置为推挽输出
        P3M1 = 0X00;

  while(1)
        {
                //temp = Read_AD_Data(0x94);//AIN0
                //temp = Read_AD_Data(0xD4);//AIN1
                //temp = Read_AD_Data(0xA4);//AIN2
                //temp = Read_AD_Data(0xE4);//AIN3
               
                for (count=0; count<ncnt; count++)                                                                    //连续采集ncnt次
                {
                 value_buf[count]= Read_AD_Data(0x94);             //将采集到的数据存到value_buf中
                }
                        for (j=0;j<ncnt-1;j++)                                                                                                     //将采集到的数据从小到大排列
                        {
                                for (i=0;i<ncnt-j;i++)                                                        //通过for循环排列数据
                                {
                                        if (value_buf[ i] > value_buf[i+1])                                          //如果前一个元素大于后一个元素
                                        {
                                                temd = value_buf[ i];                                                      //则将大的元素赋值给temd
                                                value_buf[ i] = value_buf[i+1];                                            //将小值赋给前一个元素
                                                value_buf[i+1] = temd;                                                    //将大值赋给后一个元素
                                        }
                                }
                        }
                        
                temp=value_buf[(ncnt-1)/2];                                                                                                   //取缓存中的中间值        
                val=temp*voltage/4096.0;                                                                                                   //算出当前电压,5.01是AD基准值,跟据实际电压自行修改
                sum=((250.00*val)/2.40)-112.50;                                                                     //根据公式计算出当前温度,公式: T=(250/2.4)*V-112.5
                wendu=(int)(sum*10);                                                                                                                          //将浮点数*10转换为整数型数据
               
                if(wendu&0x8000)                                                                                                                                    //如果温度为负值
                {
                        wendu=((~wendu)&0x7fff)+1;                                                                                          //则取反加1
                        puf[0]='-';                                                                                                                                 //加上负数标志位'-'
                }        
                else if((wendu/1000)==0){
                        puf[0]=' ';
                }else puf[0]=wendu/1000+0x30;
               
                if(((wendu/1000)==0)&&((wendu%1000/100)==0))                          //如果最高两位都为0
                        puf[1]=' ';                                                                                                                                                    //则不显示
                else puf[1]=wendu%1000/100+0x30;                                                        //否则正常显示数
               
                puf[2]=wendu%1000%100/10+0x30;
                puf[3]='.';
                puf[4]=wendu%1000%100%10+0x30;
   // Uart1_SendString(puf);
               
                //Uart1_SendChar(temp/256);
                //Uart1_SendChar(temp%256);
                delay_ms(300);
                }
}

原理图: 无
仿真: 无
Keil代码: PT00串口.7z (29.44 KB, 下载次数: 14)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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