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;
}