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

一、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);		
	} 
}

五、工程源码

点击下载

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全面解析平台工程与 DevOps 的区别与联系

平台工程的概念非常流行&#xff0c;但很多开发人员仍然不清楚它是如何实际运作的&#xff0c;这是非常正常的。 平台工程是与 DevOps 并行吗&#xff1f;还是可以相互替代&#xff1f;或者 DevOps 和平台工程是两个完全不同的概念&#xff1f; 一种比较容易将两者区分开来的方…

Feign负载均衡

Feign负载均衡 概念总结 工程构建Feign通过接口的方法调用Rest服务&#xff08;之前是Ribbon——RestTemplate&#xff09; 概念 官网解释: http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign Feign是一个声明式WebService客户端。使用Feign能让…

AI大模型探索之路-训练篇5:大语言模型预训练数据准备-词元化

系列文章目录&#x1f6a9; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据…

法律知识学习考试系统 C#+uniapp+asp.net微信小程序

技术要求&#xff1a;后端C#&#xff0c;安卓app&#xff0c;mysql数据库 系统分为管理员、教师端和学生端: 管理员端实现管理员的注册登录以及教师和学生的注册、法律法规内容的发布与更新、法律法规页面的评论的添加与删除、内容查询、知识小测的内容发布与删除、问卷调查的发…

云计算和边缘计算究竟有什么不同

在数据时代&#xff0c;无论是人的活动还是机器的运作都会产生各种各样海量的数据。在对数据梳理和筛选过程中&#xff0c;计算机的运算处理必不可少。为了减少本地计算机算力成本等限制&#xff0c;越来越多的企业选择了云计算和边缘计算。今天&#xff0c;德迅云安全就带您来…

SpikingJelly笔记之梯度替代

文章目录 前言一、梯度替代二、网络结构三、MNIST分类1、单步模式2、多步模式 总结 前言 在SpikingJelly使用梯度替代训练SNN&#xff0c;构建单层全连接SNN实现MNIST分类任务。 一、梯度替代 1、梯度替代&#xff1a; 阶跃函数不可微&#xff0c;无法进行反向传播 g ( x ) …

miniTry:Python实现web搜索(全自动+程序操控)

声明&#xff1a;本问给出了全部代码--可以复现--亲测有效 :) [ 代码为图片--> 强制自己去敲一次 又不多] 1.打开网站&#xff1a; 2.利用id去定位到我们要进行输入的内容&#xff08;bing可以直接进行搜索&#xff0c;而csdn需要登录&#xff0c;所以我们用csdn做演示&…

HODL、FUD、FOMO 等其他比特币俚语是什么意思?

作者&#xff1a;Paxful Team 1、FOMO&#xff08;惧怕错失机会&#xff09; FOMO 是惧怕错失机会的缩写&#xff0c;可用于日常生活。它指的是当其他人都在谈论比特币时&#xff0c;产生的购买比特币的紧迫感。 2、Shill&#xff08;不断推广吹捧&#xff09; Shilling 是指…

linux支持vGPU方案

1&#xff0c;查询gpu型号&#xff1a;lspci | grep "NVIDIA\|VGA" PCI Devices 2&#xff0c;下载驱动 官方驱动 | NVIDIA 3&#xff0c;安装 sudo sh NVIDIA-Linux-x86_64-440.118.02.run -no-x-check -no-nouveau-check -no-opengl-files参数说明&#xff1a; …

自定义View-旋转变色圆角三角形的绘制

本文字数&#xff1a;3151字 预计阅读时间&#xff1a;20分钟 在现代设计中&#xff0c;动效图在APP的UI界面中所起到的作用无疑是显著的。相比于静态的界面&#xff0c;动效更符合人类的自然认知体系&#xff0c;它有效地降低了用户的认知负载&#xff0c;UI动效俨然已经成为了…

汽车新四化,会发生什么?

北京国际汽车展览会正如火如荼地进行中,作为国内外汽车行业瞩目的盛会&#xff0c;众多车企纷纷亮出了自家的“杀手锏”。 这场汽车的盛宴不仅集中展示了众多汽车品牌的最新技术和产品&#xff0c;更深刻体现了汽车新四化的发展趋势。汽车新四化&#xff0c;即电动化、网联化、…

DS进阶:AVL树和红黑树

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

使用Keil移植工程时修改单片机型号参数

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 当使用Keil对STM32系列单片机开发时&#xff0c;如果使用的是库函数&#xff0c;那么不同型号单片机的工程项目文件是可以直接移植的。只需要按照下面的步骤修改对应的芯片&#xff0c;就可以直接将工程移植过去&a…

JVM垃圾收集器--分区收集器

G1收集器 属性 G1&#xff08;Garbage-First Garbage Collector&#xff09;在 JDK 1.7 时引入&#xff0c;在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。G1 有五个属性&#xff1a;分代、增量、并行、标记整理、STW。 分代 G1收集器 将内部分为多个大小相等的区域&#x…

Java8 Stream常见用法

Stream流的常见用法&#xff1a; 1.利用stream流特性把数组转list集合 //定义一个数组Integer[] array {5,2,1,6,4,3};//通过stream特性把数组转list集合List<Integer> list Arrays.stream(array).collect(Collectors.toList());//打印结果System.out.println(list);…

全球数据爬取的解决方案-国外数据爬取

引言 随着经济的持续低迷和对外贸易的需求扩大&#xff0c;各个公司为了更好的了解海外客户情况&#xff0c;最简单直接的办法就是从全球收集公共的网络数据。 无论是海外电商用户的消费习惯还是训练自己的通用人工智能chatgpt&#xff0c;都是需要海量和多种类型数据的支持。…

【Linux】进程间通信(共享内存、消息队列、信号量)

一、System V —— 共享内存&#xff08;详解&#xff09; 共享内存区是最快的 IPC 形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到内核&#xff0c;换句话说&#xff0c;就是进程不再通过执行进入内核的系统调用来传递彼此的数…

[NSSCTF]prize_p5

前言 之前就学过反序列化的字符串逃逸 但是没怎么做题 补一下窟窿 题目 <?phperror_reporting(0);class catalogue{public $class;public $data;public function __construct(){$this->class "error";$this->data "hacker";}public functi…

HTTP网络协议的请求方法,具体详解(2024-04-26)

1、HTTP 即超文本传输协议&#xff0c;是一种实现客户端和服务器之间通信的响应协议&#xff0c;它是用作客户端和服务器之间的请求 根据 HTTP 标准&#xff0c;HTTP 请求可以使用多种请求方法。 2、方法分类 HTTP1.0 定义了三种请求方法&#xff1a; GET, POST 和 HEAD 方…

表情识别 | 卷积神经网络(CNN)人脸表情识别(Matlab)

表情识别 | 卷积神经网络(CNN)人脸表情识别&#xff08;Matlab&#xff09; 目录 表情识别 | 卷积神经网络(CNN)人脸表情识别&#xff08;Matlab&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab使用卷积神经网络(CNN)&#xff0c;进行人脸表情情绪识别…