STM32F103读写24C02 C程序有硬件电路图和程序.docx
《STM32F103读写24C02 C程序有硬件电路图和程序.docx》由会员分享,可在线阅读,更多相关《STM32F103读写24C02 C程序有硬件电路图和程序.docx(15页珍藏版)》请在冰豆网上搜索。
STM32F103读写24C02C程序有硬件电路图和程序
//实验24C02连接在PF口
//WP、A0、A1、A2都接地,如下图所示。
//单片机:
STM32F103
#include"stm32f10x_flash.h"
#include"stm32f10x_gpio.h"
#include"stm32f10x_rcc.h"
#defineAT24C020xa0//AT24C02地址
/********************************变量定义---------------------------------------------------------*/
GPIO_InitTypeDefGPIO_InitStructure;//GPIO
ErrorStatusHSEStartUpStatus;
unsignedcharCount1,Count2;
unsignedintUSEC;
staticvu32TimingDelay;
unsignedcharReadzfc;
unsignedcharpDat[8]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};//实验数据
unsignedcharR_Dat[8];
/*********************************声明函数-----------------------------------------------*/
voidRCC_Configuration(void);
voidSysTick_Configuration(void);
voidDelay_us_24C02(u32nTime);
/************************************24C02硬件接口******************************/
#defineSDataGPIO_Pin_6//I2C时钟
#defineSCLKGPIO_Pin_7//I2C数据
/********************************宏定义*******************************************/
#defineSCL(x)x?
GPIO_SetBits(GPIOB,SCLK):
GPIO_ResetBits(GPIOB,SCLK)
#defineSDA(x)x?
GPIO_SetBits(GPIOB,SData):
GPIO_ResetBits(GPIOB,SData)
/********************************变量*******************************************/
u8ack;
/*******************************************************************
起动总线函数
函数原型:
voidStart_I2c();
功能:
启动I2C总线,即发送I2C起始条件.
********************************************************************/
voidStart_I2c()
{
SDA
(1);//SDA=1;发送起始条件的数据信号
Delay_us_24C02
(1);
SCL
(1);//SCL=1;
Delay_us_24C02(5);//起始条件建立时间大于4.7us,延时
SDA(0);//SDA=0;/*发送起始信号*/
Delay_us_24C02(5);//起始条件锁定时间大于4μs
SCL(0);//SCL=0;/*钳住I2C总线,准备发送或接收数据*/
Delay_us_24C02
(2);
}
/*******************************************************************
结束总线函数
函数原型:
voidStop_I2c();
功能:
结束I2C总线,即发送I2C结束条件.
********************************************************************/
voidStop_I2c()
{
SDA(0);//SDA=0;//发送结束条件的数据信号
Delay_us_24C02
(1);//发送结束条件的时钟信号
SCL
(1);//SCL=1;结束条件建立时间大于4μs
Delay_us_24C02(5);
SDA(0);//SDA=1;发送I2C总线结束信号
Delay_us_24C02(4);
}
/*******************************************************************
字节数据发送函数
函数原型:
voidSendByte(UCHARc);
功能:
将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1;ack=0表示被控器无应答或损坏。
********************************************************************/
voidSendByte(unsignedcharc)
{
unsignedcharBitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)//要传送的数据长度为8位
{
if((c<(1);//SDA=1;判断发送位
elseSDA(0);//SDA=0
Delay_us_24C02
(1);
SCL
(1);//SCL=1置时钟线为高,通知被控器开始接收数据位
Delay_us_24C02(5);//保证时钟高电平周期大于4μs
SCL(0);//SCL=0
}
Delay_us_24C02
(2);
SDA
(1);//SDA=1位发送完后释放数据线,准备接收应答位
Delay_us_24C02
(2);
SCL
(1);//SCL=1
Delay_us_24C02(3);
if(GPIO_ReadInputDataBit(GPIOF,SData)==1)ack=0;
elseack=1;//判断是否接收到应答信号
SCL(0);//SCL=0;
Delay_us_24C02(3);
}
/*******************************************************************
字节数据接收函数
函数原型:
UCHARRcvByte();
功能:
用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
unsignedcharRcvByte()
{
unsignedcharretc;
unsignedcharBitCnt;
retc=0;
SDA
(1);//SDA=1置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
Delay_us_24C02
(1);
SCL(0);//SCL=0置时钟线为低,准备接收数据位
Delay_us_24C02(5);//时钟低电平周期大于4.7μs
SCL
(1);//SCL=1置时钟线为高使数据线上数据有效
Delay_us_24C02
(2);
retc=retc<<1;
if(GPIO_ReadInputDataBit(GPIOF,SData)==1)retc=retc+1;//SDA==1读数据位,接收的数据位放入retc中
Delay_us_24C02
(2);
}
SCL(0);//SCL=0;
Delay_us_24C02
(2);
return(retc);
}
/********************************************************************
应答子函数
函数原型:
voidAck_I2c(bita);
功能:
主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
voidAck_I2c(u8a)
{
if(a==0)
SDA(0);//SDA=0;在此发出应答或非应答信号
else
SDA
(1);//SDA=1;
Delay_us_24C02(3);
SCL
(1);//SCL=1;
Delay_us_24C02(4);//时钟低电平周期大于4μs
SCL(0);//SCL=0;清时钟线,钳住I2C总线以便继续接收
Delay_us_24C02
(2);
}
//AT2402的功能函数
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型:
bitISendStr(UCHARsla,UCHARsuba,ucahr*s,UCHARno);
功能:
从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意:
使用前必须已结束总线。
********************************************************************/
u8ISendStr(unsignedcharsla,unsignedcharsuba,unsignedchar*s,unsignedcharno)
{
unsignedchari;
Start_I2c();/*启动总线*/
SendByte(sla);/*发送器件地址*/
if(ack==0)return(0);
SendByte(suba);/*发送器件子地址*/
if(ack==0)return(0);
for(i=0;i{
SendByte(*s);/*发送数据*/
if(ack==0)return(0);
s++;
}
Stop_I2c();/*结束总线*/
return
(1);
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型:
bitRecndStr(UCHARsla,UCHARsuba,ucahr*s,UCHARno);
功能:
从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
如果返回1表示操作成功,否则操作有误。
注意:
使用前必须已结束总线。
********************************************************************/
u8IRcvStr(unsignedcharsla,unsignedcharsuba,unsignedchar*s,unsignedcharno)
{
unsignedchari;
Start_I2c();/*启动总线*/
SendByte(sla);/*发送器件地址*/
if(ack==0)return(0);
SendByte(suba);/*发送器件子地址*/
if(ack==0)return(0);
Start_I2c();/*重新启动总线*/
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i{
*s=RcvByte();/*发送数据*/
Ack_I2c(0);/*发送就答位*/
s++;
}
*s=RcvByte();
Ack_I2c
(1);/*发送非应位*/
Stop_I2c();/*结束总线*/
return
(1);
}
voidDelay(vu32nCount)
{
for(;nCount!
=0;nCount--);
}
voidDelay_us_24C02(u32nTime)
{
unsignedintUSEC=0;
while(USEC!
=10000)
{
USEC++;
}
}
intmain()
{
#ifdefDEBUG
debug();//在线调试使用
#endif
RCC_Configuration();//系统时钟配置函数
//NVIC_Configuration();//NVIC配置函数
//SysTick_Configuration();//Systick配置函数
//启动GPIO模块时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
//把调试设置普通IO口
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;//所有GPIO为同一类型端口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出的最大频率为50HZ
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB端口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;//所有GPIO为同一类型端口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出的最大频率为50HZ
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIOB端口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;//开漏输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出的最大频率为50HZ
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIOA端口
GPIO_Write(GPIOB,0xffff);//将GPIOB16个端口全部置为高电
while
(1)
{
//========================IIC读取
if(Readzfc==1)
{
IRcvStr(AT24C02,0,&R_Dat[0],8);
Readzfc=0;
}
if(R_Dat[2]==0x55)
{
GPIO_Write(GPIOB,0xffff);
Delay(0x3fffff);
GPIO_Write(GPIOB,0x0000);
Delay(0x3fffff);
}
Readzfc=0;
if(Readzfc==0)
{
ISendStr(AT24C02,0,&pDat[0],8);
Readzfc=1;
}
}
}
/*******************************************************************************
*配置RCC
*******************************************************************************/
voidRCC_Configuration(void)
{
//复位RCC外部设备寄存器到默认值
RCC_DeInit();
//打开外部高速晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟准备好
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus==SUCCESS)//外部高速时钟已经准别好
{
//开启FLASH的预取功能
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//FLASH延迟2个周期
FLASH_SetLatency(FLASH_Latency_2);
//配置AHB(HCLK)时钟=SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//配置APB2(PCLK2)钟=AHB时钟
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置APB1(PCLK1)钟=AHB1/2时钟
RCC_PCLK1Config(RCC_HCLK_Div2);
//配置PLL时钟==外部高速晶体时钟*9PLLCLK=8MHz*9=72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
//使能PLL时钟
RCC_PLLCmd(ENABLE);
//等待PLL时钟就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
{
}
//配置系统时钟=PLL时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//检查PLL时钟是否作为系统时钟
while(RCC_GetSYSCLKSource()!
=0x08)
{
}
}
}
#ifdefDEBUG
/*******************************************************************************
*FunctionName:
assert_failed
*Description:
Reportsthenameofthesourcefileandthesourcelinenumber
*wheretheassert_paramerrorhasoccurred.
*Input:
-file:
pointertothesourcefilename
*-line:
assert_paramerrorlinesourcenumber
*Output:
None
*Return:
None
*******************************************************************************/
voidassert_failed(u8*file,u32line)
{
/*Usercanaddhisownimplementationtoreportthefilenameandlinenumber,
ex:
printf("Wrongparametersvalue:
file%sonline%d\r\n",file,line)*/
/*Infiniteloop*/
while
(1)
{
}
}
#endif