STM32、GD32等驱动AMG8833热成像传感器源码分享

news2024/12/28 14:19:11

一、AMG8833介绍

1简介

AMG8833是一种红外热像传感器,也被称为热感传感器。它可以用来检测和测量物体的热辐射,并将其转换为数字图像。AMG8833传感器可以感知的热源范围为-20°C到100°C,并能提供8x8的像素分辨率。它通过I2C接口与微控制器或单片机进行通信,并可提供实时温度图像数据。AMG8833传感器被广泛用于热成像、人体检测、温度测量等应用领域。

2、引脚图

在这里插入图片描述

二、原理图

在这里插入图片描述

三、源码

1、iic.h

#ifndef _MYIIC_H
#define _MYIIC_H
#include "sys.h"

//IO方向设置
#define SDA_IN()  {GPIOG->MODER&=~(3<<(12*2));GPIOG->MODER|=0<<12*2;}	//PH5输入模式
#define SDA_OUT() {GPIOG->MODER&=~(3<<(12*2));GPIOG->MODER|=1<<12*2;}  //PH5输出模式
//IO操作
#define IIC_SCL(n)  (n?HAL_GPIO_WritePin(GPIOG,GPIO_PIN_11,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOG,GPIO_PIN_11,GPIO_PIN_RESET)) //SCL
#define IIC_SDA(n)  (n?HAL_GPIO_WritePin(GPIOG,GPIO_PIN_12,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOG,GPIO_PIN_12,GPIO_PIN_RESET)) //SDA
#define READ_SDA    HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_12)  //输入SDA

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	 
#endif


2、iic.c

#include "iic.h"
#include "delay.h"


//IIC初始化
void IIC_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOG_CLK_ENABLE();   //使能GPIOH时钟
    
    //PH4,5初始化设置
    GPIO_Initure.Pin=GPIO_PIN_11|GPIO_PIN_12;
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;    //快速
    HAL_GPIO_Init(GPIOG,&GPIO_Initure);
    
    IIC_SDA(1);
    IIC_SCL(1);  
}

//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA(1);	  	  
	IIC_SCL(1);
	delay_us(4);
 	IIC_SDA(0);//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL(0);
	IIC_SDA(0);//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL(1); 
	IIC_SDA(1);//发送I2C总线结束信号
	delay_us(4);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA(1);delay_us(1);	   
	IIC_SCL(1);delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL(0);//时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(0);
	delay_us(2);
	IIC_SCL(1);
	delay_us(2);
	IIC_SCL(0);
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(1);
	delay_us(2);
	IIC_SCL(1);
	delay_us(2);
	IIC_SCL(0);
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL(0);//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA((txd&0x80)>>7);
        txd<<=1; 	  
		delay_us(2);   //对TEA5767这三个延时都是必须的
		IIC_SCL(1);
		delay_us(2); 
		IIC_SCL(0);	
		delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL(0); 
        delay_us(2);
		IIC_SCL(1);
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

3、amg8833.h

#ifndef __AMG8833_H
#define __AMG8833_H
#include "sys.h"
#include "myiic.h"


#define STATUS_OK       0x00
#define STATUS_FAIL     0x01

#define AMG88xx_PIXEL_TEMP_CONVERSION 0.25f
#define AMG88xx_THERMISTOR_CONVERSION 0.0625f
 
enum
{
	AMG88xx_PCTL = 0x00,
	AMG88xx_RST = 0x01,
	AMG88xx_FPSC = 0x02,
	AMG88xx_INTC = 0x03,
	AMG88xx_STAT = 0x04,
	AMG88xx_SCLR = 0x05,
	//0x06 reserved
	AMG88xx_AVE = 0x07,
	AMG88xx_INTHL = 0x08,
	AMG88xx_INTHH = 0x09,
	AMG88xx_INTLL = 0x0A,
	AMG88xx_INTLH = 0x0B,
	AMG88xx_IHYSL = 0x0C,
	AMG88xx_IHYSH = 0x0D,
	AMG88xx_TTHL = 0x0E,
	AMG88xx_TTHH = 0x0F,
	AMG88xx_INT_OFFSET = 0x010,
	AMG88xx_PIXEL_OFFSET = 0x80
};
 
enum power_modes{
	AMG88xx_NORMAL_MODE = 0x00,
	AMG88xx_SLEEP_MODE = 0x01,
	AMG88xx_STAND_BY_60 = 0x20,
	AMG88xx_STAND_BY_10 = 0x21
};
 
enum sw_resets {
	AMG88xx_FLAG_RESET = 0x30,
	AMG88xx_INITIAL_RESET = 0x3F
};
 
enum frame_rates {
	AMG88xx_FPS_10 = 0x00,
	AMG88xx_FPS_1 = 0x01
};
 
enum int_enables{
	AMG88xx_INT_DISABLED = 0x00,
	AMG88xx_INT_ENABLED = 0x01
};
 
enum int_modes {
	AMG88xx_DIFFERENCE = 0x00,
	AMG88xx_ABSOLUTE_VALUE = 0x01
};


void amg8833_init(uint8_t slaveAddress);
float amg8833_read_thermistor(uint8_t slaveAddress);
void amg8833_read_pixels(uint8_t slaveAddress,float *buf, uint8_t size);

#endif


4、amg8833.c

#include "amg8833.h"
#include "delay.h"


//IIC写一个字节数据
uint8_t amg8833_write_1byte(uint8_t slaveAddress, uint8_t reg,uint8_t data)
{
	IIC_Start();
	IIC_Send_Byte(slaveAddress<<1);
	if(IIC_Wait_Ack())
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出
 
	}
	IIC_Send_Byte(reg);
	IIC_Wait_Ack();	
	delay_us(5);
	IIC_Send_Byte(data);
	IIC_Wait_Ack();	
	IIC_Stop();
 
	return 0;
}
 
//IIC读一个字节数据
uint8_t amg8833_read_1byte(uint8_t slaveAddress, uint8_t reg,uint8_t *data) 
{
	IIC_Start();
	IIC_Send_Byte(slaveAddress<<1);//发写命令
	if(IIC_Wait_Ack())
	{
		 IIC_Stop();//释放总线
		 return 1;//没应答则退出
	}		
	IIC_Send_Byte(reg);
	IIC_Wait_Ack();
	delay_us(5);
	IIC_Start(); 
	IIC_Send_Byte((slaveAddress<<1)|0x01);//发读命令
	IIC_Wait_Ack();
	*data = IIC_Read_Byte(0);
	IIC_Stop();
 
	return 0;
}
 
//I2C读多个字节数据
uint8_t amg8833_read_nbyte(uint8_t slaveAddress, uint8_t reg, uint8_t *buf, uint16_t len)
{
	IIC_Start();
	IIC_Send_Byte(slaveAddress<<1);//发写命令
	if(IIC_Wait_Ack()) 
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出
	}
	IIC_Send_Byte(reg);
	IIC_Wait_Ack();
	delay_us(5);
	IIC_Start(); 
	IIC_Send_Byte((slaveAddress<<1)|0x01);//发读命令
	IIC_Wait_Ack();
	while(len)
	{
		
		if(1 == len)
		{
			*buf = IIC_Read_Byte(0);
		}
		else
		{
			*buf = IIC_Read_Byte(1);
		}
		buf++;
		len--;
	}
	IIC_Stop();
 
	return STATUS_OK;
}
 
//I2C写多个字节数据
uint8_t amg8833_write_nbyte(uint8_t slaveAddress, uint8_t reg, uint8_t *buf, uint16_t len)
{
	IIC_Start();
	IIC_Send_Byte(slaveAddress<<1);//发写命令
	if(IIC_Wait_Ack()) 
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出
	}
	IIC_Send_Byte(reg);
	IIC_Wait_Ack();
	while(len--)
	{
		IIC_Send_Byte(*buf++);
		IIC_Wait_Ack();
	}
	IIC_Stop();
 
	return STATUS_OK;
}

 
void amg8833_init(uint8_t slaveAddress)
{
	uint8_t read = 0xaa;
	//enter normal mode
	amg8833_write_1byte(slaveAddress,AMG88xx_PCTL,AMG88xx_NORMAL_MODE);
	
	//software reset
	amg8833_write_1byte(slaveAddress,AMG88xx_RST,AMG88xx_INITIAL_RESET);
	
	//set to 10 FPS
	amg8833_write_1byte(slaveAddress,AMG88xx_FPSC,AMG88xx_FPS_10);
	
	amg8833_read_1byte(slaveAddress, AMG88xx_FPSC,&read);
	
	printf("write = 0x%02x  read = 0x%02x\r\n", AMG88xx_FPS_10,read);
}
 
float signed_mag12_to_float(uint16_t val)
{
	//take first 11 bits as absolute val
	uint16_t absVal = (val & 0x7FF);
	
	return (val & 0x800) ? 0 - (float)absVal : (float)absVal ;
}
 
float amg8833_read_thermistor(uint8_t slaveAddress)
{
	uint8_t raw[2];
	uint16_t recast;
	
	amg8833_read_nbyte(slaveAddress,AMG88xx_TTHL, raw, 2);
	recast = ((uint16_t)raw[1] << 8) | ((uint16_t)raw[0]);
	return signed_mag12_to_float(recast) * AMG88xx_THERMISTOR_CONVERSION;
}
 
void amg8833_read_pixels(uint8_t slaveAddress,float *buf, uint8_t size)
{
	uint16_t recast;
	float converted;
	uint8_t rawArray[128],i;
	
	amg8833_read_nbyte(slaveAddress,AMG88xx_PIXEL_OFFSET,rawArray,128);
	
	for(i=0; i<size; i++)
	{
		uint8_t pos = i << 1;
		recast = ((uint16_t)rawArray[pos + 1] << 8) | ((uint16_t)rawArray[pos]);        
		
		converted = signed_mag12_to_float(recast) * AMG88xx_PIXEL_TEMP_CONVERSION;
		buf[i] = converted;
	}
}

四、使用方法

#include "sys.h" 
#include "usart.h" 
#include "delay.h" 
#include "led.h"
#include "mpu.h"
#include "amg8833.h"

int main(void)
{
	uint8_t slaveAddress = 0x69;

	float pixTempture[8][8];
	uint8_t i,j;
	
	Cache_Enable();					//打开L1-Cache
	HAL_Init();				        //初始化HAL库
	Stm32_Clock_Init(160,5,2,4);	//设置时钟,400Mhz
	delay_init(400);				//延时初始化
	uart_init(115200);				//串口初始化
	led_init();						//初始化LED时钟
	MPU_Memory_Protection();		//保护相关存储区域
	
	IIC_Init();
	
	amg8833_init(slaveAddress);
	
  
	while(1)
	{
		amg8833_read_pixels(slaveAddress,&pixTempture[0][0], 64);
		
		for(i=0;i<8;i++)
		{
			for(j=0;j<8;j++)
			{
				printf("%.2f    ",pixTempture[i][j]);
			}
			printf("\r\n");
		}
		printf("\r\n");
		printf("\r\n");
		toggle_g_led();
		delay_ms(1000);		
	} 
}

五、工程源码

点击下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1627501.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DS进阶:AVL树和红黑树

一、AVL树 1.1 AVL树的概念 二叉搜索树&#xff08;BST&#xff09;虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-…

为什么深度学习模型在 GPU 上运行得更快:CUDA 编程简介

如今,当我们谈论深度学习时,通常会将其实现与利用 GPU 来提高性能联系起来。 GPU(图形处理单元)最初设计用于加速图像、2D 和 3D 图形的渲染。然而,由于它们能够执行许多并行操作,因此它们的实用性超出了深度学习等应用程序。 GPU 在深度学习模型中的使用始于 2000 年代…

Unity读书系列《Unity高级编程:主程手记》——架构

文章目录 前言一、架构的意义1、承载力2、可扩展性3、易用性4、可伸缩性5、容错性以及错误的感知力 二、软件架构的思维方式二、构建Unity项目1、前端和后端架构之间2、培养架构设计思路3、Unity项目的分层设计 总结 前言 这篇文章是《Unity高级编程&#xff1a;主程手记》的第…

【源码】WHMCS 虚拟主机计费系统 易支付插件 USDT收款插件 支付宝 微信收款

【源码介绍】 WHMCS 虚拟主机计费系统 易支付插件 USDT收款插件 支付宝 微信收款 【源码说明】 WHMCS是一个国外的专业虚拟主机计费系统&#xff0c;功能很强大&#xff0c;这里分享一个7、8版本都可用的易支付 需要对接USDT可以谷歌下载易支付USDT插件&#xff0c;主机对接…

【R语言实战】——kNN和朴素贝叶斯方法实战

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

wifi可以连接但是上不了网该怎么解决?

上网的过程中&#xff0c;我们有时候会遇到wifi可以连接但是上不了网的情况&#xff0c;打开电脑浏览器&#xff0c;显示域名解析错误。遇到这种情况&#xff0c;一般说明IP与站点的解析过程出现了错误。 在网络中的主机都是IP地址来标识的&#xff0c;如果在浏览器输入此IP地…

美国言语听力学会(ASHA)关于非处方 (OTC) 助听器的媒体声明(翻译稿)

美国国会于 2021 年 4 月 13 日批准美国听力学会积极提供建议&#xff0c;并一直积极参与制定FDA关于非处方助听器销售的拟议法规。根据2017年通过的立法授权。学院积极参与帮助塑造授权立法&#xff0c;并就即将出台的条例分享了建议。 根据美国卫生与公众服务部NIH / NIDCD的…

数据分析:扩增子-16s rRNA分析snakemake流程

介绍 扩增子测序是分析环境微生物的常见手段&#xff0c;通常使用的是16s rRNA片段。16srRNA分析主要有质控、去冗余、聚类OTU、去嵌合体、生成OTU表和物种注释等步骤。更多知识分享请到 https://zouhua.top/。 先看看前期数据处理的可视化图。 数据 18份来自宏基因组公众号…

C# WinForm —— 08 Form初始化、布局、注册事件

Form 初始化 Form初始化的时候会调用 Designer.cs 里的 InitializeComponent(); 函数&#xff0c;在InitializeComponent(); 函数里面有Load Form语句时会调用 FrmLogin_Load()函数 Form布局 两种方式&#xff1a; 拖控件到窗体&#xff0c;设置属性在Load事件中写代码添加…

线性神经网络示例

通过5个条件判定一件事情是否会发生&#xff0c;5个条件对这件事情是否发生的影响力不同&#xff0c;计算每个条件对这件事情发生的影响力多大&#xff0c;写一个线性神经网络模型pytorch程序,最后打印5个条件分别的影响力。 一 在这个场景中&#xff0c;一个线性神经网络&…

knife4j swagger 使用笔记

1.接口访问的端口跟后台设置的不一致&#xff0c;接口请求无反应 处理办法 2.响应参数不显示问题 &#xff08;1&#xff09;返回的参数里面一定要有响应的参数对象&#xff0c;如下&#xff1a; &#xff08;2&#xff09;TableDataInfo 定义成泛型类 TableDataInfo package…

Int4:Lucene 中的更多标量量化

作者&#xff1a;来自 Elastic Benjamin Trent, Thomas Veasey 在 Lucene 中引入 Int4 量化 在之前的博客中&#xff0c;我们全面介绍了 Lucene 中标量量化的实现。 我们还探索了两种具体的量化优化。 现在我们遇到了一个问题&#xff1a;int4 量化在 Lucene 中是如何工作的以…

软件需求管理规程(Word原件2024)

软件开发人员及用户往往容易忽略信息沟通&#xff0c;这导致软件开发出来后不能很好地满足用户的需要&#xff0c;从而造成返工。而返工不仅在技术上给开发人员带来巨大的麻烦&#xff0c;造成人力、物力的浪费&#xff0c;而且软件的性能也深受影响。所以在软件项目开发周期的…

单片机为什么有多组VDD?

以前我在画尺寸小的PCB时&#xff0c;比较头痛&#xff0c;特别是芯片引脚又多的&#xff0c;芯片底下&#xff0c;又不能打太多过孔。 可能有些老铁也比较好奇&#xff0c;为什么一个单片机芯片&#xff0c;有这么多组VDD和VSS。 比如下面这个100个引脚的STM32单片机。 有5组…

前端实现将当前页面内容下载成图片(图片可做到高清画质)

插件背景&#xff1a; html2canvas可以把你想要转变的元素变为图片&#xff0c;使用file-saver下载图片。 1、安装html2canvas、file-saver npm install html2canvasnpm install file-saver --save 2、在Vue组件中引入并使用html2canvas、file-saver import html2canvas fro…

智慧旅游开启智慧出行新时代,科技引领旅行新风尚:以科技为引领,推动旅游业智慧化升级,为旅行者提供更加便捷、高效的旅行服务

一、引言 随着信息技术的飞速发展&#xff0c;智慧旅游作为一种全新的旅游形态&#xff0c;正逐渐改变着人们的出行方式。它利用现代科技手段&#xff0c;实现旅游资源的智能化管理、旅游信息的智能化传播和旅游服务的智能化提供&#xff0c;为旅行者带来更加便捷、高效的旅行…

Qt下使用OpenCV截取图像并在QtableWidget表格上显示

文章目录 前言一、在QLabel上显示图片并绘制矩形框二、保存矩形框数据为CSV文件三、保存截取图像四、将截取图像填充到表格五、图形视图框架显示图像六、示例完整代码总结 前言 本文主要讲述了在Qt下使用OpenCV截取绘制的矩形框图像&#xff0c;并将矩形框数据保存为CSV文件&a…

气膜仓库:现代化仓储新选择—轻空间

气膜仓库&#xff0c;作为现代化仓储的新选择&#xff0c;越来越受到人们的青睐。相比传统料仓&#xff0c;气膜仓库具有诸多优势&#xff0c;使其成为各行各业的首选储存解决方案。 1. 高效节能 气膜仓库的建设周期短&#xff0c;基础简单&#xff0c;安装快捷&#xff0c;能耗…

C#命名空间常用函数

在C#中&#xff0c;不同命名空间下有各种常用函数&#xff0c;下面列举一些常见的函数及其对应的命名空间&#xff1a; System命名空间&#xff1a; Console.WriteLine()&#xff1a;用于向控制台输出信息。Convert.ToInt32()&#xff1a;用于将其他数据类型转换为整数类型。 S…

Kafka 3.x.x 入门到精通(05)——对标尚硅谷Kafka教程

Kafka 3.x.x 入门到精通&#xff08;05&#xff09;——对标尚硅谷Kafka教程 2. Kafka基础2.1 集群部署2.2 集群启动2.3 创建主题2.4 生产消息2.5 存储消息2.6 消费消息2.6.1 消费消息的基本步骤2.6.2 消费消息的基本代码2.6.3 消费消息的基本原理2.6.3.1消费者组2.6.3.1.1 消费…