|
- 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腳拉低時(shí)的設(shè)備地址
- //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總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
- }
- //產(chǎn)生IIC停止信號(hào)
- 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;//發(fā)送I2C總線結(jié)束信號(hào)
- delay_us(4);
- }
- u8 AMG_IIC_Wait_Ack(void)
- {
- u8 ucErrTime=0;
- AMG_SDA_IN(); //SDA設(shè)置為輸入
- 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;//時(shí)鐘輸出0
- return 0;
- }
- //產(chǎn)生ACK應(yīng)答
- 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;
- }
- //不產(chǎn)生ACK應(yīng)答
- 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發(fā)送一個(gè)字節(jié)
- //返回從機(jī)有無(wú)應(yīng)答
- //1,有應(yīng)答
- //0,無(wú)應(yīng)答
- void AMG_IIC_Send_Byte(u8 txd)
- {
- u8 t;
- AMG_SDA_OUT();
- AMG_IIC_SCL=0;//拉低時(shí)鐘開(kāi)始數(shù)據(jù)傳輸
- 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個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK
- u8 AMG_IIC_Read_Byte(void)
- {
- unsigned char i,receive=0;
- AMG_SDA_IN(); //SDA設(shè)置為輸入
- 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寫一個(gè)字節(jié)數(shù)據(jù)
- 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;//沒(méi)應(yīng)答則退出
- }
- 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讀一個(gè)字節(jié)數(shù)據(jù)
- u8 AMG_IIC_Read_1Byte(u8 SlaveAddress, u8 REG_Address,u8 *REG_data)
- {
- AMG_IIC_Start();
- AMG_IIC_Send_Byte(SlaveAddress);//發(fā)寫命令
- if(AMG_IIC_Wait_Ack())
- {
- AMG_IIC_Stop();//釋放總線
- return 1;//沒(méi)應(yīng)答則退出
- }
- AMG_IIC_Send_Byte(REG_Address);
- AMG_IIC_Wait_Ack();
- delay_us(5);
- AMG_IIC_Start();
- AMG_IIC_Send_Byte(SlaveAddress|0x01);//發(fā)讀命令
- AMG_IIC_Wait_Ack();
- *REG_data = AMG_IIC_Read_Byte();
- AMG_IIC_Stop();
- return 0;
- }
- //I2C讀多個(gè)字節(jié)數(shù)據(jù)
- 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);//發(fā)寫命令
- if(AMG_IIC_Wait_Ack())
- {
- AMG_IIC_Stop();//釋放總線
- return 1;//沒(méi)應(yīng)答則退出
- }
- AMG_IIC_Send_Byte(REG_Address);
- AMG_IIC_Wait_Ack();
- delay_us(5);
- AMG_IIC_Start();
- AMG_IIC_Send_Byte(SlaveAddress|0x01);//發(fā)讀命令
- 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寫多個(gè)字節(jié)數(shù)據(jù)
- 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);//發(fā)寫命令
- if(AMG_IIC_Wait_Ack())
- {
- AMG_IIC_Stop();//釋放總線
- return 1;//沒(méi)應(yīng)答則退出
- }
- 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];
- }
- }
復(fù)制代碼
|
|