1、/实验 24C02 连接在 PF 口/WP、A0、A1、A2 都接地#include “stm32f10x_flash.h“#include “stm32f10x_gpio.h“#include “stm32f10x_rcc.h“#define AT24C02 0xa0 /AT24C02 地址/* 变量定义 -*/GPIO_InitTypeDef GPIO_InitStructure; /GPIOErrorStatus HSEStartUpStatus;unsigned char Count1 , Count2;unsigned int USEC;static vu32 TimingDelay
2、;unsigned char Readzfc;unsigned char pDat8 = 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55;unsigned char R_Dat8;/*声明函数 -*/void RCC_Configuration(void);void SysTick_Configuration(void);void Delay_us_24C02(u32 nTime);/*24C02 硬件接口*/ #define SData GPIO_Pin_6 /I2C 时钟 #define SCLK GPIO_Pin_7 /I2C 数据 /*宏定义*/#def
3、ine SCL(x) x ? GPIO_SetBits(GPIOF , SCLK) : GPIO_ResetBits(GPIOF , SCLK)#define SDA(x) x ? GPIO_SetBits(GPIOF , SData) : GPIO_ResetBits(GPIOF , SData)/*变量*/u8 ack;/*起动总线函数 函数原型: void Start_I2c(); 功能: 启动 I2C 总线,即发送 I2C 起始条件. */void Start_I2c()SDA(1); /SDA=1; 发送起始条件的数据信号Delay_us_24C02(1);SCL(1); /SCL=
4、1;Delay_us_24C02(5); /起始条件建立时间大于 4.7us,延时SDA(0); /SDA=0; /*发送起始信号*/Delay_us_24C02(5); / 起始条件锁定时间大于 4sSCL(0); /SCL=0; /*钳住 I2C 总线,准备发送或接收数据 */Delay_us_24C02(2);/*结束总线函数 函数原型: void Stop_I2c(); 功能: 结束 I2C 总线,即发送 I2C 结束条件. */void Stop_I2c()SDA(0); /SDA=0; /发送结束条件的数据信号Delay_us_24C02(1); /发送结束条件的时钟信号SCL(1
5、) ; /SCL=1; 结束条件建立时间大于 4sDelay_us_24C02(5);SDA(0); /SDA=1; 发送 I2C 总线结束信号Delay_us_24C02(4);/*字节数据发送函数 函数原型: void SendByte(UCHAR c);功能: 将数据 c 发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使 ack=0) 发送数据正常,ack=1; ack=0 表示被控器无应答或损坏。*/void SendByte(unsigned char c)unsigned char BitCnt;for(BitCnt=0;BitCnt8
6、;BitCnt+) /要传送的数据长度为 8 位if(cBitCnt) /SDA=1; 判断发送位else SDA(0); / SDA=0 Delay_us_24C02(1);SCL(1); /SCL=1 置时钟线为高,通知被控器开始接收数据位Delay_us_24C02(5); /保证时钟高电平周期大于 4sSCL(0); /SCL = 0Delay_us_24C02(2);SDA(1); /SDA=1 位发送完后释放数据线,准备接收应答位Delay_us_24C02(2); SCL(1); /SCL=1Delay_us_24C02(3);if(GPIO_ReadInputDataBit(G
7、PIOF ,SData)=1)ack=0; else ack=1; /判断是否接收到应答信号SCL(0); /SCL=0;Delay_us_24C02(3);/*字节数据接收函数 函数原型: UCHAR RcvByte();功能: 用来接收从器件传来的数据 ,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。 */ unsigned char RcvByte()unsigned char retc;unsigned char BitCnt;retc=0; SDA(1); /SDA=1 置数据线为输入方式for(BitCnt=0;BitCnt8;BitCnt+)Delay_us_24C
8、02(1); SCL(0); /SCL=0 置时钟线为低,准备接收数据位Delay_us_24C02(5); /时钟低电平周期大于 4.7sSCL(1); /SCL=1 置时钟线为高使数据线上数据有效Delay_us_24C02(2);retc=retc1;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);/*应答子函数函数原型: void A
9、ck_I2c(bit a);功能: 主控器进行应答信号 (可以是应答或非应答信号,由位参数 a 决定)*/void Ack_I2c(u8 a)if(a=0)SDA(0); /SDA=0;在此发出应答或非应答信号 else SDA(1); /SDA=1;Delay_us_24C02(3); SCL(1); /SCL=1; Delay_us_24C02(4); /时钟低电平周期大于 4sSCL(0) ; /SCL=0; 清时钟线,钳住 I2C 总线以便继续接收Delay_us_24C02(2); /AT2402 的功能函数/*向有子地址器件发送多字节数据函数 函数原型: bit ISendStr(
10、UCHAR sla,UCHAR suba,ucahr *s,UCHAR no); 功能: 从启动总线到发送地址,子地址 ,数据,结束总线的全过程,从器件地址 sla,子地址 suba,发送内容是 s 指向的内容,发送 no 个字节。如果返回 1 表示操作成功,否则操作有误。注意: 使用前必须已结束总线。*/u8 ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)unsigned char i;Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/i
11、f(ack=0)return(0);SendByte(suba); /*发送器件子地址*/if(ack=0)return(0);for(i=0;ino;i+) SendByte(*s); /*发送数据*/if(ack=0)return(0);s+; Stop_I2c(); /*结束总线*/ return(1);/*向有子地址器件读取多字节数据函数 函数原型: bit RecndStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no); 功能: 从启动总线到发送地址,子地址 ,读数据,结束总线的全过程,从器件地址 sla,子地址 suba,读出的内容放入 s 指向的
12、存储区,读 no 个字节。如果返回 1 表示操作成功,否则操作有误。注意: 使用前必须已结束总线。*/u8 IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)unsigned char i;Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/if(ack=0)return(0);SendByte(suba); /*发送器件子地址*/if(ack=0)return(0);Start_I2c(); /*重新启动总线*/SendByte(sla+1);i
13、f(ack=0)return(0);for(i=0;ino-1;i+) *s=RcvByte(); /*发送数据*/Ack_I2c(0); /*发送就答位*/ s+; *s=RcvByte();Ack_I2c(1); /*发送非应位*/Stop_I2c(); /*结束总线*/ return(1);void Delay(vu32 nCount)for(; nCount != 0; nCount-);void Delay_us_24C02(u32 nTime)unsigned int USEC = 0;while(USEC != 10000)USEC+;int main() #ifdef DEBU
14、Gdebug(); /在线调试使用#endifRCC_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); G
15、PIO_InitStructure.GPIO_Pin = GPIO_Pin_All; /所有 GPIO 为同一类型端口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /输出的最大频率为 50HZGPIO_Init(GPIOB, /初始化 GPIOB 端口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; /所有 GPIO 为同一类型端口GPIO_InitStructure.GPIO_Mode = GP
16、IO_Mode_Out_PP; /推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /输出的最大频率为 50HZGPIO_Init(GPIOF, /初始化 GPIOB 端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; /开漏输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /输出的最大频率为 50HZGPIO_Init(GPIOF, /初始化 G
17、PIOA 端口GPIO_Write(GPIOB,0xffff); /将 GPIOB 16 个端口全部置为高电while(1)/=IIC 读取if(Readzfc = 1) IRcvStr(AT24C02,0, Readzfc = 0;if(R_Dat2 = 0x55)GPIO_Write(GPIOB,0xffff);Delay(0x3fffff);GPIO_Write(GPIOB,0x0000);Delay(0x3fffff);Readzfc = 0;if(Readzfc = 0) ISendStr(AT24C02,0, Readzfc = 1;/* 配置 RCC*/void RCC_Conf
18、iguration(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);/
19、配置 AHB(HCLK)时钟=SYSCLKRCC_HCLKConfig(RCC_SYSCLK_Div1); /配置 APB2(PCLK2)钟=AHB 时钟RCC_PCLK2Config(RCC_HCLK_Div1); /配置 APB1(PCLK1)钟=AHB 1/2 时钟RCC_PCLK1Config(RCC_HCLK_Div2);/配置 PLL 时钟 = 外部高速晶体时钟*9 PLLCLK = 8MHz * 9 = 72 MHz RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/使能 PLL 时钟RCC_PLLCmd(ENABLE);/
20、等待 PLL 时钟就绪while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) = RESET)/配置系统时钟 = PLL 时钟RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/检查 PLL 时钟是否作为系统时钟while(RCC_GetSYSCLKSource() != 0x08)#ifdef DEBUG/* Function Name : assert_failed* Description : Reports the name of the source file and the source line number* wher
21、e the assert_param error has occurred.* Input : - file: pointer to the source file name* - line: assert_param error line source number* Output : None* Return : None*/void assert_failed(u8* file, u32 line) /* User can add his own implementation to report the file name and line number,ex: printf(“Wrong parameters value: file %s on line %drn“, file, line) */* Infinite loop */while (1)#endif