历史上的今天
今天是: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;
}
史海拾趣
|
传导干扰EMC滤波电路设计 EMI/EMC--原理与应对详解(八) 根据EMC的定义或原理,EMC滤波电路不但要抑制本电子设备产生的电磁干扰,同时也要对外来的电磁干扰信号进行抑制,因此,图14所示的EMC滤波电路还不是十分完美的。为了提高EMC滤波电路对外来电磁干扰信号的抑制能力,最好在输入端也安装一个低通滤波 ...… 查看全部问答> |
|
• 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 ...… 查看全部问答> |
|
if (IsWindow(hWnd)) { int re = ScrollWindowEx(hWnd,nXMoved,nYMoved,NULL,NULL,NULL,NULL,SW_INVALIDATE | SW_ERASE); if (re == ERROR) { DWORD error = ...… 查看全部问答> |
|
本人刚刚接触基于linux的嵌入式开发,为了深入学习,想买一块arm9开发板。 但苦于旁边都没有这方向的朋友,对于开发板的选购无从下手。貌似网上说买块2410或2440就可以了,但好像生产这两种开发板的厂家也很多,且各种板还分很多型 ...… 查看全部问答> |
|
小弟第一次做这个比赛,还不是太懂 据说,这个比赛是自己编程序,然后下载到开发平台的芯片上运行,如果开发工具用IAR EWARM 那各种接口的驱动程序,要不要自己写? 自己写的代码是不 ...… 查看全部问答> |
|
请问各位高手帮我解决一下这个问题:我打开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工程师社区: … 查看全部问答> |




