欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: STM32F103 硬件I2C成功。已驗證。 [打印本頁]

作者: 51黑ren    時間: 2015-12-27 04:00
標題: STM32F103 硬件I2C成功。已驗證。
首先聲明這里沒有打開STM32的事件中斷。本人菜鳥玩了兩天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區,(SYSTEM=72MHZ AHB=72MHZAPB1=36MHZ APB2=72MHZ PLL=72MHZ PLL2=40MHZ)
delay_init(72);//延時初始化

RCC->APB2ENR |= 1<<3; //使能PORTB時鐘;
GPIOB->CRL &= 0x00FFFFFF; //PB6 I2C1_SCL ,PB7I2C1_SDL
GPIOB->CRL |= 0xFF000000; //復用開漏輸出
IIC1_Init(0X30);//初始化IIC1接口地址為0X30
AT24C02_WriteByte(0X02,0XAA);//向AT24C02的0X02單元寫入0XAA
delay_ms(3);//延時不可小于2ms
N=AT24C02_ReadByte(0X02); //從AT24C02的0X02單元讀出數據
while(1)
{


}
}




//IIC1初始化,Addr為IIC1的自身地址
void IIC1_Init(u8 Addr)
{
RCC->APB1ENR |= 1<<21; //打開I2C1時鐘
RCC->APB1RSTR |= 1<<21; //復位I2C1
RCC->APB1RSTR &= ~(1<<21); //復位結束I2C1

I2C1->CR1 |= 1<<15; //復位寄存器
I2C1->CR1 &= ~(1<<15); //復位結束
//I2C模塊時鐘頻率,2~36MHz之間
I2C1->CR2 |= 36 ; //000000:禁用 000001:禁用

I2C1->CCR &= ~(1<<15); //I2C主模式 0:標準模式的I2C1:快速模式的I2C
//I2C1->CCR &= ~(1<<14); //快速模式時的占空比 0:Tlow/Thigh=21:Tlow/Thigh=16/9 (標準模式時Tlow/Thigh=1/1)
//得到200KHZ頻率
I2C1->CCR |= 90<<0;//標準模式時鐘控制分頻系數=PCLK1/2/f,f為想得到的頻率

I2C1->TRISE |= 37;//最大允許SCL上升時間為1000ns,故TRISE[5:0]中必須寫入(1us/(1/36)us =36+1)。

//I2C1->CR1 |= 1<<10;//打開ACK應答,在接收到一個字節后返回一個應答
I2C1->CR1 |= 1<<6; //廣播呼叫使能
I2C1->CR1 &= ~(1<<1); //0:I2C模式1:SMBus模式


I2C1->OAR1 &= ~(1<<15);//尋址模式 1:響應10位地址0:響應7位地址
I2C1->OAR1 |= 1<<14; //必須始終由軟件保持為1
I2C1->OAR1 |= Addr<<1; //設置接口地址的7~1位

//I2C1->CR2 |= 1<<10; //緩沖器中斷使能
//I2C1->CR2 |= 1<<9; //事件中斷使能
I2C1->CR2 |= 1<<8; //出錯中斷使能


I2C1->CR1 |= 1<<0; //開啟I2C1
}


//向AT24C02寫一個字節,ByteAddr字節地址(0~255),Data所要寫入的數據
void AT24C02_WriteByte(u8 ByteAddr,u8 Data)
{
int clear;
clear=clear;
while(I2C1->SR2&=1<<1);//等待SR2.Busy=0(總線空閑)
I2C1->CR1 |= 1<<8; //I2C1產生起始條件


while(!(I2C1->SR1&=1<<0));//等待SR1.SB=1開始位已經發送
I2C1->SR1 &= ~(1<<10);//SR1.AF清零
I2C1->DR =AT24C02_Addr_Write;//寫入AT24C02的地址Addr,寫指令,SR1.SB清零


while(!(I2C1->SR1&=1<<1));//等待SR1.ADDR=1,從設備應答
clear=I2C1->SR1;
clear=I2C1->SR2;//SR1.ADDR清零
I2C1->DR = ByteAddr;//寫入字節地址


while(!(I2C1->SR1&=1<<2));//等待SR1.BTF=1,字節地址發送完畢
clear=I2C1->SR1;//SR1.BTF清零
I2C1->DR = Data;//發送要寫入的數據


while(!(I2C1->SR1&=1<<2));//數據發送完成


I2C1->CR1 |= 1<<9;//I2C1產生停止條件
}


//從AT24C02讀出一個字節,ByteAddr字節地址(0~255)
int AT24C02_ReadByte(u8 ByteAddr)
{
int clear;
clear=clear;
while(I2C1->SR2&=1<<1);//等待SR2.Busy=0(總線空閑)
I2C1->CR1 |= 1<<8; //I2C1產生起始條件


while(!(I2C1->SR1&=1<<0));//等待SR1.SB=1開始位已經發送
I2C1->SR1 &= ~(1<<10);//SR1.AF清零
I2C1->DR =AT24C02_Addr_Write;//寫入AT24C02的地址Addr,寫指令,SR1.SB清零


while(!(I2C1->SR1&=1<<1));//等待SR1.ADDR=1,從設備應答
clear=I2C1->SR1;
clear=I2C1->SR2;//SR1.ADDR清零
I2C1->DR = ByteAddr;//寫入字節地址


I2C1->CR1 |= 1<<8; //I2C1產生起始條件


while(!(I2C1->SR1&=1<<0));//等待SR1.SB=1開始位已經發送
I2C1->SR1 &= ~(1<<10);//SR1.AF清零
I2C1->DR =AT24C02_Addr_Read;//寫入AT24C02的地址Addr,讀指令,SR1.SB清零


while(!(I2C1->SR1&=1<<1));//等待SR1.ADDR=1,從設備應答
clear=I2C1->SR1;
clear=I2C1->SR2;//SR1.ADDR清零


while(!(I2C1->SR1&=1<<6));//等待SR1.RxNE=1,接收到數據
I2C1->CR1 |= 1<<9; //I2C1產生停止條件
return I2C1->DR;
}



void I2C1_ER_IRQHandler(void)
{
if(I2C1->SR1 & 1<<10) //應答失敗
{
I2C1->SR1 &=~(1<<10); //清除中斷
}

if(I2C1->SR1 & 1<<14) //超時
{
I2C1->SR1 &=~(1<<14); //清除中斷
}

if(I2C1->SR1 & 1<<11) //過載/欠載
{
I2C1->SR1 &=~(1<<11); //清除中斷
}

if(I2C1->SR1 & 1<<9) //仲裁丟失
{
I2C1->SR1 &=~(1<<9); //清除中斷
}

if(I2C1->SR1 & 1<<8) //總線出錯
{
I2C1->SR1 &=~(1<<8); //清除中斷
}
}


作者: zhouji92    時間: 2019-3-29 20:10
哥就是等的你這個代碼,救了我了。我很喜歡這個代碼




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1