一、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);
}
}
五、工程源码
点击下载