TSIC506驱动程序

测试使用的MCU 型号

  • STC15F104W
  • 内部架构
    在这里插入图片描述

传感器型简介

在这里插入图片描述

传感器原理图

在这里插入图片描述

TSIC506 主驱动代码

  • config.h 文件:主要配置系统时钟主频
// ------------------config.h---------------------
#ifndef		__CONFIG_H
#define		__CONFIG_H
#include	"STC15Fxxxx.H"

//#define MAIN_Fosc		 5529600L	//定义主时钟	 110 ~ 4800
#define MAIN_Fosc		11059200L	//定义主时钟	 110 ~ 9600
//#define MAIN_Fosc		12000000L	//定义主时钟	 110 ~ 9600
//#define MAIN_Fosc		22118400L	//定义主时钟	 220 ~ 19200
//#define MAIN_Fosc		24000000L	//定义主时钟	 220 ~ 19200
//#define MAIN_Fosc		33177600L	//定义主时钟	 220 ~ 38400

// 数据类型定义
typedef bit BOOL;
typedef unsigned char uchar;
typedef unsigned int uint;

#define TRUE  1
#define FALSE 0
#define Main_Fosc_KHZ	(MAIN_Fosc / 1000)

#endif
  • tsic506.h 文件:声明tsic506外部公开的函数
// ------------------tsic506.h---------------------
#ifndef __TSIC506_H
#define __TSIC506_H
#include "config.h"

sbit DQ = P3^3;
BOOL tsic506_init(void);    // 模块初始化函数
BOOL Check_Parity(uint value);
uint read_byte(void);
BOOL getTSIC_Temp (uint *temp_value16);
#endif /* __TSIC506_H */
  • tsic506.c 文件:定义tsic06相关驱动代码
// ------------------tsic506.c---------------------
#include <tsic506.h>
#include <delay.h>

// 初始化函数
BOOL tsic506_init()
{
    DQ = 1;
    while(!DQ);
    return TRUE;
}
// 读取一次总线上的数据
uint read_byte(void)
{
    uchar i;
    uint temp_value = 0;
    // 等待开始信号
    while(DQ == 1);  // 等待总线被从机拉低
    while(DQ == 0);  // 等待就绪
    
    // 在下降沿读取8位数据+1位奇偶校验位
    for (i = 0; i < 9; i++)
    {
        while(DQ == 1);   // 等待下降沿产生,以读取总线
        delay_5us(12);
        if (DQ == 1)
        {
            temp_value |= 1 << (8-i); // 取一个位,从高位开始存
        }
        else
        {
            while(DQ == 0);  // 等待总线再次拉高,便于下次产生下降沿
        }
    }
    
    return temp_value;
}
// 检查校验位是否为1
BOOL Check_Parity(uint value)
{
    uchar i;
    uchar parity = 0;
    
    for (i = 0; i < 9; i++)
    {
        if (value & (1 << i))
        {
            parity++;
        }
    }
    if (parity % 2)
    {
        return FALSE;
    }
    
    return TRUE;  
}
// 获取温度
BOOL getTSIC_Temp (uint *temp_value16)
{
    uint temp_value1 = 0;
    uint temp_value2 = 0;
    uint Temperature;
    
    temp_value1 = read_byte();
    temp_value2 = read_byte();
    
    // 校验温度数据高字节
    while(!Check_Parity(temp_value1))
    {
        return FALSE;
    }
    // 校验温度数据低字节
    while(!Check_Parity(temp_value2))
    {
        return FALSE;
    }
 
    // 删除校验位
    temp_value1 >>= 1;
    temp_value2 >>= 1;
    
    Temperature = (temp_value1 << 8) | temp_value2;
    *temp_value16 = Temperature;
    
    return TRUE;
}
  • 延时函数源文件和头文件:定义自适应延时函数
// 头文件内容
#ifndef __DELAY_H
#define __DELAY_H
#include "config.h"

#define MS_STEP (Main_Fosc_KHZ / 14)

void delay_ms(unsigned int ms);
void delay_5us(uchar step); /* 11.0592M晶振,1T单片机 */

#endif /* __DELAY_H */

//////////////////////////////////////////////////////////////////////
// C文件内容
#include <delay.h>

/*
 * @brief:自适应毫秒延时函数,理论定时范围1~65535
 */
void delay_ms(unsigned int ms)
{
     unsigned int i;
	 do{
	      i = MS_STEP;
		  while(--i);   // 14T per loop
     }while(--ms);
}
/* 1T单片机,主频11.0592M,延时函数,延时10us */
void delay_5us(uchar step)   // 误差 -0.053530092593us
{
    unsigned char a;
    while(step-- > 0)
    {
        for(a=1;a>0;a--);
    }
}

  • 主函数调用示例程序
#include <uart.h>
#include <delay.h>
#include <tsic506.h>

void main()
{
    uint temp_value;
    float Temp_float;
    uart_init();				// UART模块的初始变量
    tsic506_init();
    while(1)
    {
		if(getTSIC_Temp(&temp_value))
		{
			Temp_float = ((float)temp_value / 2047 * 70) - 10;
			printf("%.2f

",Temp_float);
		}
    }
}

STC15F104W虚拟串口代码实现

  • 由于STC15F104W单片机内部并没有串口外设,故需要自己模拟串口,具体原理可以参考数据手册,这里就不赘述了。
  • uart源文件uart.c
#include <uart.h>

uchar data TBUF = 0, RBUF = 0;
uchar data TDAT = 0, RDAT = 0;
uchar data TCNT = 0, RCNT = 0;	// 发送和接收检测 计数器(3倍速率检测)
uchar data TBIT = 0, RBIT = 0;	// 发送和接收的数据计数器
uchar data t = 0, r = 0;
uchar data Rev_buf[BUFF_SIZE] = "0";
uchar data S_BUF;   // 用于接收串口一个字节的返回值
bit flag = 0;       // 用于标志是否有数据到来

bit  TING, RING;	// 正在发送或接收一个字节
bit  TEND, REND;	// 接收或发送完成的标志位

// UART模块的初始变量	initial UART module variable
void uart_init()
{
	InternalRAM_enable();
	Timer0_1T();
	Timer0_AsTimer();
	Timer0_16bitAutoReload();       // 设置定时器0位16位自动重装模式
	Timer0_Load(Timer0_Reload);
	Timer0_InterruptEnable();
	Timer0_Run();
	EA = 1;
	TING = 0;
	RING = 0;
	REND = 0;
    TEND = 1;
	TCNT = 0;
	RCNT = 0;
}
void uart_send(uchar dat)     // 串口发送一个字节函数
{
   if(TEND)
    {
        TEND = 0;
        TBUF = dat;
        TING = 1;
        while(!TEND);
    }
}
uchar uart_receive(void)     // 接收函数
{
	if (REND)				 // 如果接收完,把接收到的值存入接收S_BUF
	{
		REND = 0;
        if(r < BUFF_SIZE) Rev_buf[r++] = RBUF;
        else r = 0;
        S_BUF = RBUF;
        flag = 1;
	}
    return S_BUF;
}
// 重定向printf,需要重写putchar函数;当包含 stdio.h 头文件时,可以直接和标准C一样使用printf进行格式化输出。
char putchar(char c)
{
    uart_send(c);
    return c;
}
// 发送一串字符串
void uart_printf(uchar * p_buf)
{
    while(*p_buf != '')
    {
        uart_send(*p_buf);
        p_buf++;
    }
}
// 定时器0中断程序for UART 以波特率3倍的速度采样判断 开始位		Timer interrupt routine for UART
void tm0(void) interrupt 1 using 1
{

	if (RING)
	{
		if (--RCNT == 0)				  // 接收数据以定时器的1/3来接收
		{
			RCNT = 3;                     // 重置接收计数器  接收数据以定时器的1/3来接收	reset send baudrate counter
			if (--RBIT == 0)			  // 接收完一帧数据
			{
				RBUF = RDAT;              // 存储数据到缓冲区	save the data to RBUF
				RING = 0;                 // 停止接收			stop receive
				REND = 1;                 // 接收完成标志设置	set receive completed flag
			}
			else
			{
				RDAT >>= 1;			      // 把接收的单b数据 暂存到 RDAT(接收缓冲)
				if (RXB) RDAT |= 0x80;    // shift RX data to RX buffer
			}
		}
	}

	else if (!RXB)		                  // 判断是不是开始位 RXB=0;
	{
		RING = 1;                         // 如果是则设置开始接收标志位 	set start receive flag
		RCNT = 4;                         // 初始化接收波特率计数器       	initial receive baudrate counter
		RBIT = RxBitLenth;                // 初始化接收的数据位数(8个数据位+1个停止位)    initial receive bit number (8 data bits + 1 stop bit)
	}

    if (--TCNT == 0)			          // 发送数据以定时器的1/3来发送
    {
        TCNT = 3;				          // 重置发送计数器   reset send baudrate counter
        if(TING)
        {
            if (TBIT == 0)			      // 发送计数器为0 表明单字节发送还没开始
            {
                TXB = 0;			      // 发送开始位     					send start bit
                TDAT = TBUF;		      // 把缓冲的数据放到发送的buff		load data from TBUF to TDAT
                TBIT = TxBitLenth;	      // 发送数据位数 (8数据位+1停止位)	initial send bit number (8 data bits + 1 stop bit)
            }
            else					      // 发送计数器为非0 正在发送数据
            {
                TDAT >>= 1;		          // 把最低位送到 CY(益处标志位) shift data to CY
                if (--TBIT == 0)	      // 发送计数器减为0 表明单字节发送结束
                {
                    TXB = 1;		      // 送停止位数据
                    TING = 0;		      // 发送停止位    			stop send
                    TEND = 1;             // 置位发送完成标志符      set send completed flag
                }
                else
                {
                    TXB = CY;		      // 发送单b数据				write CY to TX port
                }
            }
        }
    }
}
  • uart头文件uart.h
#ifndef __UART_H

#include "config.h"
#include <stdio.h>                  // 如果内存不够,可以关闭这个头文件的包含,使用自定义的 uart_printf 函数输出字符串

#define BaudRate		9600		// 模拟串口波特率
#define Timer0_Reload	(65536 - MAIN_Fosc / BaudRate / 3)
#define D_RxBitLenth	9		    // 9: 8 + 1 stop
#define D_TxBitLenth	9		    // 9: 1 stop bit
#define BUFF_SIZE 30                // 接受缓冲区大小

sbit RXB = P3^0;                    // define UART TX/RX port
sbit TXB = P3^1;

extern uchar data TBUF, RBUF;
extern uchar data TDAT, RDAT;
extern uchar data TCNT, RCNT;	    // 发送和接收检测 计数器(3倍速率检测)
extern uchar data TBIT, RBIT;	    // 发送和接收的数据计数器
extern uchar data t, r;
extern uchar data Rev_buf[BUFF_SIZE];
extern bit flag;

extern bit  TING, RING;	            // 正在发送或接收一个字节
extern bit  TEND, REND;	            // 发送或接收完成的标志位

#define	RxBitLenth	9	            // 8个数据位+1个停止位
#define	TxBitLenth	9	            // 8个数据位+1个停止位

void uart_init(void);               // 串口初始化函数
void uart_send(uchar dat);          // 发送一个字节函数
uchar uart_receive(void);           // 接收函数
void uart_printf(uchar * p_buf);    // 串口字符串打印

#endif /* __UART_H */

原文地址:https://www.cnblogs.com/veis/p/12486391.html