系列文章目录第一章
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 *************************/
总结
活在酒里,,,,
睡在梦里,,,,