STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码

STM32+MAX6675利用io口模拟SPI获取实时温度数据程序及代码
本文采用的芯片为STM32F103RCT6
温度芯片为MAX6675
因为芯片的spi口只有3个,有部分需要外接W25Q128/64等等,所剩余的端口大部分重定义和默认的spi功能相对较少,所以采用了模拟spi的方法。
具体STM32数据手册、参考手册和max6675手册可以官网下载

原理图
在这里插入图片描述

代码

max6675.h
#ifndef __MAX6675_H
#define __MAX6675_H
 
#include "stm32f10x.h"
#include "sys.h" 

#define MAX6675_CS_H   GPIO_SetBits(GPIOB,GPIO_Pin_8)
#define MAX6675_CS_L   GPIO_ResetBits(GPIOB,GPIO_Pin_8)
#define MAX6675_CK_H   GPIO_SetBits(GPIOB,GPIO_Pin_11)
#define MAX6675_CK_L   GPIO_ResetBits(GPIOB,GPIO_Pin_11)
#define MAX6675_SO  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
  
void max6675_init(void);			 //初始化max6675模块 
u16 max6675_readRawValue(void);/*按位读取电平的原始数据函数*/
float max6675_readTemperature(void);/*读取温度函数*/
 
 
#endif

max6675.c文件参考

STM32参考手册,第8章GPIO+max6675中文手册

参考手册

max6675
MAX6675的原理及应用
文献里面的
在这里插入图片描述
时序图标红的部分为有效位部分
在这里插入图片描述

代码

max6675.c
#include "max6675.h"
#include "sys.h" 
#include "delay.h"
#include "usart.h"	

/*max6675初始化程序*/
void max6675_init(void){
    GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //PB8推挽输出  GPIO_Mode_AF_PP
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB8
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;//PB7上拉输入 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB7
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //PB11复用推挽输出  GPIO_Mode_AF_PP
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB11	
}

u16 max6675_readRawValue(void)
{
  u16 tmp=0;
  u16 i;
  MAX6675_CS_L;//cs低
  /*按位读取电平*/
  for(i=0;i<16;i++)
          {  
			  /*创建一个沿,按沿读取PB7的端口电平*/
			MAX6675_CK_H;
			delay_us(10);
			if(MAX6675_SO)tmp|=0x0001;
		    //printf("tmp%d---:%d\n",i,tmp);/*这是为了检查错误时按位打印每个数*/
			tmp<<=1;//按位左移
		    MAX6675_CK_L;
			delay_us(10);
                  }
	      MAX6675_CS_H;//cs高		  
   if (tmp&0X04) 
 {
    tmp = 0; //未检测到热电偶
	// printf("未检测到热电偶\n");//测试用
  }
  else 
 {
	tmp<<=1;//去掉D15位
	tmp>>=4;//去掉D0、1、2位
  }
	return tmp;
}
 
float max6675_readTemperature(void)
{
	u16 d;
	float i,S;
	S=2.142857;//实验数,用温水和热水 环境测得的一个实际差量
	delay_ms(300);
	d=max6675_readRawValue();
	i=d*1023.75/4095/S;
    return i;
}

代码

main.c

LED灯原理图
在这里插入图片描述

#include "stm32f10x.h"
#include "usart.h"	
#include "delay.h"
#include "sys.h"
#include "max6675.h"
#include "led.h"
/*里面我写了一个led灯闪烁程序,测试温度是否为0*/
int main(void){
		float t;
	    LED_init();
	    delay_init();
		uart_init(9600);
	    max6675_init();

	while(1){
	
		GPIO_SetBits(GPIOA,GPIO_Pin_8);
		GPIO_SetBits(GPIOC,GPIO_Pin_12);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		delay_ms(500);	
		t = max6675_readTemperature();
		printf("the temperature is:%.2f\n",t);
		printf("\n");
		if(t!=0){
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		GPIO_ResetBits(GPIOC,GPIO_Pin_12);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
		delay_ms(500);
		}	
		
	}
}

我买了模块的热电偶和其他热电偶线:
在这里插入图片描述
在这里插入图片描述

温度显示

自带的热电偶线
在这里插入图片描述

自己买的热电偶线:
在这里插入图片描述

自带的热电偶降温慢,另买的快一些。

stm32刚开始,求各位大佬带!!!!哈哈哈

猜你喜欢

转载自blog.csdn.net/answerMack/article/details/83270562