stm32-软件IIC/I2C

系列文章目录第一章

stm32ze 软件 IIC/i2c 驱动代码 ;

前言

软件IIC : GPIO开漏模式 , I2C主机模式 。编码格式:GB2312
废话不多 ,上代码。
note.仅供参考 – 手下留情…

二、使用步骤

1.软件IIC test code

2.软件IIC 头文件

3.软件IIC 源文件

**1 test - main ()

/***  test code  ****/
#include "stm32f10x.h"   
#include "bsp_systick.h"
#include "bsp_usart.h"
#include "bsp_ee_iic.h"
#include "string.h"
#include "ctype.h" 

char  *wStr = "7891011";
uint8_t rStr[8] = {0};
int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	/* init */
    bsp_UsartAndIT_Init();
	bsp_RGB_LedConfig();
	bsp_EE_Config();
	// test 
	//EE_Write_byte(170,68);
   EE_Write_nString(0,(uint8_t*)wStr);
	// test 
	//EE_Write_byte(170,68);  
    EE_Write_nString(0,(uint8_t*)wStr);
    EE_waitWriteComplete(); // wait for EEPROM written complete
	//EE_Read_byte(170,&temp);
    EE_Read_nString(0,rStr);
	printf("sTr = %s\n",rStr);	
	while(1)
	{	
	}
}

2 head code

#ifndef  _BSP_EE_IIC_H
#define  _BSP_EE_IIC_H
#include "stm32f10x.h"

#include "bsp_systick.h"

/**************** Bit band   ***************/
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 


#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //out
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //in

/**************** I/O out Macro **************/

#define    rxSlaveADDR              0xA1
#define    wxSlaveADDR              0xA0

#define    IIC_SCL                  PBout(6) 
#define    IIC_SCL_I                PBin(6) 

#define    IIC_SDA_O                PBout(7)
#define    IIC_SDA_I                PBin(7)
//#define    IIC_SDA_I              GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)     
/****************  Port macro   **************/
#define    mI2Cx_GPIO_PORT          GPIOB

#define    mI2Cx_SCL_GPIO_PIN       GPIO_Pin_6
#define    mI2Cx_SDA_GPIO_PIN       GPIO_Pin_7

#define    mI2Cx_GPIO_CLK_Cmd       RCC_APB2PeriphClockCmd
#define    mI2Cx_GPIO_PORT_CLK      RCC_APB2Periph_GPIOB

/****************  EEPROM function   **************/
void bsp_EE_Config(void);
void EE_waitWriteComplete(void);
uint8_t EE_Read_byte(uint8_t dataAddr ,uint8_t *byte);
uint8_t EE_Write_byte(uint8_t dataAddr ,uint8_t byte);
uint8_t EE_Read_nString(uint8_t dataAddr ,uint8_t *byte);
uint8_t EE_Write_nString(uint8_t dataAddr ,uint8_t *byte);
#endif /* _BSP_EE_IIC_H */

3. source file

/*  version: 1.0
 *  auther : ylb
 *  date   : 2022.3.27
 *  purpose: software I2C master ctrl mode (host)  
 *  speed  : 100kHz - 400kHz ;
 *  device : 72MHZ
 */ 
 /*************   Pravate  include       ***********/
#include "bsp_ee_iic.h"
#include "bsp_RGB_led.h"
#include "bsp_usart.h"


/*  delay function : modifyAble  */
static void delay_xus(void)
{
	uint16_t i=10;// i ≈ (1 - 100 ) us
	while(i--);
} 
/**
  * @brief   Init IIC port  PB6,PB7
  *      
  * @param   None
  *
  * @retval  None
  */
void bsp_EE_Config(void)
{
	GPIO_InitTypeDef GPIO_InitTypeDefStruct;
	// open GPIO clock   
	mI2Cx_GPIO_CLK_Cmd(mI2Cx_GPIO_PORT_CLK,ENABLE);
	//GPIO_Mode_Out_OD
	GPIO_InitTypeDefStruct.GPIO_Pin = mI2Cx_SCL_GPIO_PIN;
	GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init(mI2Cx_GPIO_PORT,&GPIO_InitTypeDefStruct);
	
	GPIO_InitTypeDefStruct.GPIO_Pin = mI2Cx_SDA_GPIO_PIN;
	GPIO_Init(mI2Cx_GPIO_PORT,&GPIO_InitTypeDefStruct);
     // setup high level 
	GPIO_SetBits(mI2Cx_GPIO_PORT,mI2Cx_SCL_GPIO_PIN|mI2Cx_SDA_GPIO_PIN);	
}
/* start signal */
static void IIC_start(void)
{
	IIC_SCL = 1; 
	IIC_SDA_O = 1; 
	delay_xus();
	IIC_SDA_O = 0;
	delay_xus();
	IIC_SCL = 0;	
}
/* stop signal */
static void IIC_stop(void)
{
	IIC_SCL = 0;	
	IIC_SDA_O = 0;
	IIC_SCL = 1;
	delay_xus();
    IIC_SDA_O = 1;
	delay_xus();
}
/* send ACK signal */
static void IIC_txACK(void)
{
	IIC_SDA_O = 0; 
	delay_xus();	 
	IIC_SCL = 1; 
	delay_xus();
    IIC_SCL = 0;	
	IIC_SDA_O = 1;	
}
/* send NACK signal */
static void IIC_txNACK(void)
{   
	IIC_SCL = 0;
	IIC_SDA_O = 1; 
	delay_xus();
	IIC_SCL = 1;   
	delay_xus();
	IIC_SCL = 0;
}
/* receive ACK .return 1 : no got . return 0 : ok . */
static uint8_t IIC_rxACK(void)
{   
	IIC_SCL = 0;
	delay_xus();
	IIC_SCL = 1;
	if(IIC_SDA_I){ return 1;  } 
	delay_xus();  
	IIC_SCL = 0;
	IIC_SDA_O=1;
    return 0;	  
}
/**
  * @brief   IIC send a byte
  *      
  * @param   byte: data to be sent
  *
  * @retval  None .
  */
static void IIC_Send_Byte(uint8_t byte)
{	
    uint8_t i=0;	
	
	for(i=0;i<8;i++)
	{
		if(byte&(0x80>>i)){IIC_SDA_O = 1;}              
		else { IIC_SDA_O = 0;}	   	
		IIC_SCL = 1;
		delay_xus();
		IIC_SCL = 0;
		delay_xus();	
	}
	IIC_SDA_O = 1;
}
/**
  * @brief  IIC receive a byte
  *      
  * @param   None
  *
  * @retval  rutern got byte .
  */
static uint16_t IIC_Reveive_byte(void)
{
	uint8_t i=0;
	uint16_t byte=0X00;
	for(i=0;i<8;i++)
	{   
		IIC_SCL = 0;
		IIC_SCL = 1;
		if(IIC_SDA_I){byte|=(0x80>>i);}		    
        delay_xus();		
		IIC_SCL = 0;
		delay_xus();
	}	
	return byte;
}
/**
  * @brief   written a byte to EEPROM
  *      
  * @param   dataAddr: operation of byteAddr
  * @param       byte: written data
  *
  * @retval  0 succeed ,1 failed .
  */
uint8_t EE_Write_byte(uint8_t dataAddr ,uint8_t byte)
{
	IIC_start();
	IIC_Send_Byte(wxSlaveADDR);
	if(IIC_rxACK()) {return 1;}
	IIC_Send_Byte(dataAddr);
	if(IIC_rxACK()) {return 1;}
	IIC_Send_Byte(byte);
	IIC_rxACK();
	IIC_stop();
	return 0; //succeed written
}
/**
  * @brief  Read a byte from EEPROM
  *
  * @param  dataAddr: operation of byteAddr     
  * @param  *byte: readed data of pointer
  *
  * @retval 0 succeed , 1 failed .
  */
uint8_t EE_Read_byte(uint8_t dataAddr ,uint8_t *byte)
{
	IIC_start();
	IIC_Send_Byte(wxSlaveADDR);
	if(IIC_rxACK()) {return 1;}
	IIC_Send_Byte(dataAddr);
	if(IIC_rxACK()) {return 1;}
	// reStart
	IIC_start();
	IIC_Send_Byte(rxSlaveADDR);
	if(IIC_rxACK()) {return 1;}
	*byte=IIC_Reveive_byte();
	IIC_txNACK();
	IIC_stop();
	return 0;	
}
/**
  * @brief  written a str to EEPROM( 8-byte page )
  *          
  * @param  dataAddr: operation of byteAddr
  * @param       byte: written string (less-than < 8 byte)
  *
  * @retval 0 succeed ,1 failed .
  */
uint8_t EE_Write_nString(uint8_t dataAddr ,uint8_t *byte)
{
	uint8_t i=0,num =0 ;
	for(i=0;i<8;i++)
	{
	//++num; /* want to written '\0'; open: ++num; close: num++;*/
	  if(byte[i] == '\0')break;
	  num++;   		
	}
	printf("num= %d",num);
	IIC_start();
	IIC_Send_Byte(wxSlaveADDR);
	if(IIC_rxACK()) {return 1;}
	IIC_Send_Byte(dataAddr);
	if(IIC_rxACK()) {return 1;}
    while(num--)
	{
	IIC_Send_Byte(*byte);
	IIC_rxACK();
	byte++;
	}
	IIC_stop();
	return 0; //succeed written
}
/**
  * @brief  Read a byte from EEPROM
  *
  * @param  dataAddr: operation of byteAddr     
  * @param  *byte: readed string of pointer(less-than < 8 byte)
  *
  * @retval 0 succeed , 1 failed .
  */
uint8_t EE_Read_nString(uint8_t dataAddr ,uint8_t *byte)
{
	uint8_t i = 0;
	IIC_start();
	IIC_Send_Byte(wxSlaveADDR);
	if(IIC_rxACK()) {return 1;}
	IIC_Send_Byte(dataAddr);
	if(IIC_rxACK()) {return 1;}
	// reStart
	IIC_start();
	IIC_Send_Byte(rxSlaveADDR);
	if(IIC_rxACK()) {return 1;}
	do
	{	 
	byte[i]=IIC_Reveive_byte();
	IIC_txACK();
	++i;
    }while((byte[i-1] != '\0') && (i<8));
	IIC_txNACK();
	IIC_stop();
	return 0 ;
}
/**
  * @brief   wait for write complete
  *      
  * @param   dataAddr: operation of byteAddr 
  *
  * @retval  None.
  */
void EE_waitWriteComplete(void)
{
	uint16_t timOut = 100;
	do{
		IIC_stop();
		IIC_start();	
	    IIC_Send_Byte(wxSlaveADDR);
		timOut--;
		if(timOut==0){IIC_stop();printf("| EE_timOut |");return;}
	}while(IIC_rxACK());
	IIC_stop();
}
/************************* IIC - EEPROM  end *************************/

总结

活在酒里,,,,
睡在梦里,,,,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值