MAX6675ISA学习笔记-基于linux驱动


目录

1、MAX6675简介

2、基本参数

3、引脚配置

4、参考电路

5、引脚功能描述

6、转换公式

7、读写的格式

8、时序

9、输出的数据内容​

10、模拟程序书写

10.1、引脚配置

10.2、引脚初始化

10.3、模拟SPI接收一个字节的数据

10.4、读取温度数据

10.5、杂项设备编写

10.6、测试程序编写

11、结果

12、总结

 


1、MAX6675简介

         MAX6675 K-型热电偶温湿度检测模块,将K型热电偶信号转换成数字信号。

数据手册:

         MAX6675数据手册


2、基本参数

 接口:采用SPI通信方式,只读模式

数据格式:12-Bit

温度测试范围: -20℃ to +85℃

注意事项:只读模式


3、引脚配置


4、参考电路


5、引脚功能描述

 

 


6、转换公式


7、读写的格式

注意事项:时序


8、时序

注意参数:

最大和最小的时间。


9、输出的数据内容


10、模拟程序书写

10.1、引脚配置

//第一步:设定引脚的宏定义
#define ANALOG_SPI_SCK_GPIO      (PAD_GPIO_A + 12)   //spi时钟引脚SCK
#define ANALOG_SPI_CS_GPIO       (PAD_GPIO_A + 4)    //spi片选引脚CS
#define ANALOG_SPI_MISO_GPIO     (PAD_GPIO_A + 11)   //spi数据接收MISO 

//第二步:定义一个引脚的结构体
struct spi_gpio
{
	int gpio;
	char *name;
};

//赋值
struct spi_gpio mygpio[] = {
    [0]={ANALOG_SPI_SCK_GPIO, "ANALOG_SPI_SCK_GPIO"},
    [1]={ANALOG_SPI_CS_GPIO, "ANALOG_SPI_CS_GPIO"},
    [2]={ANALOG_SPI_MISO_GPIO, "ANALOG_SPI_MISO_GPIO"},
};

//定义的结构体的大小
#define MYGPIONUM ARRAY_SIZE(mygpio) 

10.2、引脚初始化

/*
@第一步:设置时钟引脚输出电平
**/
void spi_scl_output_level(bool level)
{
	gpio_set_value(ANALOG_SPI_SCK_GPIO, level);  
}

/*
@第二步:设置数据引脚为输入模式,并且读取引脚电平\
**/
bool spi_rxd__level(void)
{
	return gpio_get_value(ANALOG_SPI_MISO_GPIO);
}


/*
@第三步:设置片选的电平
**/
void spi_cs__level(bool level)
{
	gpio_set_value(ANALOG_SPI_CS_GPIO,level);
}


/*
@第四步:引脚初始化配置
**/
bool spi_gpio_config(void)
{
	int ret, i;
	mutex_init(&lock);
	
    //1、资源申请
	for(i=0; i<MYGPIONUM; i++)
	{
		ret = gpio_request(mygpio[i].gpio, mygpio[i].name);
		if (ret) 
		{
			debug("<0>""%s: request GPIO %d for keyforled failed, ret = %d\n", mygpio[i].name, mygpio[i].gpio, ret);
			goto error;
		}

	}
	
	
	//2、时钟引脚设置为输出模式,默认为高电平
	ret = gpio_direction_output(mygpio[0].gpio,1);  
	if(ret < 0){
		debug("<0>""spi0.scl_gpio=%d config  error %s %d\n",mygpio[0].gpio,__FUNCTION__,__LINE__);
		return 0;
	}
	
    //3、MISO设置为输入模式,接收数据(根据数据手册,只读模式)
	ret = gpio_direction_input(mygpio[2].gpio);  
	if(ret < 0){
		debug("<0>""spi0.rxd_gpio=%d config  error %s %d\n",mygpio[2].gpio,__FUNCTION__,__LINE__);
		return 0;
	}
	
	//4、设置片选引脚为输出模式,默认输出格式为高电平	
	ret = gpio_direction_output(mygpio[1].gpio ,1);  
	if(ret < 0){
		debug("<0>""spi0.frm_gpio=%d config  error %s %d\n",mygpio[1].gpio,__FUNCTION__,__LINE__);
		return 0;
	}
	
	return 1;
error:
	for(;i>0;i--)
		gpio_free(mygpio[i].gpio);
	return 0;
}

10.3、模拟SPI接收一个字节的数据

/*接收一个字节的数据
*/
unsigned char gec6818_analog_spi_recv_byte(void)
{	
	unsigned char counter = 0;
	unsigned char data = 0;
	mutex_lock(&lock);
	for(counter=0x80; counter!=0; counter>>=1)
	{
		spi_scl_output_level(0);
		udelay(ANALOG_SPI_CLK_PW);
		spi_scl_output_level(1);
		if(spi_rxd__level() == 1)
		{
			data |= counter;
		}
		else
		{
			data &= ~counter;	
		}
		udelay(ANALOG_SPI_CLK_PW);
	}
	mutex_unlock(&lock);
	return data;
}

10.4、读取温度数据

/**
*读取一个字节的数据
* reg :寄存器地址
*/
uint16_t spi_read_reg_byte(void)
{
	uint16_t data=0;
	spi_cs__level(0);
	data = gec6818_analog_spi_recv_byte ();
	data <<= 8;
	data |= gec6818_analog_spi_recv_byte ();
	spi_cs__level(1);
	if(data & 4)
	{
		data = 4095;
		debug("<0>""waring !!!! No thermocouple\r\n");
	}
	else
	{
		data = data >> 3; //根据数据手册得到
	}
	data = data&0x0FFF;
	debug("<0>""recive data is %d\r\n",data);
	return data;		
}

10.5、杂项设备编写

static ssize_t gec6818_max6675_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
 	int ret;
	uint16_t value = 0;
	
	value = spi_read_reg_byte();
		
	ret = copy_to_user(buf, &value, sizeof(value));
	if(ret < 0){
		debug("<0>""%s %d err copy max6675 value to user\n",__FUNCTION__,__LINE__);
		return -EFAULT;
	}
	return ret;
}

static const struct file_operations gec6818_max6675_fops = {
	.owner = THIS_MODULE,
	.read = gec6818_max6675_read,
};


static struct miscdevice miscdev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICENAME,
	.fops = &gec6818_max6675_fops,
};



static int __init gec6818_max6675_init(void)
{
	char ret;
	ret = spi_gpio_config();
	if(ret == 0)
	{
		debug("<0>""spi init error %s %d \r\n",__FUNCTION__,__LINE__);
		goto err;
	}

	ret = misc_register(&miscdev);
	if(ret < 0){

		debug("<0>""misc driver register error\n");
		goto err;
	}
	spi_read_reg_byte();
	printk("<0>""max is init OK\r\n");
	return 0;

err:	
	return ret; //返回错误的原因
}

static void __exit gec6818_max6675_exit(void)
{
	int i;
	for(i=0;i<MYGPIONUM;i++)
		gpio_free(mygpio[i].gpio);
	misc_deregister(&miscdev);
	printk("<0>""gec6818_max6675_exit\n");	
}


module_init(gec6818_max6675_init);//入口函数
module_exit(gec6818_max6675_exit);//出口函数

MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("max6675 driver for GEC6818");
MODULE_LICENSE("GPL"); //符合GPL协议
MODULE_VERSION("V1.0");

 

10.6、测试程序编写

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <poll.h>

int fd_max = 0;

unsigned short max_value;  

int main(void)
{
	int ret;
	char num=0;
	
	fd_max = open("/dev/max6675", O_RDWR);
	if(fd_max < 0)
	{
		perror("open max_drv driver");
		return -1;		
	}
	while(1)
	{
		ret = read(fd_max,&max_value,sizeof(max_value));
		if(ret<0)
		{
			perror("read error\n");
			return -1;
		}
		
		printf("max_value = %.2f \n",(float)(max_value*1024.0)/4096);	
		sleep(1);
		num++;
		if(num>20)
			break;
	}
	close(fd_max);
	
	return 0;
}

11、结果

12、总结

     通过对MAX6675K型热电偶的学习,对SPI通信的应用运用更加熟悉。

完整程序

Guess you like

Origin blog.csdn.net/ZOROE123/article/details/105774184