標(biāo)題:
改進(jìn)型STM32模擬IIC 源程序
[打印本頁]
作者:
isdasjkdajk
時間:
2019-11-2 20:49
標(biāo)題:
改進(jìn)型STM32模擬IIC 源程序
最近在研究MPU6050,但是MPU6050的底層驅(qū)動又不想自己寫,那怎么辦呢我就想到了去移植正點(diǎn)原子的代碼,但是打開代碼一看需要修改寄存器值 那意味著要去翻數(shù)據(jù)是手冊,我這個人本身比較懶不想去翻,也為了以后不翻,于是乎我想到了自己動手寫模擬IIC的代碼。寫的過程中我就發(fā)現(xiàn)一個問題為什么每次都要管腳切換方向非常麻煩(本人非常煩這一點(diǎn)),于是乎我就在想有沒有辦法不切換方向去讀數(shù)據(jù)。最后我終于在野火的樹上找到了這樣一句話“STM32的管腳在輸出模式下也可以讀到數(shù)據(jù)”,起初我對這句話半信半疑于是我自己做了一波實(shí)驗(yàn),把管腳配置成輸出模式(推挽和開漏都配置了)結(jié)果真的能讀到數(shù)據(jù)不過要使用函數(shù)GPIO_ReadInputDataBit去讀IDR寄存器的值。用位帶操作就是不行。然后抱著這個結(jié)果我就開始了寫IIC。在這里對IIC協(xié)議不再介紹,畢竟網(wǎng)上大佬挺多的隨便改都能找到協(xié)議的說明。我的代碼最大的好處就是容易移植容易修改廢話不多說了開始附上代碼。
單片機(jī)源程序如下:
#include "bsp_i2c_ee.h"
/*適用于STM32F103系列*/
void IIC_Init(void) //初始化IIC總線所用到的端口
{
GPIO_InitTypeDef IICBUS;
IICBUS.GPIO_Mode = GPIO_Mode_Out_OD;
IICBUS.GPIO_Speed = GPIO_Speed_50MHz;
IICBUS.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //修改
GPIO_Init(GPIOA,&IICBUS); //修改
GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1); // 修改 //拉高總線(釋放總線)不進(jìn)行操作
}
static void IIC_Delay(void) //IIC延時函數(shù)對總線速度進(jìn)行控制
{
u8 i = 0;
/*
下面的時間是通過邏輯分析儀測試得到的。
工作條件:CPU主頻72MHz ,MDK編譯環(huán)境,1級優(yōu)化
循環(huán)次數(shù)為10時,SCL頻率 = 205KHz
循環(huán)次數(shù)為7時,SCL頻率 = 347KHz, SCL高電平時間1.5us,SCL低電平時間2.87us
循環(huán)次數(shù)為5時,SCL頻率 = 421KHz, SCL高電平時間1.25us,SCL低電平時間2.375us
*/
for (i = 0; i < 7; i++);
}
// IIC起始信號
void IIC_Start(void)
{
SDA_SETB;
SCL_SETB;
IIC_Delay();
SDA_CLR;
IIC_Delay();
SCL_CLR;
}
// IIC停止信號
void IIC_Stop(void)
{
SCL_CLR;
SDA_CLR;
SCL_SETB;
IIC_Delay();
SDA_SETB;
IIC_Delay();
}
//IIC主機(jī)產(chǎn)生應(yīng)答信號
void IIC_Ack(void)
{
SCL_CLR;
SDA_CLR;
IIC_Delay();
SCL_SETB;
IIC_Delay();
SCL_CLR;
}
//IIC主機(jī)不應(yīng)答
void IIC_Nack(void)
{
SCL_CLR;
SDA_SETB;
IIC_Delay();
SCL_SETB;
IIC_Delay();
SCL_CLR;
}
//IIC主機(jī)等待從機(jī)應(yīng)答
u8 IIC_WaitAck(void)
{
u8 timeout = 0;
SDA_SETB;
IIC_Delay();
SCL_SETB;
IIC_Delay();
while(SDA_Read)//讀取
{
if(++timeout>250)
{
IIC_Stop();
return 1; //超時沒有應(yīng)答
}
}
SCL_CLR;
return 0; //應(yīng)答了
}
//IIC總線發(fā)送一組數(shù)據(jù)
void IIC_SendByte(u8 TXData)
{
u8 i = 0;
SCL_CLR;
for(i = 0;i<8;i++)
{
if(TXData&0x80)
{
SDA_SETB;
}
else
{
SDA_CLR;
}
IIC_Delay();
SCL_SETB;
IIC_Delay();
SCL_CLR;
TXData<<=1;
}
}
//讀取一byte數(shù)據(jù)
//ack = 1;應(yīng)答
//ack = 0;不應(yīng)答
u8 IIC_ReadByte(u8 ack)
{
u8 Receive = 0;
u8 i = 0;
for(i=0;i<8;i++)
{
SCL_CLR;
IIC_Delay();
SCL_SETB;
Receive<<=1; //先左移動一位空位置出來
if(SDA_Read)
{
Receive ++;
}
IIC_Delay();
}
if(ack)
{
IIC_Ack(); //產(chǎn)生應(yīng)答信號
}
else
{
IIC_Nack();//不產(chǎn)生應(yīng)答信號
}
return Receive;
}
//返回0檢測到了設(shè)備
//返回1沒有檢測到設(shè)備
//參數(shù)是你所要檢測的設(shè)備的地址
u8 IIC_CheckDevice(u8 __Address)//檢測外部是否掛載了從機(jī)
{
u8 ucAck = 0;
IIC_Init();
IIC_Start();
IIC_SendByte(__Address|IIC_Wr);
ucAck = IIC_WaitAck();
IIC_Stop();
return ucAck;
}
復(fù)制代碼
全部資料51hei下載地址:
i2c.zip
(1.82 KB, 下載次數(shù): 31)
2019-11-2 20:49 上傳
點(diǎn)擊文件名下載附件
模擬IIC
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1