您的位置 首页 系统

STM32运用模仿IIC操作EEPROM

贴出stm32f103vet6使用模拟IIC操作EEPROM的代码:头文件部分i2c.h#ifndef_i2c_H_#define_i2c_H_#includestm32f10x.h#defineco

贴出stm32f103vet6运用模仿IIC操作EEPROM的代码:

头文件部分i2c.h

#ifndef _i2c_H_
#define _i2c_H_

#include “stm32f10x.h”
#define countof(a) (sizeof(a)/sizeof(*(a)))

#define GPIOA_IDR_Addr (GPIOA_BASE + 8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE + 8) //

/*位带操作,完成51类似的GPIO操控功用*/
/*IO口操作宏界说 */
#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))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C

#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入

//IO方向设置
#define SDA_IN() {GPIOA->CRL&=0XFFFF0FFF;GPIOA->CRL|=8<<12;}
#define SDA_OUT() {GPIOA->CRL&=0XFFFF0FFF;GPIOA->CRL|=3<<12;} //IO操作函数
#define IIC_SCL PAout(2) //SCL—PA2
#define IIC_SDA PAout(3) //SDA—PA3
#define READ_SDA PAin(3) //输入SDA

#define EEPROM_SLAVE_ADDRESS (0x50)

//IIC一切操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开端信号
void IIC_Stop(void); //发送IIC中止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
unsigned char IIC_Read_Byte( void );//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等候ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号

unsigned char eeprom_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,unsigned char u_data);
unsigned char eeprom_read(unsigned char c_slave_address7bit,unsigned char c_reg_address);
unsigned char eeprom_continue_read(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_read_arr[],unsigned int len);
unsigned char eeprom_continue_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_write_arr[],unsigned int len);
unsigned char read_eeprom_status(unsigned char c_slave_address7bit);

#endif

源码i2c.c

#include “i2c.h”
#include “stm32f10x.h”

static void Delay_us(int value)
{
int i = 0,j;
for(i = 0 ; i < 5 ; i ++)
for(j = 0 ; j < value ; j ++)
;
}

//////////////////////////////////////////////////////////////////////////
// 函数名 : IIC_Init
// 功用 : 初始化i2c
// 参数 : void
// 作者 : wit_yuan
// 时刻 : 2014-11-07
////////////////////////////////////////////////////////////////////////////
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_2); //PA2,PA3 输出高
GPIO_SetBits(GPIOA,GPIO_Pin_3); //PA2,PA3 输出高
}
//////////////////////////////////////////////////////////////////////////
// 函数名 : IIC_Start
// 功用 : i2c起始信号
// 参数 : void
// 作者 : wit_yuan
// 时刻 : 2014-11-07
////////////////////////////////////////////////////////////////////////////
void IIC_Start(void)
{
SDA_OUT(); //因为上一个SCL状况是0或者是1,要让SDA安稳输出,都能够设置为1。
IIC_SDA=1;
Delay_us(2);

IIC_SCL=1; //让SCL发生改变,为0不变,为1则改变,标明数据能够变动了。
Delay_us(2);

IIC_SDA=0; //SDA线数据改变,然后能够确保宣布的是start信号。
Delay_us(2);

IIC_SCL=0; //将I2C总线钳住,下一个时刻SDA能够输出凹凸电平。
Delay_us(4);
}
//////////////////////////////////////////////////////////////////////////
// 函数名 : IIC_Stop
// 功用 : i2c完毕信号
// 参数 : void
// 作者 : wit_yuan
// 时刻 : 2014-11-07
////////////////////////////////////////////////////////////////////////////
void IIC_Stop(void)
{
SDA_OUT();
IIC_SDA=0; //上一个状况的SCL=0,这个状况设置SDA=0,意图是让状况能回转
Delay_us(2);

IIC_SCL=1; //该时刻设置SCL=1,然后就能够让数据安稳在改状况下。
Delay_us(2);

IIC_SDA=1;
Delay_us(4);
}
//////////////////////////////////////////////////////////////////////////
// 函数名 : IIC_Wait_Ack
// 功用 : 等候i2c的应对信号
// 参数 : void
// 作者 : wit_yuan
// 时刻 : 2014-11-07
////////////////////////////////////////////////////////////////////////////
//等候应对信号到来
//回来值:1,接纳应对失利
// 0,接纳应对成功
u8 IIC_Wait_Ack(void)
{
u16 ucErrTime=0;

IIC_SCL=0;
Delay_us(1);

SDA_IN(); //SDA设置为输入

while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1; //超时,标明数据传输有问题
}
}
IIC_SCL=1;
Delay_us(1);

IIC_SCL=0;//时钟输出0
Delay_us(2);

return 0;
}
//////////////////////////////////////////////////////////////////////////
// 函数名 : IIC_Ack
// 功用 : 发生i2c的ack应对信号
// 参数 : void
// 作者 : wit_yuan
// 时刻 : 2014-11-07
////////////////////////////////////////////////////////////////////////////
//发生ACK应对
void IIC_Ack(void)
{
IIC_SCL=0;
Delay_us(2);

SDA_OUT();
IIC_SDA=0;
Delay_us(1);

IIC_SCL=1;
Delay_us(1);
IIC_SCL=0;
Delay_us(4);

}
//不发生ACK应对
void IIC_NAck(void)
{
SDA_OUT();
IIC_SCL=0;
Delay_us(2);

IIC_SDA=1;
Delay_us(2);

IIC_SCL=1;
Delay_us(2);
IIC_SCL=0;
Delay_us(2);
}
//IIC发送一个字节
//回来从机有无应对
//1,有应对
//0,无应对
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开端数据传输
Delay_us(2);
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
Delay_us(2);
IIC_SCL=1;
Delay_us(2);
IIC_SCL=0;
Delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
unsigned char IIC_Read_Byte( void )
{
unsigned char i,u_receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
Delay_us(4);
IIC_SCL=1;
Delay_us(1);
u_receive<<=1;
if(READ_SDA)
u_receive++;
}

return u_receive;
}

unsigned char eeprom_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,unsigned char u_data)
{
unsigned char u_wait_err = 0;

IIC_Start();
IIC_Send_Byte(c_slave_address7bit << 1);
u_wait_err |= IIC_Wait_Ack();

IIC_Send_Byte(c_reg_address);
u_wait_err |= IIC_Wait_Ack();

IIC_Send_Byte(u_data);
u_wait_err |= IIC_Wait_Ack();

IIC_Stop();

if( u_wait_err == 0)
return 0;
return 1;
}

unsigned char eeprom_read(unsigned char c_slave_address7bit,unsigned char c_reg_address)
{
unsigned char u_temp;
unsigned char u_wait_err = 0;

IIC_Start();
IIC_Send_Byte(c_slave_address7bit << 1);
u_wait_err |= IIC_Wait_Ack();

IIC_Send_Byte(c_reg_address);
u_wait_err |= IIC_Wait_Ack();

IIC_Start();
IIC_Send_Byte((c_slave_address7bit << 1)+1);
u_wait_err |= IIC_Wait_Ack();

u_temp = IIC_Read_Byte( );
IIC_NAck();//不需要呼应

IIC_Stop();

return u_temp;
}

unsigned char eeprom_continue_read(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_read_arr[],unsigned int len)
{
unsigned char u_wait_err = 0;
int i = 0;

IIC_Start();
IIC_Send_Byte(c_slave_address7bit << 1);
u_wait_err |= IIC_Wait_Ack();

IIC_Send_Byte(c_reg_address);
u_wait_err |= IIC_Wait_Ack();

IIC_Start();
IIC_Send_Byte((c_slave_address7bit << 1)+1);
u_wait_err |= IIC_Wait_Ack();

for(i = 0 ; i < len - 1 ; i ++)
{
c_continue_read_arr[i] = IIC_Read_Byte( );
IIC_Ack();
}

c_continue_read_arr[len-1] = IIC_Read_Byte( );
u_wait_err |= IIC_Wait_Ack();

IIC_Stop();

if(u_wait_err == 0)
return 0;
return 1;
}

//假如数据写入有问题,则回来1,表明过错,回来0,表明过错
unsigned char eeprom_continue_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_write_arr[],unsigned int len)
{
unsigned int i;
unsigned int i_err = 0;

IIC_Start();
IIC_Send_Byte(c_slave_address7bit << 1);
i_err |= IIC_Wait_Ack();

IIC_Send_Byte(c_reg_address);
i_err |= IIC_Wait_Ack();

for( i = 0 ; i < len ; i ++ )
{
IIC_Send_Byte(c_continue_write_arr[i]);

i_err |= IIC_Wait_Ack();
}
IIC_Stop();

if(i_err == 0)
return 0;

return 1;
}

//该函数改写本来的函数 2016-09-16 by wit_yuan

unsigned char read_eeprom_status(unsigned char c_slave_address7bit)

{

unsigned int i = 0;

int i_ret = 0;

do

{

IIC_Start();

IIC_Send_Byte(c_slave_address7bit << 1);

i_ret = IIC_Wait_Ack();

i++;

if(i >= 10000)

{

IIC_Stop();

return 1;//表明无呼应

}

}while(i_ret);

IIC_Stop();

return 0;//表明操作序列完毕

}

主测验程序main.c:

/******************** (C) COPYRIGHT 2015 **************************
* 文件名 :main.c
* 描绘 :

**********************************************************************************/
#include “stm32f10x.h”
#include “usart1.h”
#include “i2c.h”

static void delay(int time)
{
int i = 0 ,j = 0;
for(i = 0 ; i < 5 ; i ++)
for(j = 0 ; j < time ; j ++)
;
}

unsigned char g_c_continue_read_array[256];

unsigned char g_c_continue_write[256];

/*
* 函数名:main
* 描绘 :主函数
* 输入 :无
* 输出 :无
*/
int main(void)
{
unsigned int i;
unsigned char value;
/* USART1 config 9600 8-N-1 */
USART1_Config();

printf(“——–app run———–\n”);

IIC_Init();

//memset(g_c_continue_write,0x32,256);

printf(“write:\n”);
for(i = 0 ; i < 16 ; i ++)
{
//printf(“%0x “,g_c_continue_write[i]);
g_c_continue_write[i] = i;
}
printf(“\n”);

eeprom_continue_write(EEPROM_SLAVE_ADDRESS,0,g_c_continue_write,16);

value = read_eeprom_status(EEPROM_SLAVE_ADDRESS);
printf(“\n status : %d\n”,value);

//printf(“status = %d\n”,read_eeprom_status());

eeprom_continue_read(EEPROM_SLAVE_ADDRESS,0,g_c_continue_read_array,16);

printf(“read:\n”);
for(i = 0 ; i < 16 ; i ++)
{
printf(“%0x “,g_c_continue_read_array[i]);
}
printf(“\n”);

value = eeprom_read(EEPROM_SLAVE_ADDRESS,0x15);
printf(“value = 0x%0x\n”,value);

printf(“write:\n”);
eeprom_write(EEPROM_SLAVE_ADDRESS,0x01,0x25);
value = read_eeprom_status(EEPROM_SLAVE_ADDRESS);
value = eeprom_read(EEPROM_SLAVE_ADDRESS,0x01);
printf(“value = 0x%0x\n”,value);

for(;;)
{

}
}
/******************* (C) COPYRIGHT 2016 *****END OF FILE************/

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/252321.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部