STM32 IIC

STM32 IIC

没有调试器,都是用显示SR1的值来观察中间结果,花了好多时间,记下来

void eprom_init()
{
	RCC->APB2ENR|=0x09;
	RCC->APB1ENR|=1<<22;
	RCC->APB1RSTR|=1<<22;
	RCC->APB1RSTR&=~(1<<22);

	GPIOB->CRH&=0xffff00ff;
	GPIOB->CRH|=0x0000ff00; //开漏复用
	I2C2->CR1=0x8000;
	I2C2->CR1=0x0000;


	I2C2->CR2=0x08;
	I2C2->OAR1=0x4140;
	I2C2->CCR=0x0028;
	I2C2->TRISE=0x0009;
	I2C2->CR1|=1;
	I2C2->CR1|=1<<10;
}

u8 eprom_getch(u8 arr)
{
	u8 clear;
	while(I2C2->SR2&2);
	I2C_START;
	while(!(I2C2->SR1&1));
	I2C2->DR=0xa0;
	while(!(I2C2->SR1&2));
	clear=I2C2->SR2;
	I2C2->DR=arr;
	while(!(I2C2->SR1&4));
	I2C_START;
	while(!(I2C2->SR1&1));
	I2C2->DR=0xa1;
	while(!(I2C2->SR1&2));
	clear=I2C2->SR2;
	while(!(I2C2->SR1&0x40));
	I2C2->CR1&=~(1<<10);
	clear=I2C2->DR;
	I2C_STOP;
	return clear;
}

``下面是改为用DMA传输的

// dma.h
#ifndef __DMA_H
#define __DMA_H
#include "sys.h"
void DMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 ccr,u32 cpar,u32 cmar,u16 cndtr);
void DMA_Enable(DMA_Channel_TypeDef* DMA_CHx);
#endif
 dma.c
#include "dma.h"
#include "delay.h"
u16 DMA1_MEM_LEN;
void DMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 ccr,u32 cpar,u32 cmar,u16 cndtr)
{
	RCC->AHBENR|=1;
	delay_ms(5);
	DMA_CHx->CPAR=cpar;
	DMA_CHx->CMAR=cmar;
	DMA1_MEM_LEN=cndtr;
	DMA_CHx->CNDTR=DMA1_MEM_LEN;
	DMA_CHx->CCR=0;
	DMA_CHx->CCR=ccr;
}
void DMA_Enable(DMA_Channel_TypeDef* DMA_CHx)
{
	DMA_CHx->CCR&=~1;
	DMA_CHx->CNDTR=DMA1_MEM_LEN;
	DMA_CHx->CCR|=1;
}

//eprom.c
#include "eprom.h"
#include "delay.h"
#include "led_beep.h"
#include "dma.h"
u8 I2C2_buff[32];
u8 I2C2_arr;
u8 I2C2_cnt;
u8 I2C2_stat;
void eprom_init()
{
	RCC->APB2ENR|=0x09;
	RCC->APB1ENR|=1<<22;
	RCC->APB1RSTR|=1<<22;
	RCC->APB1RSTR&=~(1<<22);

	GPIOB->CRH&=0xffff00ff;
	GPIOB->CRH|=0x0000ff00; //开漏复用
	I2C2->CR1=0x8000;
	I2C2->CR1=0x0000;
	NVIC_Init(1,1,I2C2_EV_IRQn);


//	I2C2->CR2=0x0608; //开中断,时钟8M
	I2C2->CR2=0x1808; //不开中断,用DMA 标记LAST
	I2C2->OAR1=0x4140;
	I2C2->CCR=0x0028; //100K 1:1
	I2C2->TRISE=0x0009; //1000ns+
	I2C2->CR1|=1;
	I2C2->CR1|=1<<10;
	DMA_Config(DMA1_Channel5,0x1082,(u32)&I2C2->DR,(u32)I2C2_buff,32); //DMA初始化CCR=0x1082存储器自动增量,读,开完成中断
}


void eprom_read(u8 arr,u8 len)
{
	I2C2_stat=0x80; //read;
	I2C2_arr=arr;
	I2C2_cnt=len;

	I2C_START;
	while(!(I2C2->SR1&1));
	I2C2->DR=0xa0;
	while(!(I2C2->SR1&2));
	I2C2->SR2;
	I2C2->DR=arr;
	while(!(I2C2->SR1&4));
	I2C_START;
	while(!(I2C2->SR1&1));
	I2C2->DR=0xa1;
	while(!(I2C2->SR1&2));
	I2C2->SR2;
	DMA_Enable(DMA1_Channel5);//到开始读数据才启动DMA
}

void DMA1_Channel5_IRQHandler(void)
{
	I2C_STOP;
	I2C2_stat=0x9f;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值