目录
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、总结
MAX6675 K-型热电偶温湿度检测模块,将K型热电偶信号转换成数字信号。
数据手册:
MAX6675数据手册
接口:采用SPI通信方式,只读模式
数据格式:12-Bit
温度测试范围: -20℃ to +85℃
注意事项:只读模式
注意参数:
最大和最小的时间。
//第一步:设定引脚的宏定义
#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)
/*
@第一步:设置时钟引脚输出电平
**/
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""%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;
}
/*接收一个字节的数据
*/
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;
}
/**
*读取一个字节的数据
* 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;
}
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""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");
#include
#include
#include
#include
#include
#include
#include
#include
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;
}
通过对MAX6675K型热电偶的学习,对SPI通信的应用运用更加熟悉。
完整程序