STM32 软件模拟 IIC 代码,标准库、HAL库可用
生活随笔
收集整理的這篇文章主要介紹了
STM32 软件模拟 IIC 代码,标准库、HAL库可用
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1 #ifndef _IIC_H
2 #define _IIC_H
3
4 #include "stdio.h"
5 #include "stm32f1xx_hal.h"
6
7
8 /* 定義控制 SDA SCL 的宏 標(biāo)準(zhǔn)庫版
9 #define I2C_SDA_UP GPIO_SetBits (GPIOC,GPIO_PIN_8) //SDA高電平
10 #define I2C_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_PIN_8) //SDA低電平
11 #define I2C_SCL_UP GPIO_SetBits (GPIOC,GPIO_PIN_9) //SCL高電平
12 #define I2C_SCL_LOW GPIO_ResetBits(GPIOC,GPIO_PIN_9) //SCL低電平
13 */
14
15
16 /* 定義控制 SDA SCL 的宏 HAL庫版 */
17
18 #define I2C_SDA_UP HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET) //SDA高電平
19 #define I2C_SDA_LOW HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET) //SDA低電平
20 #define I2C_SCL_UP HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET) //SCL高電平
21 #define I2C_SCL_LOW HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET) //SCL低電平
22
23
24
25 /* 獲取 SDA SCL 引腳狀態(tài),標(biāo)準(zhǔn)庫版也是用相同邏輯 */
26
27 #define I2C_SDA HAL_GPIO_ReadPin(GPIOC ,GPIO_PIN_8) //獲取SDA引腳狀態(tài)
28 #define I2C_SCL HAL_GPIO_ReadPin(GPIOC ,GPIO_PIN_9) //獲取SCL引腳狀態(tài)
29
30
31 void iic_stare(void); //* 開始信號(hào)
32 void i2c_ack(void); //* 應(yīng)答信號(hào)
33 void I2C_No_ack(void); //* 非應(yīng)答信號(hào)
34 void i2c_stop(void); //* 停止信號(hào)
35 char i2c_wit_ack(void); //* 等待應(yīng)答
36 void i2c_send(uint8_t dat); //* 發(fā)送數(shù)據(jù)
37 uint8_t i2c_read(void); //* 接收數(shù)據(jù)
38
39 void SDA_OUT(void); //* SDA 設(shè)置為輸出
40 void SDA_IN(void); //* SDA 設(shè)置為輸入
41
42 void delay_us(uint32_t i); //*延時(shí)
43
44 #endif /*****************************************************************************
* *
* File: 軟件模擬IIC, HAL庫版本,標(biāo)準(zhǔn)庫也 *
* 可用,只需要做一些相對(duì)應(yīng)修改即可 *
* *
*****************************************************************************/#include "iic.h"/*******************************************************************************
* 函 數(shù) 名 : i2c_stare
* 函數(shù)功能 : iic開始信號(hào),SCL高電平時(shí),SDA出現(xiàn)一個(gè)下跳沿表示啟動(dòng)信號(hào)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void i2c_stare(void)
{SDA_OUT(); I2C_SDA_UP;I2C_SCL_UP;delay_us(4);I2C_SDA_LOW; //啟動(dòng)開始信號(hào)delay_us(4);I2C_SCL_LOW; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}/*******************************************************************************
* 函 數(shù) 名 : i2c_stop
* 函數(shù)功能 : iic停止信號(hào),SCL高電平時(shí),SDA出現(xiàn)一個(gè)上跳沿表示停止信號(hào)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void i2c_stop(void)
{SDA_OUT(); //sda線輸出I2C_SDA_LOW; //發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)
I2C_SCL_UP;delay_us(4); //結(jié)束條件建立時(shí)間大于4μI2C_SDA_UP; //發(fā)送I2C總線結(jié)束信號(hào)delay_us(4);I2C_SCL_LOW;
}/*******************************************************************************
* 函 數(shù) 名 : i2c_send
* 函數(shù)功能 : iic發(fā)送數(shù)據(jù)
* 輸 入 : uint8_t dat,要發(fā)送的數(shù)據(jù)
* 輸 出 : 無
*******************************************************************************/
void i2c_send(uint8_t dat)
{unsigned char temp;SDA_OUT();for(temp=0x80;temp!=0;temp>>=1){if((temp & dat)== 0){I2C_SDA_LOW;}else{I2C_SDA_UP;}delay_us(1);I2C_SCL_UP;delay_us(4);I2C_SCL_LOW;}
}/*******************************************************************************
* 函 數(shù) 名 : i2c_read
* 函數(shù)功能 : iic接收數(shù)據(jù)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
uint8_t i2c_read(void)
{unsigned char temp;unsigned char dat;I2C_SDA_UP; //釋放總線準(zhǔn)備接收
SDA_IN();for(temp=0x80;temp!=0;temp>>=1){delay_us(1);I2C_SCL_UP;if(I2C_SDA==1){dat|=temp;}else{dat&=~temp;}I2C_SCL_LOW;}return dat;
}/*******************************************************************************
* 函 數(shù) 名 : i2c_wit_ack
* 函數(shù)功能 : iic等待應(yīng)答
* 輸 入 : 無
* 輸 出 : 0/1,返回1表示無應(yīng)答信號(hào),返回0表示應(yīng)答
*******************************************************************************/
char i2c_wit_ack(void)
{uint8_t con=0;I2C_SDA_UP; //釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答delay_us(1);I2C_SCL_UP; //CPU驅(qū)動(dòng)SCL = 1, 此時(shí)器件會(huì)返回ACK應(yīng)答
SDA_IN(); delay_us(1);while( I2C_SDA ) //CPU讀取SDA口線狀態(tài)
{con++;if(con>255){i2c_stop();return 1; //無應(yīng)答信號(hào)
}}I2C_SCL_LOW; delay_us(1);return 0; //有應(yīng)答
}/*******************************************************************************
* 函 數(shù) 名 : i2c_ack
* 函數(shù)功能 : iic應(yīng)答信號(hào)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void i2c_ack(void)
{SDA_OUT();I2C_SDA_LOW;delay_us(1);I2C_SCL_UP; //CPU產(chǎn)生1個(gè)時(shí)鐘delay_us(4); //時(shí)鐘低電平周期大于4μI2C_SCL_LOW; //清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收delay_us(4);I2C_SDA_UP; //CPU釋放SDA總線
}/*******************************************************************************
* 函 數(shù) 名 : I2C_No_ack
* 函數(shù)功能 : iic非應(yīng)答信號(hào)
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void I2C_No_ack(void)
{SDA_OUT();I2C_SDA_UP;delay_us(1);I2C_SCL_UP;delay_us(4);I2C_SCL_LOW; delay_us(4);
}/*******************************************************************************
* 函 數(shù) 名 : SDA_OUT
* 函數(shù)功能 : SDA 設(shè)置為輸出
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void SDA_OUT(void)
{ /* 標(biāo)準(zhǔn)庫使用,修改端口引腳可用GPIO_InitTypeDef GPIO_InitTypeStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitTypeStruct.GPIO_Pin=GPIO_Pin_7; GPIO_InitTypeStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitTypeStruct);
*/ /* HAL庫使用,HAL庫注意要把初始化函數(shù)的靜態(tài)標(biāo)記去掉 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = SDA_Pin; //使用STM3cubemx是定義好的SDA_Pin為GPIO_PIN_8的標(biāo)簽GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}/*******************************************************************************
* 函 數(shù) 名 : SDA_IN
* 函數(shù)功能 : SDA 設(shè)置為輸入
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void SDA_IN(void)
{/* 標(biāo)準(zhǔn)庫使用,修改端口引腳可用GPIO_InitTypeDef GPIO_InitTypeStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitTypeStruct.GPIO_Pin=GPIO_Pin_7; GPIO_InitTypeStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitTypeStruct);
*/ /* HAL庫使用, HAL庫注意要把初始化函數(shù)的靜態(tài)標(biāo)記去掉 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = SDA_Pin ; //使用STM3cubemx是定義好的SDA_Pin為GPIO_PIN_8的標(biāo)簽GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
} /*******************************************************************************
* 函 數(shù) 名 : delay_us
* 函數(shù)功能 : 延時(shí)函數(shù),延時(shí)us
* 輸 入 : i
* 輸 出 : 無
*******************************************************************************/
void delay_us(uint32_t i)
{uint32_t temp;SysTick->LOAD=9*i; //設(shè)置重裝數(shù)值, 72MHZ時(shí)SysTick->CTRL=0X01; //使能,減到零是無動(dòng)作,采用外部時(shí)鐘源SysTick->VAL=0; //清零計(jì)數(shù)器do{temp=SysTick->CTRL; //讀取當(dāng)前倒計(jì)數(shù)值
}while((temp&0x01)&&(!(temp&(1<<16)))); //等待時(shí)間到達(dá)
SysTick->CTRL=0; //關(guān)閉計(jì)數(shù)器SysTick->VAL=0; //清空計(jì)數(shù)器
}
?
該代碼,標(biāo)準(zhǔn)庫可用,HAL庫也可用,只需要代碼做一些修改即可!
轉(zhuǎn)載于:https://www.cnblogs.com/xingboy/p/9585350.html
總結(jié)
以上是生活随笔為你收集整理的STM32 软件模拟 IIC 代码,标准库、HAL库可用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Sentinel实现黑白名单控制详细教程
- 下一篇: 第二次考核