AMG8833 8x8热成像传感器

Posted 学工科的皮皮志^_^

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AMG8833 8x8热成像传感器相关的知识,希望对你有一定的参考价值。

文章目录


前言

AMG8833这款传感器是 8x8 红外热传感器阵列。 当连接到您的微控制器(或树莓派)时,它将通过 I2C 返回一组 64 个单独的红外温度读数。 它就像那些花哨的热像仪,但足够紧凑和简单,易于集成。
该部件将测量范围从 0°C 到 80°C(32°F 到 176°F)的温度,精度为 ± 2.5°C (4.5°F)。它可以在最远 7 米 (23) 英尺的距离内检测到人。最大帧速率为 10Hz,非常适合创建自己的人体探测器或迷你热像仪。
注意:他的分辨率是0.25°C,但是精度是==±2.5°C==,分辨率和精度大家要分清,对精度要求较高的场景要谨慎使用。

一、如何使用AMG8833

对于使用者来说我们只关心这个传感器能不能满足我们的要求,并不是很关心其内部如何实现,具体的寄存器和引脚这篇文章说的很清楚,大家感兴趣的可以了解。驱动代码也是用他的,主要是教大家如何使用这个传感器。
AMG8833的使用与stm32驱动代码

二、配置头文件.h,.c文件

硬件平台:STM32ZET6正点原子,AMG8833
软件平台:keil5

2.1.IIC头文件,C文件

因为这个传感器的通信方式是IIC,所以需要用IIC来驱动,所以需要配置时序,具体可以看芯片手册的时序图,从这个头文件我们可以得出什么,1.引脚的连接方式
传感器的SCL脚接单片机的PB6脚
SDA接单片机的PB7脚
AD0要拉低,即接到地
电源和地自然不用多说,接单片机的5V/3.3V,GND

同时我们可以看到宏定义了两个函数直接操作了GPIOB的CRL寄存器,是对他的输出模式进行定义
具体可以看这一篇
STM32的GPIO方向定义和方向寄存器的理解
每个单片机的这个不一样,具体看芯片手册

1.AMG_IIC.h

#ifndef __AMG_I2C_H
#define __AMG_I2C_H
 
#include "stdint.h"
#include "sys.h"
#include "delay.h"
 
#define AMG_SDA_RCC  RCC_APB2Periph_GPIOB
#define AMG_SDA_PIN  GPIO_Pin_7
#define AMG_SDA_IOx  GPIOB  
#define AMG_SCL_RCC  RCC_APB2Periph_GPIOB
#define AMG_SCL_PIN  GPIO_Pin_6
#define AMG_SCL_IOx  GPIOB  
 
#define AMG_SDA_IN()  GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=8<<28;
#define AMG_SDA_OUT() GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=3<<28;
#define AMG_IIC_SCL    PBout(6)      //SCL
#define AMG_IIC_SDA    PBout(7)      //SDA	 
#define AMG_READ_SDA   PBin(7) 		 //输入SDA 
 
#define AMG88xx_ADR    0xD0          //5脚拉低时的设备地址
 
//Status
#define STATUS_OK       0x00
#define STATUS_FAIL     0x01
 
void AMG8833_IIC_Init(void);
u8 AMG_IIC_Write_1Byte(u8 SlaveAddress, u8 REG_Address,u8 REG_data);
u8 AMG_IIC_Read_1Byte(u8 SlaveAddress, u8 REG_Address,u8 *REG_data);
uint8_t AMG_I2C_Read_nByte(uint8_t SlaveAddress, uint8_t REG_Address, uint8_t *buf, uint16_t len);
 
#endif 
 
 

2.AMG_IIC.c

#include "AMG_IIC.h"
 
void AMG8833_IIC_Init(void)

	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	AMG_SDA_RCC, ENABLE );	
	GPIO_InitStructure.GPIO_Pin = AMG_SDA_PIN;               //端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;       //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //50Mhz速度
	GPIO_Init(AMG_SDA_IOx, &GPIO_InitStructure);
 
	RCC_APB2PeriphClockCmd(	AMG_SCL_RCC, ENABLE );	
	GPIO_InitStructure.GPIO_Pin = AMG_SCL_PIN;               //端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;       //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //50Mhz速度
	GPIO_Init(AMG_SCL_IOx, &GPIO_InitStructure);
	
	GPIO_SetBits(AMG_SDA_IOx,AMG_SDA_PIN);//SDA输出高	
	GPIO_SetBits(AMG_SCL_IOx,AMG_SCL_PIN);//SCL输出高	

 
void AMG_IIC_Start(void)

	AMG_SDA_OUT();//sda线输出
	AMG_IIC_SDA=1;	  	  
	AMG_IIC_SCL=1;
	delay_us(4);
 	AMG_IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	AMG_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 

 
//产生IIC停止信号
void AMG_IIC_Stop(void)

	AMG_SDA_OUT();//sda线输出
	AMG_IIC_SCL=0;
	AMG_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	AMG_IIC_SCL=1; 
	AMG_IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	

 
u8 AMG_IIC_Wait_Ack(void)

	u8 ucErrTime=0;
	AMG_SDA_IN();  //SDA设置为输入  
	AMG_IIC_SDA=1;delay_us(1);	   
	AMG_IIC_SCL=1;delay_us(1);	 
	while(AMG_READ_SDA)
	
		ucErrTime++;
		if(ucErrTime>250)
		
			AMG_IIC_Stop();
			return 1;
		
	
	AMG_IIC_SCL=0;//时钟输出0 	   
	return 0;  

 
//产生ACK应答
void AMG_IIC_Ack(void)

	AMG_IIC_SCL=0;
	AMG_SDA_OUT();
	AMG_IIC_SDA=0;
	delay_us(2);
	AMG_IIC_SCL=1;
	delay_us(2);
	AMG_IIC_SCL=0;

 
//不产生ACK应答		    
void AMG_IIC_NAck(void)

	AMG_IIC_SCL=0;
	AMG_SDA_OUT();
	AMG_IIC_SDA=1;
	delay_us(2);
	AMG_IIC_SCL=1;
	delay_us(2);
	AMG_IIC_SCL=0;

 
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void AMG_IIC_Send_Byte(u8 txd)
                        
    u8 t;   
	AMG_SDA_OUT(); 	    
    AMG_IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
                  
		if((txd&0x80)>>7)
			AMG_IIC_SDA=1;
		else
			AMG_IIC_SDA=0;
		txd<<=1; 	  
		delay_us(2);  
		AMG_IIC_SCL=1;
		delay_us(2); 
		AMG_IIC_SCL=0;	
		delay_us(2);
    	 
 
 
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 AMG_IIC_Read_Byte(void)

	unsigned char i,receive=0;
	AMG_SDA_IN();          //SDA设置为输入
	AMG_IIC_SDA = 1;
	delay_us(4);
	for(i=0;i<8;i++ )
	
		receive<<=1;
		AMG_IIC_SCL=0; 
		delay_us(4);
	    AMG_IIC_SCL=1;
		delay_us(4);
		if(AMG_READ_SDA)
			receive |= 0x01;   
	    delay_us(4); //1
		
    AMG_IIC_SCL = 0;	
	return receive;

 
//IIC写一个字节数据
u8 AMG_IIC_Write_1Byte(u8 SlaveAddress, u8 REG_Address,u8 REG_data)

	AMG_IIC_Start();
	AMG_IIC_Send_Byte(SlaveAddress);
	if(AMG_IIC_Wait_Ack())
	
		AMG_IIC_Stop();//释放总线
		return 1;//没应答则退出
 
	
	AMG_IIC_Send_Byte(REG_Address);
	AMG_IIC_Wait_Ack();	
	delay_us(5);
	AMG_IIC_Send_Byte(REG_data);
	AMG_IIC_Wait_Ack();	
	AMG_IIC_Stop();
 
	return 0;

 
//IIC读一个字节数据
u8 AMG_IIC_Read_1Byte(u8 SlaveAddress, u8 REG_Address,u8 *REG_data) 

	AMG_IIC_Start();
	AMG_IIC_Send_Byte(SlaveAddress);//发写命令
	if(AMG_IIC_Wait_Ack())
	
		 AMG_IIC_Stop();//释放总线
		 return 1;//没应答则退出
			
	AMG_IIC_Send_Byte(REG_Address);
	AMG_IIC_Wait_Ack();
	delay_us(5);
	AMG_IIC_Start(); 
	AMG_IIC_Send_Byte(SlaveAddress|0x01);//发读命令
	AMG_IIC_Wait_Ack();
	*REG_data = AMG_IIC_Read_Byte();
	AMG_IIC_Stop();
 
	return 0;

 
//I2C读多个字节数据
uint8_t AMG_I2C_Read_nByte(uint8_t SlaveAddress, uint8_t REG_Address, uint8_t *buf, uint16_t len)

	AMG_IIC_Start();
	AMG_IIC_Send_Byte(SlaveAddress);//发写命令
	if(AMG_IIC_Wait_Ack()) 
	
		AMG_IIC_Stop();//释放总线
		return 1;//没应答则退出
	
	AMG_IIC_Send_Byte(REG_Address);
	AMG_IIC_Wait_Ack();
	delay_us(5);
	AMG_IIC_Start(); 
	AMG_IIC_Send_Byte(SlaveAddress|0x01);//发读命令
	AMG_IIC_Wait_Ack();
	while(len)
	
		*buf = AMG_IIC_Read_Byte();
		if(1 == len)
		
			AMG_IIC_NAck();
		
		else
		
			AMG_IIC_Ack();
		
		buf++;
		len--;
	
	AMG_IIC_Stop();
 
	return STATUS_OK;

 
//I2C写多个字节数据
uint8_t AMG_I2C_Write_nByte(uint8_t SlaveAddress, uint8_t REG_Address, uint8_t *buf, uint16_t len)

	AMG_IIC_Start();
	AMG_IIC_Send_Byte(SlaveAddress);//发写命令
	if(AMG_IIC_Wait_Ack()) 
	
		AMG_IIC_Stop();//释放总线
		return 1;//没应答则退出
	
	AMG_IIC_Send_Byte(REG_Address);
	AMG_IIC_Wait_Ack();
	while(len--)
	
		AMG_IIC_Send_Byte(*buf++);
		AMG_IIC_Wait_Ack();
	
	AMG_IIC_Stop();
 
	return STATUS_OK;

这两个就分别保存为.h,.c文件仿真工程文件的HARDWARE的IIC下,没有就新建一个

2.2.AMG8833模块的驱动文件,.h,.c

驱动就是对他进行初始化,定义读数据函数,写数据写指令等

AMG8833.h

#ifndef __AMG8833_H
#define __AMG8833_H
#include "AMG_IIC.h"
 
#define AMG88xx_PIXEL_TEMP_CONVERSION 0.25
#define AMG88xx_THERMISTOR_CONVERSION 0.0625
 
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(void);
float AMG88xx_ReadThermistor(void);
void amg88xx_readPixels(float *buf, uint8_t size);
 
#endif

AMG8833.c

#include "AMG8833.h"
 
void AMG8833_Init(void)

	AMG8833_IIC_Init();           //IIC初始化
	
	//enter normal mode
	AMG_IIC_Write_1Byte(AMG88xx_ADR,AMG88xx_PCTL,AMG88xx_NORMAL_MODE);
	
	//software reset
	AMG_IIC_Write_1Byte(AMG88xx_ADR,AMG88xx_RST,AMG88xx_INITIAL_RESET);
	
	//set to 10 FPS
	AMG_IIC_Write_1Byte(AMG88xx_ADR,AMG88xx_FPSC,AMG88xx_FPS_10);

 
float signedMag12ToFloat(uint16_t val)

	//take first 11 bits as absolute val
	uint16_t absVal = (val & 0x7FF);
	
	return (val & 0x800) ? 0 - (float)absVal : (float)absVal ;

 
float AMG88xx_ReadThermistor(void)

	uint8_t raw[2];
	uint16_t recast;
	
	AMG_I2C_Read_nByte(AMG88xx_ADR,AMG88xx_TTHL, raw, 2);
	recast = ((uint16_t)raw[1] << 8) | ((uint16_t)raw[0]);
	return signedMag12ToFloat(recast) * AMG88xx_THERMISTOR_CONVERSION;

 
void amg88xx_readPixels(float *buf, uint8_t size)

	uint16_t recast;
	float converted;
	uint8_t rawArray[128],i;
	
	AMG_I2C_Read_nByte(AMG88xx_ADR,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 = signedMag12ToFloat(recast) * AMG88xx_PIXEL_TEMP_CONVERSION;
		buf[i] = converted;
	

同样也是保存为.c,.h文件保存在这个文件夹下

三、Keil相关配置

前面我们已经配置好了,需要在keil中进行文件添加和路径添加,点击我们这个快捷键
点击HARDWARE,把我们刚才的两个.c文件添加进来,注意添加.c就可以了,.h他会自动包含。

3.1.路径添加

点击我们的快捷键魔术棒,c/c++,添加路径,就是头文件的路径嘛,把他包含进来


四、主函数编写

主函数主要是对传感器和串口的初始化,就可以打印输出了,它将通过 I2C 返回一组 64 个单独的红外温度读数。
他比较适合用来做红外热成像,因为它本来就干这个的,不适合用来测人体温度,因为精度不够±2.5℃,想做红外热成像的可以看看这个up主,这里就不做展开了。
AMG8833红外热成像

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "math.h" 
#include "stdio.h"
#include "s

以上是关于AMG8833 8x8热成像传感器的主要内容,如果未能解决你的问题,请参考以下文章

ESP32+AMG8833+RGB屏240*320(ST7789)红外热成像

MLX90640 红外热成像传感器测温模块开发笔记

stm32+AMG8833+VS2015 C#上位机图像显示

LINUX驱动开发AMG8833红外成像模块在HI3516上的应用

LINUX驱动开发AMG8833红外成像模块在HI3516上的应用

MLX90640 红外热成像仪测温传感器模块开发笔记