硬汉嵌入式论坛

 找回密码
 立即注册
查看: 717|回复: 9
收起左侧

关于IIC写EEROM写数据时必须打断点才能写成功

[复制链接]

6

主题

32

回帖

50

积分

初级会员

积分
50
发表于 2022-5-27 12:31:27 | 显示全部楼层 |阅读模式


在写数据的时候打个断点,然后第一个TXE出现则之后在运行没有问题.若不打断点TXE没有置为,SR1寄存器没有任何反应,直接卡死.

[C] 纯文本查看 复制代码
//初始化
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;

	//主模式
	I2C1->CR2 |= I2C_CR2_FREQ_5 | I2C_CR2_FREQ_4 | I2C_CR2_FREQ_1;	   //32M
	I2C1->CCR &= ~I2C_CCR_FS;           //标准模式    
	I2C1->CCR |=  0xA1 <<  I2C_CCR_CCR_Pos;
	I2C1->TRISE |= 0x21;                 /*  1/ (1/32) = 32+1*/
	I2C1->CR2 |= I2C_CR2_ITBUFEN | I2C_CR2_ITEVTEN |I2C_CR2_ITERREN;//中断使能
	I2C1->CR1 |= I2C_CR1_ACK;
	I2C1->CR1 |= I2C_CR1_PE;//外设使能
		

void I2C_Write1(uint8_t Addr, uint8_t* pDat, uint8_t Cnt)
{
	uint8_t TxCnt = 0;
	
       
   while((I2C1->SR2 & I2C_SR2_BUSY) == 1);   //总线不忙碌
    
do{     
	I2C1->CR1 |= I2C_CR1_START;
	while(( I2C1->SR1 & I2C_SR1_SB) == 0) ;
	I2C1->DR = 0xA0;   //写
    while(( I2C1->SR1 & I2C_SR1_TXE) == 0) ;
	I2C1->DR = Addr;
    }while(( I2C1->SR1 & I2C_SR1_ADDR) == 0);

	while(TxCnt < Cnt)
	{
   //      mSDelay(7);
		I2C1->DR = pDat[TxCnt];
  //      while((I2C1->SR1 & I2C_SR1_AF )== 1)  I2C1->DR = pDat[TxCnt];
     
		while(( I2C1->SR1 & I2C_SR1_TXE) == 0) ;
		TxCnt += 1;
	}	
	
	I2C1->CR1 |= I2C_CR1_STOP;

}






Snipaste_2022-05-27_12-27-36.png
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-5-27 18:52:51 | 显示全部楼层
为方便大佬帮我测试,我把系统时钟 外设初始化函数都沾出来,非常感谢
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-5-27 18:55:03 | 显示全部楼层
1.系统时钟初始化,配置的180MHZ
[C] 纯文本查看 复制代码
void SysClk_Init(void)
{
	//bus enable
	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
	RCC->APB1ENR |= RCC_APB1ENR_PWREN;
	//调压
	PWR->CR = (PWR->CR & (~PWR_CR_VOS)) |  PWR_CR_VOS;
	//HSE
	RCC->CR |= RCC_CR_HSEON;
	while((RCC->CR & RCC_CR_HSERDY) == 0);
	//PLL

	RCC->PLLCFGR = 25UL << RCC_PLLCFGR_PLLM_Pos | 360UL << RCC_PLLCFGR_PLLN_Pos & (~RCC_PLLCFGR_PLLP)| RCC_PLLCFGR_PLLSRC_HSE;
	
//	RCC->PLLCFGR = 25UL << RCC_PLLCFGR_PLLM_Pos | 320UL << RCC_PLLCFGR_PLLN_Pos & (~RCC_PLLCFGR_PLLP)| RCC_PLLCFGR_PLLSRC_HSE;
	RCC->CR |= RCC_CR_PLLON;
	while((RCC->CR & RCC_CR_PLLRDY) == 0);

	//flash
	FLASH->ACR =(FLASH->ACR & (~FLASH_ACR_LATENCY)) | FLASH_ACR_LATENCY_5WS;
	//while(FLASH->ACR )
	RCC->CFGR = RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_SW_PLL;
	while((RCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
	
	SystemCoreClockUpdate();
	
	SysTick_Config(SystemCoreClock / 1000);//括号里算的是自动重装载值,这个值在除以系统CLOCK
	NVIC_SetPriority(SysTick_IRQn,10);    //设置中断优先级
}
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-5-27 18:58:50 | 显示全部楼层
2.I2C初始化配置,刚开始是按照32M标准模式,后来改成45M,FS是快速模式  占空比2
[C] 纯文本查看 复制代码
void I2C_Config(void)
{
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
	
	GPIOB->MODER = (GPIOB->MODER & (~GPIO_MODER_MODE6)) | GPIO_MODER_MODER6_1;//复用模式
	GPIOB->MODER = (GPIOB->MODER & (~GPIO_MODER_MODE7)) | GPIO_MODER_MODER7_1;
	GPIOB->OTYPER |= GPIO_OTYPER_OT6 | GPIO_OTYPER_OT7;//输出开漏
	GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7);//11高速
//	GPIOB->PUPDR = (GPIOB->PUPDR & (~GPIO_PUPDR_PUPD6)) | GPIO_PUPDR_PUPD6_0;//上拉
//	GPIOB->PUPDR = (GPIOB->PUPDR & (~GPIO_PUPDR_PUPD7)) | GPIO_PUPDR_PUPD7_0;//上拉
	GPIOB->AFR[0] =(GPIOB->AFR[0] & (~0xFFFFFFFF)) | 0x44000000;//复用连接


	RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;

	//主模式
	I2C1->CR2 |= 0x2D;	   //45M
	I2C1->CCR |= I2C_CCR_FS;           //快速模式    
    I2C1->CCR &= ~I2C_CCR_DUTY_Pos;  //快速模式2
	I2C1->CCR |=  0x25 <<  I2C_CCR_CCR_Pos;
	I2C1->TRISE |= 0x0E << I2C_TRISE_TRISE_Pos;     //
//	I2C1->CR2 |= I2C_CR2_ITBUFEN | I2C_CR2_ITEVTEN |I2C_CR2_ITERREN;//中断使能
	I2C1->CR1 |= I2C_CR1_ACK;
	I2C1->CR1 |= I2C_CR1_PE;//外设使能
		
}
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-5-27 18:59:15 | 显示全部楼层
3.读函数
[C] 纯文本查看 复制代码
void I2C_Read(uint8_t Addr, uint8_t* pDat, uint8_t Cnt)
{
	uint8_t RxCnt = 0;
	
    
    
   while((I2C1->SR2 & I2C_SR2_BUSY) == 1);   //总线不忙碌
    
do{     
	I2C1->CR1 |= I2C_CR1_START;
	while(( I2C1->SR1 & I2C_SR1_SB) == 0) ;
	I2C1->DR = 0xA0;   //写
    while(( I2C1->SR1 & I2C_SR1_TXE) == 0) ;
	I2C1->DR = Addr;
    }while(( I2C1->SR1 & I2C_SR1_ADDR) == 0);
	I2C1->CR1 |= I2C_CR1_ACK | I2C_CR1_START;
	while(( I2C1->SR1 & I2C_SR1_SB) == 0) ;
	I2C1->DR = 0xA1;
	while(RxCnt < Cnt - 1)
	{

		while(( I2C1->SR1 & I2C_SR1_RXNE) == 0) ;
		pDat[RxCnt] = I2C1->DR;
		
		RxCnt += 1;
        if(RxCnt == Cnt - 1)break; 
	}	
    I2C1->CR1 &= ~I2C_CR1_ACK;
    while(( I2C1->SR1 & I2C_SR1_RXNE) == 0) ;
    pDat[RxCnt] = I2C1->DR;
	I2C1->CR1 |= I2C_CR1_STOP;
	
}
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-5-27 18:59:36 | 显示全部楼层
4.写函数
[C] 纯文本查看 复制代码
void I2C_Write1(uint8_t Addr, uint8_t* pDat, uint8_t Cnt)
{
	uint8_t TxCnt = 0;
	
       
   while((I2C1->SR2 & I2C_SR2_BUSY) == 1);   //总线不忙碌
    
    
	I2C1->CR1 |= I2C_CR1_START;
	while(( I2C1->SR1 & I2C_SR1_SB) == 0) ;
	I2C1->DR = 0xA0;   //写
    while(( I2C1->SR1 & I2C_SR1_TXE) == 0) ;
	I2C1->DR = Addr;
    while(( I2C1->SR1 & I2C_SR1_TXE) == 0);

	while(TxCnt < Cnt)
	{
		I2C1->DR = pDat[TxCnt];
  //      while((I2C1->SR1 & I2C_SR1_AF )== 1)  I2C1->DR = pDat[TxCnt];
     
		while(( I2C1->SR1 & I2C_SR1_TXE) == 0) ;
		TxCnt += 1;
	}	
	
	I2C1->CR1 |= I2C_CR1_STOP;

}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106621
QQ
发表于 2022-5-28 10:09:30 | 显示全部楼层
这个发送标志 I2C_SR1_TXE是发送空,是不是还有个 I2C_SR1_TC,如果有的话,发送等待改成用这个标志。
回复

使用道具 举报

6

主题

32

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2022-5-28 11:56:32 | 显示全部楼层
eric2013 发表于 2022-5-28 10:09
这个发送标志 I2C_SR1_TXE是发送空,是不是还有个 I2C_SR1_TC,如果有的话,发送等待改成用这个标志。

SR1没有这个位.我找到原因了,我真是服了这个芯片手册,也怪我看的时候没看仔细,真的是半句话都不能忽略,句句精华.
回复

使用道具 举报

210

主题

1042

回帖

1682

积分

至尊会员

More we do, more we can do.

积分
1682
发表于 2022-5-28 23:22:02 | 显示全部楼层
I2C协议熟悉的话,可以自己写,刚接触建议用官方驱动;
另外,高频次访问时,要考虑EEPROM本身是个低速设备。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106621
QQ
发表于 2022-5-29 09:23:13 | 显示全部楼层
money7110 发表于 2022-5-28 11:56
SR1没有这个位.我找到原因了,我真是服了这个芯片手册,也怪我看的时候没看仔细,真的是半句话都不能忽略,句 ...

没有TC的话,配套个I2C等待应答更好使些。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-26 14:06 , Processed in 0.214385 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表