- 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;
- }
- 3、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
- 4、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 = converted[i];
- }
- }
复制代码
|