|
首先聲明這里沒(méi)有打開(kāi)STM32的事件中斷。本人菜鳥(niǎo)玩了兩天I2C。
#include"stm32f10x_lib.h"
#include"stm32f10x_it.h"
#include"sys.h"
#define AT24C02_Addr_Write 0XA0;
#define AT24C02_Addr_Read(0XA0+1);
void IIC1_Init(u8 Addr);
void AT24C02_WriteByte(u8 ByteAddr,u8 Data);
int AT24C02_ReadByte(u8 ByteAddr);
int N;
int main(void)
{
Stm32_Clock_Init(9); //中斷向量表映射到flash區(qū),(SYSTEM=72MHZ AHB=72MHZAPB1=36MHZ APB2=72MHZ PLL=72MHZ PLL2=40MHZ)
delay_init(72);//延時(shí)初始化
RCC->APB2ENR |= 1<<3; //使能PORTB時(shí)鐘;
GPIOB->CRL &= 0x00FFFFFF; //PB6 I2C1_SCL ,PB7I2C1_SDL
GPIOB->CRL |= 0xFF000000; //復(fù)用開(kāi)漏輸出
IIC1_Init(0X30);//初始化IIC1接口地址為0X30
AT24C02_WriteByte(0X02,0XAA);//向AT24C02的0X02單元寫(xiě)入0XAA
delay_ms(3);//延時(shí)不可小于2ms
N=AT24C02_ReadByte(0X02); //從AT24C02的0X02單元讀出數(shù)據(jù)
while(1)
{
}
}
//IIC1初始化,Addr為IIC1的自身地址
void IIC1_Init(u8 Addr)
{
RCC->APB1ENR |= 1<<21; //打開(kāi)I2C1時(shí)鐘
RCC->APB1RSTR |= 1<<21; //復(fù)位I2C1
RCC->APB1RSTR &= ~(1<<21); //復(fù)位結(jié)束I2C1
I2C1->CR1 |= 1<<15; //復(fù)位寄存器
I2C1->CR1 &= ~(1<<15); //復(fù)位結(jié)束
//I2C模塊時(shí)鐘頻率,2~36MHz之間
I2C1->CR2 |= 36 ; //000000:禁用 000001:禁用
I2C1->CCR &= ~(1<<15); //I2C主模式 0:標(biāo)準(zhǔn)模式的I2C1:快速模式的I2C
//I2C1->CCR &= ~(1<<14); //快速模式時(shí)的占空比 0:Tlow/Thigh=21:Tlow/Thigh=16/9 (標(biāo)準(zhǔn)模式時(shí)Tlow/Thigh=1/1)
//得到200KHZ頻率
I2C1->CCR |= 90<<0;//標(biāo)準(zhǔn)模式時(shí)鐘控制分頻系數(shù)=PCLK1/2/f,f為想得到的頻率
I2C1->TRISE |= 37;//最大允許SCL上升時(shí)間為1000ns,故TRISE[5:0]中必須寫(xiě)入(1us/(1/36)us =36+1)。
//I2C1->CR1 |= 1<<10;//打開(kāi)ACK應(yīng)答,在接收到一個(gè)字節(jié)后返回一個(gè)應(yīng)答
I2C1->CR1 |= 1<<6; //廣播呼叫使能
I2C1->CR1 &= ~(1<<1); //0:I2C模式1:SMBus模式
I2C1->OAR1 &= ~(1<<15);//尋址模式 1:響應(yīng)10位地址0:響應(yīng)7位地址
I2C1->OAR1 |= 1<<14; //必須始終由軟件保持為1
I2C1->OAR1 |= Addr<<1; //設(shè)置接口地址的7~1位
//I2C1->CR2 |= 1<<10; //緩沖器中斷使能
//I2C1->CR2 |= 1<<9; //事件中斷使能
I2C1->CR2 |= 1<<8; //出錯(cuò)中斷使能
I2C1->CR1 |= 1<<0; //開(kāi)啟I2C1
}
//向AT24C02寫(xiě)一個(gè)字節(jié),ByteAddr字節(jié)地址(0~255),Data所要寫(xiě)入的數(shù)據(jù)
void AT24C02_WriteByte(u8 ByteAddr,u8 Data)
{
int clear;
clear=clear;
while(I2C1->SR2&=1<<1);//等待SR2.Busy=0(總線空閑)
I2C1->CR1 |= 1<<8; //I2C1產(chǎn)生起始條件
while(!(I2C1->SR1&=1<<0));//等待SR1.SB=1開(kāi)始位已經(jīng)發(fā)送
I2C1->SR1 &= ~(1<<10);//SR1.AF清零
I2C1->DR =AT24C02_Addr_Write;//寫(xiě)入AT24C02的地址Addr,寫(xiě)指令,SR1.SB清零
while(!(I2C1->SR1&=1<<1));//等待SR1.ADDR=1,從設(shè)備應(yīng)答
clear=I2C1->SR1;
clear=I2C1->SR2;//SR1.ADDR清零
I2C1->DR = ByteAddr;//寫(xiě)入字節(jié)地址
while(!(I2C1->SR1&=1<<2));//等待SR1.BTF=1,字節(jié)地址發(fā)送完畢
clear=I2C1->SR1;//SR1.BTF清零
I2C1->DR = Data;//發(fā)送要寫(xiě)入的數(shù)據(jù)
while(!(I2C1->SR1&=1<<2));//數(shù)據(jù)發(fā)送完成
I2C1->CR1 |= 1<<9;//I2C1產(chǎn)生停止條件
}
//從AT24C02讀出一個(gè)字節(jié),ByteAddr字節(jié)地址(0~255)
int AT24C02_ReadByte(u8 ByteAddr)
{
int clear;
clear=clear;
while(I2C1->SR2&=1<<1);//等待SR2.Busy=0(總線空閑)
I2C1->CR1 |= 1<<8; //I2C1產(chǎn)生起始條件
while(!(I2C1->SR1&=1<<0));//等待SR1.SB=1開(kāi)始位已經(jīng)發(fā)送
I2C1->SR1 &= ~(1<<10);//SR1.AF清零
I2C1->DR =AT24C02_Addr_Write;//寫(xiě)入AT24C02的地址Addr,寫(xiě)指令,SR1.SB清零
while(!(I2C1->SR1&=1<<1));//等待SR1.ADDR=1,從設(shè)備應(yīng)答
clear=I2C1->SR1;
clear=I2C1->SR2;//SR1.ADDR清零
I2C1->DR = ByteAddr;//寫(xiě)入字節(jié)地址
I2C1->CR1 |= 1<<8; //I2C1產(chǎn)生起始條件
while(!(I2C1->SR1&=1<<0));//等待SR1.SB=1開(kāi)始位已經(jīng)發(fā)送
I2C1->SR1 &= ~(1<<10);//SR1.AF清零
I2C1->DR =AT24C02_Addr_Read;//寫(xiě)入AT24C02的地址Addr,讀指令,SR1.SB清零
while(!(I2C1->SR1&=1<<1));//等待SR1.ADDR=1,從設(shè)備應(yīng)答
clear=I2C1->SR1;
clear=I2C1->SR2;//SR1.ADDR清零
while(!(I2C1->SR1&=1<<6));//等待SR1.RxNE=1,接收到數(shù)據(jù)
I2C1->CR1 |= 1<<9; //I2C1產(chǎn)生停止條件
return I2C1->DR;
}
void I2C1_ER_IRQHandler(void)
{
if(I2C1->SR1 & 1<<10) //應(yīng)答失敗
{
I2C1->SR1 &=~(1<<10); //清除中斷
}
if(I2C1->SR1 & 1<<14) //超時(shí)
{
I2C1->SR1 &=~(1<<14); //清除中斷
}
if(I2C1->SR1 & 1<<11) //過(guò)載/欠載
{
I2C1->SR1 &=~(1<<11); //清除中斷
}
if(I2C1->SR1 & 1<<9) //仲裁丟失
{
I2C1->SR1 &=~(1<<9); //清除中斷
}
if(I2C1->SR1 & 1<<8) //總線出錯(cuò)
{
I2C1->SR1 &=~(1<<8); //清除中斷
}
}
|
|