历史上的今天
返回首页

历史上的今天

今天是:2025年08月07日(星期四)

正在发生

2019年08月07日 | STM32F103,HAL实现软件I2C,与硬件I2C

2019-08-07 来源:eefocus

1,硬件I2C


HAL_I2C_Mem_Write(&hi2c1,0x88,0,I2C_MEMADD_SIZE_8BIT,0,0,0X10);//写

 

HAL_I2C_Master_Receive(&hi2c1,0x89,(uint8_t*)datatemp,4,0x10);//读

2 软件I2C


#ifndef __MYI2C_H__

#define __MYI2C_H__

 

#include "stm32f1xx_hal.h"

#include "main.h"

#include "stdint.h"

 

#define CPU_FREQUENCY_MHZ  72

#define MYI2C_SCL_PIN   I2C_SCL_Pin

#define MYI2C_SCL_PORT I2C_SCL_GPIO_Port

#define MYI2C_SDA_PIN I2C_SDL_Pin

#define MYI2C_SDA_PORT I2C_SDL_GPIO_Port

 

#define SDA_Dout_LOW()                          HAL_GPIO_WritePin(MYI2C_SDA_PORT,MYI2C_SDA_PIN,GPIO_PIN_RESET) 

#define SDA_Dout_HIGH()                         HAL_GPIO_WritePin(MYI2C_SDA_PORT,MYI2C_SDA_PIN,GPIO_PIN_SET)

#define SDA_Data_IN()                           HAL_GPIO_ReadPin(MYI2C_SDA_PORT,MYI2C_SDA_PIN)

#define SCL_Dout_LOW()                          HAL_GPIO_WritePin(MYI2C_SCL_PORT,MYI2C_SCL_PIN,GPIO_PIN_RESET) 

#define SCL_Dout_HIGH()                         HAL_GPIO_WritePin(MYI2C_SCL_PORT,MYI2C_SCL_PIN,GPIO_PIN_SET)

#define SCL_Data_IN()                           HAL_GPIO_ReadPin(MYI2C_SCL_PORT,MYI2C_SCL_PIN)

#define SDA_Write(XX)    HAL_GPIO_WritePin(MYI2C_SDA_PORT,MYI2C_SDA_PIN,(XX?GPIO_PIN_SET:GPIO_PIN_RESET))

 

void I2C_Init(void);

void I2C_Start(void);

void I2C_Stop(void);

void I2C_Send_Byte(uint8_t txd); 

uint8_t     I2C_Read_Byte(uint8_t ack);

void I2C_NAck(void);

void I2C_Ack(void);

uint8_t     I2C_Wait_Ack(void);

 

 

 

 

void delay_xus(__IO uint32_t nTime);

 

 

#define Delay_us(xx)  delay_xus(xx)

 

#endif

 

#include "myi2c.h"

 

 

 

void delay_xus(__IO uint32_t nTime)

{

    int old_val,new_val,val;

 

    if(nTime > 900)

    {

        for(old_val = 0; old_val < nTime/900; old_val++)

        {

            delay_xus(900);

        }

        nTime = nTime%900;

    }

 

    old_val = SysTick->VAL;

    new_val = old_val - CPU_FREQUENCY_MHZ*nTime;

    if(new_val >= 0)

    {

        do

        {

            val = SysTick->VAL;

        }

        while((val < old_val)&&(val >= new_val));

    }

    else

    {

        new_val +=CPU_FREQUENCY_MHZ*1000;

        do

        {

            val = SysTick->VAL;

        }

        while((val <= old_val)||(val > new_val));

 

    }

}

 

//--------------------------------------------

void SDA_Output(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = MYI2C_SDA_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Speed =GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(MYI2C_SDA_PORT,&GPIO_InitStruct);

}

 

 

void SDA_Input(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = MYI2C_SDA_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Speed =GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(MYI2C_SDA_PORT,&GPIO_InitStruct);

}

 

void SCL_Output(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = MYI2C_SCL_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Speed =GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(MYI2C_SCL_PORT,&GPIO_InitStruct);

}

 

 

void SCL_Input(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = MYI2C_SCL_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Speed =GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(MYI2C_SCL_PORT,&GPIO_InitStruct);

}

 

 

 

 

void I2C_Init(void)

{

SCL_Output();

SDA_Output();

SCL_Dout_HIGH();

SDA_Dout_HIGH();

}

 

 

//产生IIC起始信号

 

void I2C_Start(void)

{

SDA_Output();

SDA_Dout_HIGH();

SCL_Dout_HIGH();

Delay_us(4);

SDA_Dout_LOW();

Delay_us(4);

SCL_Dout_LOW();

}

 

  

//产生IIC停止信号

 

void I2C_Stop(void)

{

SDA_Output();

SCL_Dout_LOW();

SDA_Dout_LOW();

Delay_us(4);

SCL_Dout_HIGH();

SDA_Dout_HIGH();

Delay_us(4);    

}

 

uint8_t I2C_Wait_Ack(void)

{

uint8_t ucErrTime=0;

SDA_Input();

SDA_Dout_HIGH();Delay_us(1);    

SCL_Dout_HIGH();Delay_us(1);  

while(SDA_Data_IN())

{

ucErrTime++;

if(ucErrTime>250)

{

I2C_Stop();

return 1;

}

}

SCL_Dout_LOW();//时钟输出0    

return 0; 

}

 

//产生ACK应答

 

void I2C_Ack(void)

{

SCL_Dout_LOW();

SDA_Output();

SDA_Dout_LOW();

Delay_us(2);

SCL_Dout_HIGH();

Delay_us(2);

SCL_Dout_LOW();

}

 

//不产生ACK应答   

 

void I2C_NAck(void)

{

SCL_Dout_LOW();

SDA_Output();

SDA_Dout_HIGH();

Delay_us(2);

SCL_Dout_HIGH();

Delay_us(2);

SCL_Dout_LOW();

}      

//IIC发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答

void I2C_Send_Byte(uint8_t txd) 

{                        

uint8_t t;      

//拉低时钟开始数据传输

SDA_Output();

SCL_Dout_LOW();

for(t=0;t<8;t++)

{  

SDA_Write((txd&0x80)>>7);    

txd<<=1;   

Delay_us(5);   //对TEA5767这三个延时都是必须的

SCL_Dout_HIGH();

Delay_us(5);

SCL_Dout_LOW();

//Delay_us(2);

  }  

}     

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   

uint8_t I2C_Read_Byte(uint8_t ack)

{

unsigned char i,receive=0;

//SDA设置为输入

SDA_Input();

  for(i=0;i<8;i++ )

{

SCL_Dout_LOW();

Delay_us(5);

SCL_Dout_HIGH();

receive<<=1;

if(SDA_Data_IN())receive++;   

Delay_us(5); 

  }  

  if(!ack)I2C_NAck();//发送nACK

  else  I2C_Ack(); //发送ACK   

  

return receive;

}

推荐阅读

史海拾趣

上海如韵(CONSONANCE)公司的发展小趣事

随着电子行业的快速发展,市场竞争日益激烈。为了应对这一挑战,如韵不断调整和优化产品线,加强与国际知名企业的合作,引进先进的技术和设备。同时,公司加大了对研发团队的投入,鼓励员工进行创新实践和技术交流。

在面对行业内的价格战和恶性竞争时,如韵始终坚持产品质量和客户满意度为首要原则。通过不断提升产品质量和服务水平,如韵赢得了客户的信任和口碑。即使在行业面临困境的时期,如韵也凭借着强大的技术实力和良好的市场口碑保持了稳健的发展态势。

Calmos Systems Inc公司的发展小趣事

为了进一步扩大市场份额,Calmos Systems Inc公司积极寻求与行业内外的合作伙伴建立合作关系。公司与多家知名企业签订了战略合作协议,共同开发新产品、拓展新市场。同时,公司还积极参加各类行业展会和交流活动,与业内同行进行深入交流,了解行业动态和发展趋势。通过这些努力,公司的品牌知名度和影响力不断提升,为公司的长期发展打下了坚实的基础。

Bud Industries公司的发展小趣事

为了进一步扩大市场份额,Calmos Systems Inc公司积极寻求与行业内外的合作伙伴建立合作关系。公司与多家知名企业签订了战略合作协议,共同开发新产品、拓展新市场。同时,公司还积极参加各类行业展会和交流活动,与业内同行进行深入交流,了解行业动态和发展趋势。通过这些努力,公司的品牌知名度和影响力不断提升,为公司的长期发展打下了坚实的基础。

GE Solid State公司的发展小趣事
在嘈杂的环境中,声音信号可能受到干扰,影响用户的判断。
Elytone Electronics Co Ltd公司的发展小趣事

进入XXXX年代,随着电子技术的飞速发展,Elytone公司意识到技术创新是企业持续发展的关键。公司投入大量资金引进先进设备和研发人才,成功开发出一系列具有竞争力的电子产品。这些产品在市场上获得了良好的口碑,为公司的快速发展奠定了坚实基础。

ACL staticide公司的发展小趣事

进入XXXX年代,随着电子技术的飞速发展,Elytone公司意识到技术创新是企业持续发展的关键。公司投入大量资金引进先进设备和研发人才,成功开发出一系列具有竞争力的电子产品。这些产品在市场上获得了良好的口碑,为公司的快速发展奠定了坚实基础。

问答坊 | AI 解惑

传导干扰EMC滤波电路设计 EMI/EMC--原理与应对详解(八)

根据EMC的定义或原理,EMC滤波电路不但要抑制本电子设备产生的电磁干扰,同时也要对外来的电磁干扰信号进行抑制,因此,图14所示的EMC滤波电路还不是十分完美的。为了提高EMC滤波电路对外来电磁干扰信号的抑制能力,最好在输入端也安装一个低通滤波 ...…

查看全部问答>

RF 技术支持工程师

• Recommend suitable product offerings/solution including marketing promotions. • Generate new business opportunities for EMG while satisfying/fulfilling customer’s needs. • Take ownership of customer technica ...…

查看全部问答>

ScrollWindowEx 失败

if (IsWindow(hWnd)) {    int re = ScrollWindowEx(hWnd,nXMoved,nYMoved,NULL,NULL,NULL,NULL,SW_INVALIDATE | SW_ERASE);    if (re == ERROR)    {         DWORD error = ...…

查看全部问答>

想买块arm9开发板

本人刚刚接触基于linux的嵌入式开发,为了深入学习,想买一块arm9开发板。     但苦于旁边都没有这方向的朋友,对于开发板的选购无从下手。貌似网上说买块2410或2440就可以了,但好像生产这两种开发板的厂家也很多,且各种板还分很多型 ...…

查看全部问答>

做过“博创杯”嵌入式设计大赛的大虾,指教下~~~

    小弟第一次做这个比赛,还不是太懂     据说,这个比赛是自己编程序,然后下载到开发平台的芯片上运行,如果开发工具用IAR EWARM     那各种接口的驱动程序,要不要自己写?     自己写的代码是不 ...…

查看全部问答>

求助!!!8051

我想把字母\'G\'傳送去終端機,發現8051和MAX232的Port11(TXD)没信号到,不知道程式那錯了!?請各位幫幫忙看看那錯了??謝謝各位的幫忙!! 程式如下:     ORG 00H     MOV SP,#1FH AGAIN:        & ...…

查看全部问答>

CCS 5.1打开问题

请问各位高手帮我解决一下这个问题:我打开CCS 5.1.1.00031时总出现log文件出错,开始安装时还能用,不知道什么时候就不能用了(用得还不够90天),重装或系统恢复都不行!!急着学launchpad去比赛,软件又不能用!请问高手们有什么解决办法呢?? ...…

查看全部问答>

传感器销售工程师招聘

深圳铭之光电子招聘 : 招聘销售工程师数名。要求:理工科背景,在传感器、GPS等行业做过销售。有意者请发简历至hr@sinocomopto.com 深圳铭之光电子招聘 : 招聘网页设计/制作/美工一名 要求:计算计应用、艺术设计等相关专业毕业,有工作经验优 ...…

查看全部问答>

接下来的4周时间,estore上launchpad仅售$6.99

TI在从8月19日以来的四周,每周周一的launchpad仅售6.99刀, launchpad涨价到10个美金后很久没有这样的好价位了。 这次是TI组织的Back To School Sale活动,为大学生提供开发平台。 特别注意要输入优惠码:LP_BTS 消息来自TI工程师社区: …

查看全部问答>