作弊網(wǎng)站網(wǎng)站開發(fā)建設(shè)步驟
目錄
STM32模擬I2C通訊的驅(qū)動程序
開發(fā)環(huán)境
引腳連接
驅(qū)動程序
STM32模擬I2C通訊的驅(qū)動程序
開發(fā)環(huán)境
立創(chuàng)天空星開發(fā)板、主控芯片為STM32F407VxT6
引腳連接
使用stm32的PB9引腳模擬I2C時鐘線SCL、PB8引腳模擬I2C數(shù)據(jù)線SDA
驅(qū)動程序
i2c.h文件如下:
#ifndef _I2C_H
#define _I2C_H#include "stm32f4xx.h"//端口宏定義
#define RCC_I2C_GPIO RCC_AHB1Periph_GPIOB
#define PORT_I2C_GPIO GPIOB#define GPIO_SDA GPIO_Pin_8
#define GPIO_SCL GPIO_Pin_9//設(shè)置SDA輸出模式
#define SDA_OUT() { \GPIO_InitTypeDef GPIO_InitStructure; \GPIO_InitStructure.GPIO_Pin = GPIO_SDA; \GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; \GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; \GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; \GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; \GPIO_Init(PORT_I2C_GPIO, &GPIO_InitStructure); \}
//設(shè)置SDA輸入模式
#define SDA_IN() { \GPIO_InitTypeDef GPIO_InitStructure; \GPIO_InitStructure.GPIO_Pin = GPIO_SDA; \GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; \GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; \GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; \GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; \GPIO_Init(PORT_I2C_GPIO, &GPIO_InitStructure); \}
//獲取SDA引腳的電平
#define SDA_GET() GPIO_ReadInputDataBit(PORT_I2C_GPIO, GPIO_SDA)//SDA與SCL輸出高低電平
#define SDA(x) GPIO_WriteBit(PORT_I2C_GPIO, GPIO_SDA, (x?Bit_SET:Bit_RESET) )
#define SCL(x) GPIO_WriteBit(PORT_I2C_GPIO, GPIO_SCL, (x?Bit_SET:Bit_RESET) )//模擬I2C引腳初始化
void I2C_GPIO_Init(void);//I2C起始時序
void I2C_Start(void);//I2C停止時序
void I2C_Stop(void);//主機(jī)發(fā)送應(yīng)答或者非應(yīng)答信號
void I2C_Send_Ack(unsigned char ack);//主機(jī)等待從機(jī)應(yīng)答
unsigned char I2C_WaitAck(void);//主機(jī)發(fā)送一個字節(jié)數(shù)據(jù)
void Send_Byte(uint8_t dat);//主機(jī)接收一個字節(jié)數(shù)據(jù)
unsigned char Read_Byte(void);#endif
i2c.c文件如下:
#include "i2c.h"/******************************************************************* 函 數(shù) 名 稱:I2C_GPIO_Init* 函 數(shù) 說 明:模擬IIC引腳初始化* 函 數(shù) 形 參:無* 函 數(shù) 返 回:無* 備 注:無
******************************************************************/
void I2C_GPIO_Init(void)
{RCC_AHB1PeriphClockCmd(RCC_I2C_GPIO, ENABLE); // 使能GPIO時鐘GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_SDA | GPIO_SCL;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(PORT_I2C_GPIO, &GPIO_InitStructure);
}/******************************************************************* 函 數(shù) 名 稱:I2C_Start* 函 數(shù) 說 明:IIC起始時序* 函 數(shù) 形 參:無* 函 數(shù) 返 回:無* 備 注:無
******************************************************************/
void I2C_Start(void)
{SDA_OUT();SCL(1);SDA(0);SDA(1);delay_us(5);SDA(0);delay_us(5);SCL(0);
}/******************************************************************* 函 數(shù) 名 稱:I2C_Stop* 函 數(shù) 說 明:I2C停止信號* 函 數(shù) 形 參:無* 函 數(shù) 返 回:無* 備 注:無
******************************************************************/
void I2C_Stop(void)
{SDA_OUT();SCL(0);SDA(0);SCL(1);delay_us(5);SDA(1);delay_us(5);
}/******************************************************************* 函 數(shù) 名 稱:I2C_Send_Ack* 函 數(shù) 說 明:主機(jī)發(fā)送應(yīng)答或者非應(yīng)答信號* 函 數(shù) 形 參:0發(fā)送應(yīng)答 1發(fā)送非應(yīng)答* 函 數(shù) 返 回:無* 備 注:無
******************************************************************/
void I2C_Send_Ack(unsigned char ack)
{SDA_OUT();SCL(0);SDA(0);delay_us(5);if(!ack) SDA(0);else SDA(1);SCL(1);delay_us(5);SCL(0);SDA(1);
}/******************************************************************* 函 數(shù) 名 稱:I2C_WaitAck* 函 數(shù) 說 明:主機(jī)等待從機(jī)應(yīng)答* 函 數(shù) 形 參:無* 函 數(shù) 返 回:0有應(yīng)答 1超時無應(yīng)答* 備 注:無
******************************************************************/
unsigned char I2C_WaitAck(void)
{char ack = 0;unsigned char ack_flag = 10;SCL(0);SDA(1);SDA_IN();SCL(1);while( (SDA_GET()==1) && ( ack_flag ) ){ack_flag--;delay_us(5);}if( ack_flag <= 0 ){I2C_Stop();return 1; //應(yīng)答超時返回1}else{SCL(0);SDA_OUT();}return ack; //正常通訊返回應(yīng)答
}/******************************************************************* 函 數(shù) 名 稱:Send_Byte* 函 數(shù) 說 明:主機(jī)發(fā)送一個字節(jié)數(shù)據(jù)* 函 數(shù) 形 參:dat要發(fā)送的數(shù)據(jù)* 函 數(shù) 返 回:無* 備 注:無
******************************************************************/
void Send_Byte(uint8_t dat)
{int i = 0;SDA_OUT();SCL(0);//拉低時鐘開始數(shù)據(jù)傳輸for( i = 0; i < 8; i++ ){SDA( (dat & 0x80) >> 7 );delay_us(1);SCL(1);delay_us(5);SCL(0);delay_us(5);dat<<=1;}
}/******************************************************************* 函 數(shù) 名 稱:Read_Byte* 函 數(shù) 說 明:主機(jī)接收一個字節(jié)數(shù)據(jù)* 函 數(shù) 形 參:無* 函 數(shù) 返 回:接收到的數(shù)據(jù)* 備 注:無
******************************************************************/
unsigned char Read_Byte(void)
{unsigned char i,receive=0;SDA_IN();for(i=0;i<8;i++ ){SCL(0);delay_us(5);SCL(1);delay_us(5);receive<<=1;if(SDA_GET()){receive |= 1;}delay_us(5);}SCL(0);return receive;
}
? ?