STM32F103读写24C02程序使用过肯定能用Word格式文档下载.docx
《STM32F103读写24C02程序使用过肯定能用Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《STM32F103读写24C02程序使用过肯定能用Word格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。
#defineSDA(x)x?
GPIO_SetBits(GPIOF,SData):
GPIO_ResetBits(GPIOF,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;
/*发送起始信号*/
//起始条件锁定时间大于4μs
SCL(0);
//SCL=0;
/*钳住I2C总线,准备发送或接收数据*/
Delay_us_24C02
(2);
}
结束总线函数
voidStop_I2c();
结束I2C总线,即发送I2C结束条件.
voidStop_I2c()
//发送结束条件的数据信号
//发送结束条件的时钟信号
SCL
(1);
结束条件建立时间大于4μs
发送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<
<
BitCnt)&
0x80)SDA
(1);
判断发送位
elseSDA(0);
//SDA=0
//SCL=1置时钟线为高,通知被控器开始接收数据位
//保证时钟高电平周期大于4μs
//SCL=0
}
//SDA=1位发送完后释放数据线,准备接收应答位
SCL
(1);
//SCL=1
Delay_us_24C02(3);
if(GPIO_ReadInputDataBit(GPIOF,SData)==1)ack=0;
elseack=1;
//判断是否接收到应答信号
SCL(0);
字节数据接收函数
UCHARRcvByte();
用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
unsignedcharRcvByte()
unsignedcharretc;
retc=0;
//SDA=1置数据线为输入方式
BitCnt++)
//SCL=0置时钟线为低,准备接收数据位
Delay_us_24C02(5);
//时钟低电平周期大于4.7μs
//SCL=1置时钟线为高使数据线上数据有效
retc=retc<
1;
if(GPIO_ReadInputDataBit(GPIOF,SData)==1)retc=retc+1;
//SDA==1读数据位,接收的数据位放入retc中
//SCL=0;
return(retc);
/********************************************************************
应答子函数
voidAck_I2c(bita);
主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
voidAck_I2c(u8a)
if(a==0)
在此发出应答或非应答信号
else
//时钟低电平周期大于4μs
SCL(0);
清时钟线,钳住I2C总线以便继续接收
//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);
/*发送器件子地址*/
for(i=0;
i<
no;
i++)
{
SendByte(*s);
/*发送数据*/
s++;
}
Stop_I2c();
/*结束总线*/
return
(1);
向有子地址器件读取多字节数据函数
bitRecndStr(UCHARsla,UCHARsuba,ucahr*s,UCHARno);
从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
u8IRcvStr(unsignedcharsla,unsignedcharsuba,unsignedchar*s,unsignedcharno)
/*重新启动总线*/
SendByte(sla+1);
no-1;
*s=RcvByte();
Ack_I2c(0);
/*发送就答位*/
Ack_I2c
(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_Init(GPIOF,&
//初始化GPIOB端口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
//开漏输出
//初始化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);
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:
voidassert_failed(u8*file,u32line)
/*Usercanaddhisownimplementationtoreportthefilenameandlinenumber,
ex:
printf("
Wrongparametersvalue:
file%sonline%d\r\n"
file,line)*/
/*Infiniteloop*/
while
(1)
#endif