STM32和MLX90614非接触式温度传感器。I2C连接

MLX90614传感器是一种非接触式传感器,通过接收和转换红外辐射来读取物体的温度。它可以在三种模式下工作:恒温器,PWM输出和SMBus。在恒温模式下,传感器不需要控制器,只需通过控制开漏负载驱动器将温度保持在指定的范围内即可。在PWM模式下,PWM信号出现在传感器输出上,其占空比取决于温度。为了连接到控制器,最有趣的模式是SMBus。由于此协议与I2C电气和信号兼容,因此我们将使用硬件I2C与传感器配合使用。他将在本文中讨论。通过写入特定的EEPROM单元来配置所有传感器模式。默认情况下,传感器处于SMBus模式。


外观及连接图

. " " STM32F103C8T6 , . 2 I2C. . PB6 - SCL, PB7 - SDA. , 4.7 .

, : mlx90614.h mlx90614.c . LCD A2004 . .

.

#ifndef I2C_DEVICES_I2C_H_
#define I2C_DEVICES_I2C_H_

#include "stm32f1xx.h"
#include <stdio.h>
#include "delay.h"

#define F_APB1 36 													//   APB1
#define TPCLK1 ( 1000/F_APB1 ) 							//   APB1 ns. ~ 28
#define CCR_VALUE ( 10000 /(TPCLK1 * 2 ) ) 	//   CCR  36  ~ 179
#define TRISE_VALUE ( 1000 / TPCLK1)

. stm32f1xx.h. stdio.h , char LCD. delay.h - .

I2C. . , F_APB1, .

, : RAM EEPROM. RAM . , RAM . " ". . , . MLX90614 . , . EEPROM . .

//---------------- RAM addresses --------------------------------------------
#define MLX90614_RAW_IR_1 0x04		//    
#define MLX90614_RAW_IR_2 0x05
#define MLX90614_TA 0x06					//   
#define MLX90614_TOBJ_1 0x07			//     
#define MLX90614_TOBJ_2 0x08			//     

//--------------- EEPROM addresses ------------------------------------------
#define MLX90614_TO_MAX 0x00
#define MLX90614_TO_MIN 0x01
#define MLX90614_PWM_CTRL 0x02
#define MLX90614_TA_RANGE 0x03
#define MLX90614_EMISSIVITY 0x04
#define MLX90614_CONFIG_REGISTER_1 0x05
#define MLX90614_SMBUS_ADDRESS 0x0E // LSByte only
#define MLX90614_ID_NUMBER_1 0x1C
#define MLX90614_ID_NUMBER_2 0x1D
#define MLX90614_ID_NUMBER_3 0x1E
#define MLX90614_ID_NUMBER_4 0x1F

, .

//--------------- Commands ------------------------------------------------
#define MLX90614_RAM_ACCESS 0 					//   RAM
#define MLX90614_EEPROM_ACCESS 0x20 		//   EEPROM
#define MLX90614_READ_FLAGS 0xF0 				//  
#define MLX90614_ENTER_SLEEP_MODE 0xFF 	//  
#define MLX90614_READ 1									//    
#define MLX90614_WRITE 0								//    

. , . , I2C , - 5A. , , . .

:

void mlx90614Init( void );
double getTemp_Mlx90614_Double( uint16_t address, uint8_t ram_address );
void getTemp_Mlx90614_CharArray( uint16_t address, uint8_t ram_address, char* buf );

uint16_t getAddrFromEEPROM( uint16_t address );
int setAddrToEEPROM ( uint16_t address, uint16_t new_address );

uint16_t readEEPROM( uint16_t address, uint16_t eeprom_address );
void writeEEPROM ( uint16_t address, uint16_t eeprom_address, uint16_t data );

#endif /* I2C_DEVICES_I2C_H_ */

void mlx90614Init( void )

I2C

double getTempMlx90614Double( uint16t address, uint8t ram_address )

double . , . RAM . RAM , 1 2.

void getTempMlx90614CharArray( uint16t address, uint8t ram_address, char* buf )

, , char , . LCD

uint16t getAddrFromEEPROM( uint16t address )

, EEPROM. .

int setAddrToEEPROM ( uint16t address, uint16t new_address )

EEPROM. .

uint16t readEEPROM( uint16t address, uint16t eepromaddress )

EEPROM

void writeEEPROM ( uint16t address, uint16t eepromaddress, uint16t data )

EEPROM

. .

void mlx90614Init(void){

	 delay_ms(120);																//        

RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;							//  
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;							//  i2c1

GPIOB->CRL |= GPIO_CRL_MODE6 | GPIO_CRL_MODE7;	//  50 
GPIOB->CRL |= GPIO_CRL_CNF6 | GPIO_CRL_CNF7; 		//  -  

I2C1->CR2 &= ~I2C_CR2_FREQ; 										//       APB1
I2C1->CR2 |= F_APB1; 														//    APB1    I2C 
I2C1->CR1 &= ~I2C_CR1_PE; 											//   I2C    CCR
I2C1->CCR &= ~I2C_CCR_CCR;
I2C1->CCR |=  CCR_VALUE;
I2C1->TRISE |=  TRISE_VALUE;

I2C1->CR1 |= I2C_CR1_ENPEC; 										//   PEC
I2C1->CR1 |= I2C_CR1_PE;												//   I2C
I2C1->CR1 |= I2C_CR1_ACK; 											//  ACK

}

. F_APB1, CCR_VALUE TRISE_VALUE , . I2C CCR ( ) ACK I2C , ACK .

double getTemp_Mlx90614_Double( uint16_t address,
								uint8_t ram_address){

	 uint16_t	temp ; 																// 
	 uint8_t	temp_lsb ;														//   
	 double temp_result ; 													//   
	 double temp_double ;														// ,    double

	 address = address<<1; 													//     (  
	 	 	 	 	 	 	 	 	 	 	 														//   1-  /)
	 I2C1->CR1 |= I2C_CR1_START;
	 while (!(I2C1->SR1 & I2C_SR1_SB)){}

	 (void) I2C1->SR1;

	 I2C1->DR = address | MLX90614_WRITE; 					//   ,   MLX90614
	 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

	 (void) I2C1->SR1;
	 (void) I2C1->SR2;

	 I2C1->DR= ram_address;													//   RAM   MLX90614
	 while (!(I2C1->SR1 & I2C_SR1_TXE)){}

	 I2C1->CR1 |= I2C_CR1_START;										//  
	 while (!(I2C1->SR1 & I2C_SR1_SB)){}

	 (void) I2C1->SR1;

	 I2C1->DR = address | MLX90614_READ;						//     
	 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

	 (void) I2C1->SR1;
	 (void) I2C1->SR2;

	 while(!(I2C1->SR1 & I2C_SR1_RXNE)){}

	 temp_lsb = I2C1->DR;														//   

	 while(!(I2C1->SR1 & I2C_SR1_RXNE)){}

	 temp = I2C1->DR;																//   

	 I2C1->CR1 |= I2C_CR1_STOP;

	 temp = (temp & 0x007F) << 8;										//   ,    
	 temp |= temp_lsb;
	 temp_double = (double) temp; 									//    double
	 temp_result =  ((temp_double * 0.02)- 0.01 );	//    
	 temp_result = temp_result - 273.15; 						//    . 



return temp_result;


 }

, 1 , 1 , 0 - . I2C. 5A, B4 B5 . , , . . . , - (temp & 0x007F).

, LCD, . void getTempMlx90614CharArray, char , sprintf(), stdio.h

void getTemp_Mlx90614_CharArray( uint16_t address, uint8_t ram_address, char* buf){

	double t;
	t = getTemp_Mlx90614_Double(address,ram_address);

	 sprintf(buf, "%.1f",t);

	return ;

}

RAM :

  1. START

  2. , 1 (). - 0

  3. RAM RAM. RAM .

  4. START

  5. 1 .

  6. STOP

. , . EEPROM .

EEPROM :

  1. START

  2. , 1 (). - 0

  3. EEPROM EEPROM ( )

  4. START

  5. STOP

EEPROM

uint16_t readEEPROM( uint16_t address, uint16_t eeprom_address ){

	 uint16_t	data_msb;
	 uint16_t	data_lsb;
	 uint16_t data_result;

	 address = address<<1; 																//     (    + 1  /)

	 	 I2C1->CR1 |= I2C_CR1_START;
		 while (!(I2C1->SR1 & I2C_SR1_SB)){}

		 (void) I2C1->SR1;

		 I2C1->DR = address | MLX90614_WRITE; 							//   ,   MLX90614
		 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

		 (void) I2C1->SR1;
		 (void) I2C1->SR2;

		 I2C1->DR= eeprom_address | MLX90614_EEPROM_ACCESS;	//   EEPROM  MLX90614
		 while (!(I2C1->SR1 & I2C_SR1_TXE)){}

		 I2C1->CR1 |= I2C_CR1_START;												//  
		 while (!(I2C1->SR1 & I2C_SR1_SB)){}

		 (void) I2C1->SR1;

		 I2C1->DR = address | MLX90614_READ;								//     
		 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

		 (void) I2C1->SR1;
		 (void) I2C1->SR2;

		 //I2C1->CR1 &= ~I2C_CR1_ACK;
		 while (!(I2C1->SR1 & I2C_SR1_RXNE)){};

		 data_lsb = I2C1->DR;															//   

		 while(!(I2C1->SR1 & I2C_SR1_RXNE)){}

		 data_msb = I2C1->DR;															//   


		 I2C1->CR1 |= I2C_CR1_STOP;


		data_result = ((data_msb << 8) | data_lsb) ;

		 return data_result;


}

EEPROM RAM. .

. :

  1. START

  2. ,

  3. EEPROM EEPROM

  4. PEC ( )

  5. STOP

, . , , .

EEPROM

void writeEEPROM ( uint16_t address, uint16_t eeprom_address, uint16_t data ){


		 address = address<<1; 																//     (..    + 1  /)

		 	 I2C1->CR1 |= I2C_CR1_START;
			 while (!(I2C1->SR1 & I2C_SR1_SB)){}

			 (void) I2C1->SR1;

			 I2C1->DR = address | MLX90614_WRITE; 							//   ,   MLX90614
			 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

			 (void) I2C1->SR1;
			 (void) I2C1->SR2;

			 I2C1->DR= eeprom_address | MLX90614_EEPROM_ACCESS;	//   EEPROM  MLX90614
			 while (!(I2C1->SR1 & I2C_SR1_TXE)){}

			 I2C1->DR =  ( uint8_t ) ( data & 0x00FF );					//   

			 while(!(I2C1->SR1 & I2C_SR1_BTF)){}

			 I2C1->DR = ( uint8_t ) ( data >> 8 )	;							//   
			 while(!(I2C1->SR1 & I2C_SR1_BTF)){}

			 I2C1->CR1 |= I2C_CR1_PEC;													//  PEC
			 I2C1->CR1 |= I2C_CR1_STOP;


			 return ;
}

EEPROM. . , .

uint16_t getAddrFromEEPROM ( uint16_t address ){

	uint16_t addr_eeprom;
	addr_eeprom = readEEPROM( address, MLX90614_SMBUS_ADDRESS );

	return addr_eeprom;

}

. , readEEPROM() EEPROM .

EEPROM . MLX90614 EEPROM:

  1. ,

  2. 10

  3. 10

  4. , ,

. . , , , . - , EEPROM ? ? , . , .

EEPROM

int setAddrToEEPROM ( uint16_t address, uint16_t new_address ){

	uint16_t addr;

	writeEEPROM ( address, MLX90614_SMBUS_ADDRESS, 0x0); 					//  
	delay_ms(10);
	writeEEPROM (address, MLX90614_SMBUS_ADDRESS, new_address ); 	//   
	delay_ms(10);
	addr = readEEPROM ( address, MLX90614_SMBUS_ADDRESS );			 	//   

	if ( addr == new_address){
		return 1;
	}

	else return 0;

}

. main()

#include "main.h"
#include <stdio.h>
int main (void){

	clk_ini(); 										//   
	lcd_2004a_init(); 						//   a2004
	mlx90614Init(); 							//  I2C  

	uint16_t geted_eeprom_address;
	char char_eeprom_address[20];
	char crystal_temp[10];   			//    
	char first_sensor_temp[10];
//     EEPROM    LCD
	geted_eeprom_address = getAddrFromEEPROM( 0x5A );
	sprintf(char_eeprom_address, "%x", (uint8_t) geted_eeprom_address);
	sendStr("addr value:", 3, 0);
	sendStr (char_eeprom_address, 3, 14 );

	setAddrToEEPROM (0x5A , 0xA); //   
//       LCD
	geted_eeprom_address = getAddrFromEEPROM( 0x5A );
	sprintf(char_eeprom_address, "%x", (uint8_t) geted_eeprom_address);
	sendStr("new addr :", 4, 0);
	sendStr (char_eeprom_address, 4, 14 );



	while(1){
//        
		 getTemp_Mlx90614_CharArray ( 0x5A,  MLX90614_TA, crystal_temp );
		 sendStr( "Crystal Temp :", 1, 0 );
		 sendStr( crystal_temp, 1, 14 );
    
		delay_s(1);
    
		 getTemp_Mlx90614_CharArray ( 0x5A,  MLX90614_TOBJ_1, first_sensor_temp );
		 sendStr( "Sensor Temp  :", 2, 0 );
		 sendStr( first_sensor_temp, 2, 14 );
    
			delay_s(1);
	}
}

main.h

#ifndef CORE_INC_MAIN_H_
#define CORE_INC_MAIN_H_

#include "stm32f1xx.h"
#include "clk_ini.h" //  
#include "delay.h"		//  
#include "lcd_20x4.h" //     LCD A2004
#include "mlx90614.h" //    

#endif /* CORE_INC_MAIN_H_ */

:

总之,完整的项目清单

mlx90614.h
#ifndef I2C_DEVICES_I2C_H_
#define I2C_DEVICES_I2C_H_

#include "stm32f1xx.h"
#include <stdio.h>
#include "delay.h"

#define F_APB1 36 //   APB1
#define TPCLK1 ( 1000/F_APB1 ) //   APB1 ns. ~ 28
#define CCR_VALUE ( 10000 /(TPCLK1 * 2 ) ) //   CCR  36  ~ 179
#define TRISE_VALUE ( 1000 / TPCLK1)

//---------------- RAM addresses --------------------------------------------
#define MLX90614_RAW_IR_1 0x04		//    
#define MLX90614_RAW_IR_2 0x05
#define MLX90614_TA 0x06			//   
#define MLX90614_TOBJ_1 0x07		//     
#define MLX90614_TOBJ_2 0x08		//     

//--------------- EEPROM addresses ------------------------------------------
#define MLX90614_TO_MAX 0x00
#define MLX90614_TO_MIN 0x01
#define MLX90614_PWM_CTRL 0x02
#define MLX90614_TA_RANGE 0x03
#define MLX90614_EMISSIVITY 0x04
#define MLX90614_CONFIG_REGISTER_1 0x05
#define MLX90614_SMBUS_ADDRESS 0x0E // LSByte only
#define MLX90614_ID_NUMBER_1 0x1C
#define MLX90614_ID_NUMBER_2 0x1D
#define MLX90614_ID_NUMBER_3 0x1E
#define MLX90614_ID_NUMBER_4 0x1F

//--------------- Commands ------------------------------------------------
#define MLX90614_RAM_ACCESS 0 			//   RAM
#define MLX90614_EEPROM_ACCESS 0x20 	//   EEPROM
#define MLX90614_READ_FLAGS 0xF0 		//  
#define MLX90614_ENTER_SLEEP_MODE 0xFF 	//  
#define MLX90614_READ 1					//    
#define MLX90614_WRITE 0				//    

void mlx90614Init( void );
double getTemp_Mlx90614_Double( uint16_t address, uint8_t ram_address );
void getTemp_Mlx90614_CharArray( uint16_t address, uint8_t ram_address, char* buf );

uint16_t getAddrFromEEPROM( uint16_t address );
int setAddrToEEPROM ( uint16_t address, uint16_t new_address );

uint16_t readEEPROM( uint16_t address, uint16_t eeprom_address );
void writeEEPROM ( uint16_t address, uint16_t eeprom_address, uint16_t data );

#endif /* I2C_DEVICES_I2C_H_ */

mlx90614.c
#include "mlx90614.h"

/********************************************************************************************
 *   I2C      MLX90614   					*
 * 																		 					*
 ********************************************************************************************/

 void mlx90614Init(void){

	 delay_ms(120);								//        

RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;				//  
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;				//  i2c1

GPIOB->CRL |= GPIO_CRL_MODE6 | GPIO_CRL_MODE7;	//  50 
GPIOB->CRL |= GPIO_CRL_CNF6 | GPIO_CRL_CNF7; 	//  -  

I2C1->CR2 &= ~I2C_CR2_FREQ; 					//       APB1
I2C1->CR2 |= F_APB1; 							//    APB1    I2C 
I2C1->CR1 &= ~I2C_CR1_PE; 						//   I2C    CCR
I2C1->CCR &= ~I2C_CCR_CCR;
I2C1->CCR |=  CCR_VALUE;
I2C1->TRISE |=  TRISE_VALUE;

I2C1->CR1 |= I2C_CR1_ENPEC; 					//   PEC
I2C1->CR1 |= I2C_CR1_PE;						//   I2C
I2C1->CR1 |= I2C_CR1_ACK; 						//  ACK

}

/********************************************************************************************
 *      .    double. 					*
 * 																		  					*
 *  : 														   					*
 * address - 				  MLX90614						   					*
 * 																		   					*
 * ram_address RAM-   ( .   .h  ) : 		   					*
 * 																		   					*
 * 	MLX90614_TA - 		  					   					*
 * 	MLX90614_TOBJ_1 - 	   					   					*
 * 	MLX90614_TOBJ_2 - 	   					  					*
  *******************************************************************************************/

double getTemp_Mlx90614_Double( uint16_t address,
								uint8_t ram_address){

	 uint16_t	temp ; 						// 
	 uint8_t	temp_lsb ;					//   
	 double temp_result ; 					//   
	 double temp_double ;					// ,    double

	 address = address<<1; 						//     (  
	 	 	 	 	 	 	 	 	 	 	 	//   1-  /)
	 I2C1->CR1 |= I2C_CR1_START;
	 while (!(I2C1->SR1 & I2C_SR1_SB)){}

	 (void) I2C1->SR1;

	 I2C1->DR = address | MLX90614_WRITE; 		//   ,   MLX90614
	 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

	 (void) I2C1->SR1;
	 (void) I2C1->SR2;

	 I2C1->DR= ram_address;						//   RAM   MLX90614
	 while (!(I2C1->SR1 & I2C_SR1_TXE)){}

	 I2C1->CR1 |= I2C_CR1_START;				//  
	 while (!(I2C1->SR1 & I2C_SR1_SB)){}

	 (void) I2C1->SR1;

	 I2C1->DR = address | MLX90614_READ;			//     
	 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

	 (void) I2C1->SR1;
	 (void) I2C1->SR2;

	 while(!(I2C1->SR1 & I2C_SR1_RXNE)){}

	 temp_lsb = I2C1->DR;							//   

	 while(!(I2C1->SR1 & I2C_SR1_RXNE)){}

	 temp = I2C1->DR;								//   

	 I2C1->CR1 |= I2C_CR1_STOP;

	 temp = (temp & 0x007F) << 8;					//   ,    
	 temp |= temp_lsb;
	 temp_double = (double) temp; 					//    double
	 temp_result =  ((temp_double * 0.02)- 0.01 );	//    
	 temp_result = temp_result - 273.15; 			//    . 



return temp_result;


 }


/********************************************************************************************
 *   ,   ,   char   .  *
 * 																							*
 *  : 																			*
 * address - 			  MLX90614												*
 * 																							*
 * ram_address RAM-   ( .   .h  ) : 							*
 * 																							*
 * 	MLX90614_TA - 		  										*
 * 	MLX90614_TOBJ_1 - 	   										*
 * 	MLX90614_TOBJ_2 - 	   										*
 * 																							*
 * 	*buf - 				  													*
 *******************************************************************************************/

void getTemp_Mlx90614_CharArray( uint16_t address, uint8_t ram_address, char* buf){

	double t;
	t = getTemp_Mlx90614_Double(address,ram_address);

	 sprintf(buf, "%.1f",t);

	return ;

}



/********************************************************************************************
 *   EEPROM    											*
 *  :																			*
 * address -  																	*
 * eeprom_address -   EEPROM															*
 * 																							*
 *  :																			*
 *    EEPROM  uint16_t													*
 *																							*
 * ******************************************************************************************/

uint16_t readEEPROM( uint16_t address, uint16_t eeprom_address ){

	 uint16_t	data_msb;
	 uint16_t	data_lsb;
	 uint16_t data_result;

	 address = address<<1; 									//     (    + 1  /)

	 	 I2C1->CR1 |= I2C_CR1_START;
		 while (!(I2C1->SR1 & I2C_SR1_SB)){}

		 (void) I2C1->SR1;

		 I2C1->DR = address | MLX90614_WRITE; 				//   ,   MLX90614
		 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

		 (void) I2C1->SR1;
		 (void) I2C1->SR2;

		 I2C1->DR= eeprom_address | MLX90614_EEPROM_ACCESS;	//   EEPROM  MLX90614
		 while (!(I2C1->SR1 & I2C_SR1_TXE)){}

		 I2C1->CR1 |= I2C_CR1_START;						//  
		 while (!(I2C1->SR1 & I2C_SR1_SB)){}

		 (void) I2C1->SR1;

		 I2C1->DR = address | MLX90614_READ;				//     
		 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

		 (void) I2C1->SR1;
		 (void) I2C1->SR2;

		 //I2C1->CR1 &= ~I2C_CR1_ACK;
		 while (!(I2C1->SR1 & I2C_SR1_RXNE)){};

		 data_lsb = I2C1->DR;								//   

		 while(!(I2C1->SR1 & I2C_SR1_RXNE)){}

		 data_msb = I2C1->DR;									//   


		 I2C1->CR1 |= I2C_CR1_STOP;


		data_result = ((data_msb << 8) | data_lsb) ;//& 0x1F;

		 return data_result;


}

/********************************************************************************************
 *   EEPROM    												    *
 * 																						    *
 *  :																		    *
 * address - 		 														    *
 * eeprom_address -   EEPROM														    *
 * data - 																			    *
 ********************************************************************************************/
void writeEEPROM ( uint16_t address, uint16_t eeprom_address, uint16_t data ){


		 address = address<<1; 									//     (..    + 1  /)

		 	 I2C1->CR1 |= I2C_CR1_START;
			 while (!(I2C1->SR1 & I2C_SR1_SB)){}

			 (void) I2C1->SR1;

			 I2C1->DR = address | MLX90614_WRITE; 				//   ,   MLX90614
			 while (!(I2C1->SR1 & I2C_SR1_ADDR)){}

			 (void) I2C1->SR1;
			 (void) I2C1->SR2;

			 I2C1->DR= eeprom_address | MLX90614_EEPROM_ACCESS;	//   EEPROM  MLX90614
			 while (!(I2C1->SR1 & I2C_SR1_TXE)){}

			 I2C1->DR =  ( uint8_t ) ( data & 0x00FF );			//   

			 while(!(I2C1->SR1 & I2C_SR1_BTF)){}

			 I2C1->DR = ( uint8_t ) ( data >> 8 )	;			//   
			 while(!(I2C1->SR1 & I2C_SR1_BTF)){}

			 I2C1->CR1 |= I2C_CR1_PEC;							//  PEC
			 I2C1->CR1 |= I2C_CR1_STOP;


			 return ;
}

/********************************************************************************************
 *     EEPROM															*
 * 																							*
 *  :																			*
 * address -  																	*
 *																							*
 *  :																			*
 *    uint8_t																	*
 *  																						*
 *******************************************************************************************/

uint16_t getAddrFromEEPROM ( uint16_t address ){

	uint16_t addr_eeprom;
	addr_eeprom = readEEPROM( address, MLX90614_SMBUS_ADDRESS );

	return addr_eeprom;

}

/********************************************************************************************
 *      EEPROM													*
 * 																							*
 *  :																			*
 * address - 		  															*
 * new_address -	 															*
 * 																							*
 *  1 - / 0 - 														*
 ********************************************************************************************/

int setAddrToEEPROM ( uint16_t address, uint16_t new_address ){

	uint16_t addr;

	writeEEPROM ( address, MLX90614_SMBUS_ADDRESS, 0x0); //  
	delay_ms(10);
	writeEEPROM (address, MLX90614_SMBUS_ADDRESS, new_address ); //   
	delay_ms(10);
	addr = readEEPROM ( address, MLX90614_SMBUS_ADDRESS ); //   

	if ( addr == new_address){
		return 1;
	}

	else return 0;

}

clk_ini.h
#ifndef INC_CLK_INI_H_
#define INC_CLK_INI_H_
#include "stm32f1xx.h"

int clk_ini(void);
#endif /* INC_CLK_INI_H_ */

clk_ini.c
#include "clk_ini.h"

int clk_ini(void){

	RCC->CR |= (1 << RCC_CR_HSEON_Pos);

	__IO int startCounter;
	for(startCounter = 0; ; startCounter++){

		if(RCC->CR & (1 << RCC_CR_HSERDY_Pos)){

			break;
		}// if

		if(startCounter > 0x1000){

			RCC->CR &= ~(1 << RCC_CR_HSEON_Pos);
			return 1;
		}
	}// for

	RCC->CFGR |= (0x07 << RCC_CFGR_PLLMULL_Pos) // PLL x9
			 	 |(0x01 << RCC_CFGR_PLLSRC_Pos); // start clocking PLL of HSE

	RCC->CR |= (1 << RCC_CR_PLLON_Pos);

	for(startCounter = 0; ; startCounter++){

		if(RCC->CR & (1 << RCC_CR_PLLRDY_Pos)){

			break;
		}//if

		if(startCounter > 0x1000){

			RCC->CR &= ~(1 << RCC_CR_HSEON_Pos);
			RCC->CR &= ~(1 << RCC_CR_PLLON_Pos);
			return 2;
		}// if
	}// for

	////////////////////////////////////////////////////////////
	  // FLASH  
	  ////////////////////////////////////////////////////////////

	  // 2    Flash
	  //       48 MHz < SYSCLK <= 72 MHz
	  FLASH->ACR |= (0x02<<FLASH_ACR_LATENCY_Pos);

	  //
	  RCC->CFGR |= (0x00<<RCC_CFGR_PPRE2_Pos) //  APB2  1
	            | (0x04<<RCC_CFGR_PPRE1_Pos) //  APB1  2
	            | (0x00<<RCC_CFGR_HPRE_Pos); // AHB 


	  RCC->CFGR |= (0x02<<RCC_CFGR_SW_Pos); //    PLL

	  //,  
	  while((RCC->CFGR & RCC_CFGR_SWS_Msk) != (0x02<<RCC_CFGR_SWS_Pos))
	  {
	  }

	  // ,   
	  //  
	  //  RC-
	  //  
	  RCC->CR &= ~(1<<RCC_CR_HSION_Pos);

	  //   
	  //   
	  // PLL  .
	  //

	return 0;
}

延迟
#ifndef DELAY_DELAY_H_
#define DELAY_DELAY_H_

#include "stm32f1xx.h"

#define F_CPU 72000000UL
#define US F_CPU/1000000
#define MS F_CPU/1000
#define SYSTICK_MAX_VALUE 16777215
#define US_MAX_VALUE SYSTICK_MAX_VALUE/(US)
#define MS_MAX_VALUE SYSTICK_MAX_VALUE/(MS)


void delay_us(uint32_t us); //  233 
void delay_ms(uint32_t ms); //  233 
void delay_s(uint32_t s);

延迟
#include "delay.h"


/*      */

void delay_us(uint32_t us){ //  233 016 

	if (us > US_MAX_VALUE || us == 0)
		return;

	SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //     0
	SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk; //    
	SysTick->LOAD = (US * us-1); //       
	SysTick->VAL = 0; //     SYST_CVR
	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //  

	while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); //    COUNFLAG   SYST_CSR

	SysTick->CTRL &= ~SysTick_CTRL_COUNTFLAG_Msk;	//   COUNTFLAG
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //  
	return;

}

void delay_ms(uint32_t ms){ //  233 

	if(ms > MS_MAX_VALUE || ms ==0)
		return;

	SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
	SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
	SysTick->LOAD = (MS * ms);
	SysTick->VAL = 0;
	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

	while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));

	SysTick->CTRL &= ~SysTick_CTRL_COUNTFLAG_Msk;
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
return;

}

void delay_s(uint32_t s){

	for(int i=0; i<s*5;i++) delay_ms(200);
	return;
}

lcd_20x4.h
#ifndef LCD_LCD_20X4_2004A_LCD_20X4_H_
#define LCD_LCD_20X4_2004A_LCD_20X4_H_

#include "stm32f1xx.h"
#include "delay.h"

// display commands

#define CLEAR_DISPLAY 0x1
#define RETURN_HOME 0x2
#define ENTRY_MODE_SET 0x6 // mode cursor shift rihgt, display non shift
#define DISPLAY_ON 0xC // non cursor
#define DISPLAY_OFF 0x8
#define CURSOR_SHIFT_LEFT 0x10
#define CURSOR_SHIFT_RIGHT 0x14
#define DISPLAY_SHIFT_LEFT 0x18
#define DISPLAY_SHIFT_RIGHT 0x1C
#define DATA_BUS_4BIT_PAGE0 0x28
#define DATA_BUS_4BIT_PAGE1 0x2A
#define DATA_BUS_8BIT_PAGE0 0x38
#define SET_CGRAM_ADDRESS 0x40 // usage address |= SET_CGRAM_ADDRESS
#define SET_DDRAM_ADDRESS 0x80

//     ODR
#define PIN_RS 0x1
#define PIN_EN 0x2
#define PIN_D4 0x1000
#define PIN_D5 0x2000
#define PIN_D6 0x4000
#define PIN_D7 0x8000

#define     LCD_PORT               	GPIOB
#define		LCD_ODR 				LCD_PORT->ODR

#define     LCD_PIN_RS()     		LCD_PORT->CRL |= GPIO_CRL_MODE0_0;\
									LCD_PORT->CRL &= ~GPIO_CRL_CNF0; // PB0   -,  10 

#define     LCD_PIN_EN()            LCD_PORT->CRL |= GPIO_CRL_MODE1_0;\
									LCD_PORT->CRL &= ~GPIO_CRL_CNF1;        // PB1

#define     LCD_PIN_D4()            LCD_PORT->CRH |= GPIO_CRH_MODE12_0;\
									LCD_PORT->CRH &= ~GPIO_CRH_CNF12;          // PB7

#define     LCD_PIN_D5()           	LCD_PORT->CRH |= GPIO_CRH_MODE13_0;\
									LCD_PORT->CRH &= ~GPIO_CRH_CNF13;      // PB6

#define     LCD_PIN_D6()            LCD_PORT->CRH |= GPIO_CRH_MODE14_0;\
									LCD_PORT->CRH &= ~GPIO_CRH_CNF14;         // PB5

#define     LCD_PIN_D7()            LCD_PORT->CRH |= GPIO_CRH_MODE15_0;\
									LCD_PORT->CRH &= ~GPIO_CRH_CNF15;         // PB10

#define     LCD_PIN_MASK   (PIN_RS | PIN_EN | PIN_D7 | PIN_D6 | PIN_D5 | PIN_D4) // 0b0000000011110011    

void lcd_2004a_init(void); //     
void sendByte(char byte, int isData);
void sendStr(char *str, int row , int position); //  


#endif /* LCD_LCD_20X4_2004A_LCD_20X4_H_ */

lcd_20x4.c
#include "lcd_20x4.h"

//     LCD

void lcdInit(void); //  


void sendByte(char byte, int isData){

	//   
	LCD_ODR &= ~LCD_PIN_MASK;

	if(isData == 1) LCD_ODR |= PIN_RS; //    RS
		else LCD_ODR &= ~(PIN_RS);		   //   RS

	//   E
		LCD_ODR |= PIN_EN;

	//     
	if(byte & 0x80) LCD_ODR |= PIN_D7;
	if(byte & 0x40) LCD_ODR |= PIN_D6;
	if(byte & 0x20) LCD_ODR |= PIN_D5;
	if(byte & 0x10) LCD_ODR |= PIN_D4;
	
	LCD_ODR &= ~PIN_EN; //   

	//     RS
	LCD_ODR &= ~(LCD_PIN_MASK & ~PIN_RS);

	//   E

		LCD_ODR |= PIN_EN;
	//     
	if(byte & 0x8) LCD_ODR |= PIN_D7;
	if(byte & 0x4) LCD_ODR |= PIN_D6;
	if(byte & 0x2) LCD_ODR |= PIN_D5;
	if(byte & 0x1) LCD_ODR |= PIN_D4;

	//   

	LCD_ODR &= ~(PIN_EN);
	delay_us(40);


	return;
}

//               50 

void lcd_2004a_init(void){

//----------------------  ----------------------------------------------------

	if(LCD_PORT == GPIOB) RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
	else if (LCD_PORT == GPIOA) RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
	else return;

//---------------------    LCD-----------------------------------------------------

		LCD_PIN_RS();
		LCD_PIN_EN();
		LCD_PIN_D7();
		LCD_PIN_D6();
		LCD_PIN_D5();
		LCD_PIN_D4();


		lcdInit();






	return ;
}

//---------------------  -----------------------------------------------------------
void lcdInit(void){



			delay_ms(200); //    

			sendByte(0x33, 0); //      0011
			delay_us(120);

			sendByte(0x32, 0); //      00110010
			delay_us(40);

			sendByte(DATA_BUS_4BIT_PAGE0, 0); //   4 
			delay_us(40);
			sendByte(DISPLAY_OFF, 0); //  
			delay_us(40);
			sendByte(CLEAR_DISPLAY, 0); //  
			delay_ms(2);
			sendByte(ENTRY_MODE_SET, 0); //      
			delay_us(40);
			sendByte(DISPLAY_ON, 0);//     
			delay_us(40);


	return ;
}

void sendStr( char *str, int row , int position ){

	char start_address;

	switch (row) {

	case 1:
		start_address = 0x0; // 1 
		break;

	case 2:
		start_address = 0x40; // 2 
		break;

	case 3:
		start_address = 0x14; // 3 
		break;

	case 4:
		start_address = 0x54; // 4 
		break;

	}

	start_address += position; //       

	sendByte((start_address |= SET_DDRAM_ADDRESS), 0); //         DDRAM

	delay_ms(4);
	while(*str != '\0'){

		sendByte(*str, 1);
		str++;


	}// while
}




All Articles