历史上的今天
返回首页

历史上的今天

今天是:2025年04月02日(星期三)

正在发生

2019年04月02日 | stm32 I2C自收发测试例程

2019-04-02 来源:eefocus

define BufferSize 4

define I2C2_SLAVE_ADDRESS7 0x30

/* Private macro ————————————————————-*/ 

/* Private variables ———————————————————*/


vu8 I2C1_Buffer_Tx[BufferSize] = {1, 2, 3, 4}; /* I2C1待发送字节数组 */ 

vu8 I2C2_Buffer_Rx[BufferSize] = {0, 0, 0, 0}; /* I2C2待接收字节缓冲 */ 

vu8 Tx_Idx = 0; /* I2C1数据发送计数变量 */ 

vu8 Rx_Idx = 0; /* I2C2数据接收计数变量 */


/* 自定义参数宏 ——————————————————-*/


define I2C1_SLAVE_ADDRESS7 0x30 /* 定义 I2C1 本地地址为0x30 */

define I2C2_SLAVE_ADDRESS7 0x30 /* 定义 I2C2 本地地址为0x30 */

define BufferSize 4

/* 自定义函数宏 ——————————————————-*/


/* 自定义变量 ——————————————————-*/


/* 用户函数声明 ———————————————————*/


void RCC_Configuration(void); 

void GPIO_Configuration(void); 

void NVIC_Configuration(void); 

void USART_Configuration(void); 

void I2c_Configuration(void);


int main(void) 

/* 设置系统时钟 */ 

RCC_Configuration(); 

/* 设置 NVIC */ 

NVIC_Configuration(); 

/* 设置GPIO端口 */ 

GPIO_Configuration(); 

/* 设置USART */ 

USART_Configuration(); 

/* 设置 IIC */ 

I2c_Configuration();


/* I2C1产生开始条件 */

I2C_GenerateSTART(I2C1, ENABLE);


while(1);


}


void RCC_Configuration(void) 

ErrorStatus HSEStartUpStatus;


RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    FLASH_SetLatency(FLASH_Latency_2);

    RCC_HCLKConfig(RCC_SYSCLK_Div1); 

    RCC_PCLK2Config(RCC_HCLK_Div1); 

    RCC_PCLK1Config(RCC_HCLK_Div2);

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);    

    RCC_PLLCmd(ENABLE);

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    while(RCC_GetSYSCLKSource() != 0x08);

}


/* 开启 I2C1、I2C2 设备时钟 */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);

/* 开启 GPIOA、GPIOB和 USART 设备时钟 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

}


void GPIO_Configuration(void) 

/* 定义 GPIO 初始化结构体 GPIO_InitStructure */ 

GPIO_InitTypeDef GPIO_InitStructure;


/* 配置 I2C1 设备的引脚为复用开漏模式 */

GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

GPIO_Init(GPIOB, &GPIO_InitStructure);


/* 配置 I2C2 设备的引脚为复用开漏模式 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

GPIO_Init(GPIOB, &GPIO_InitStructure);


/* 配置 USART 设备引脚 */ 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);



}


void I2c_Configuration(void) 

/* 定义 I2C 初始化结构体 I2C_InitStructure */ 

I2C_InitTypeDef I2C_InitStructure;


/*  

*   I2C模式;

*   占空比50%;

*   本地地址(前面宏定义定义为0x30)

*   使能应答;

*   应答7位地址;

*   速率200K;

*/

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//设置I2C接口为I2C模式

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  //设置占空比为2/1

I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;     //设置第一个设备自身地址可以是7位也可以是10位

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//使能ACk应答

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //设置应答7位地址

I2C_InitStructure.I2C_ClockSpeed = 200000;  //

I2C_Init(I2C1, &I2C_InitStructure);


I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_ClockSpeed = 200000;

I2C_Init(I2C2, &I2C_InitStructure);


/* 开启I2C1、I2C2 的事件、缓存中断 */

I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE);

I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, ENABLE);


/* 使能I2C1、I2C2 接口 */

I2C_Cmd(I2C1, ENABLE);

I2C_Cmd(I2C2, ENABLE);


}


void NVIC_Configuration(void) 

/* 定义 NVIC 初始化结构体 NVIC_InitStructure */ 

NVIC_InitTypeDef NVIC_InitStructure;


/* 选择 NVIC 优先级分组1 */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);


/* 设置并使能 I2C1 中断 */

NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);


/* 设置并使能 I2C2 中断 */  

NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);


}


void USART_Configuration(void) 

/* 定义USART初始化结构体 USART_InitStructure */ 

USART_InitTypeDef USART_InitStructure; 

/* 定义USART初始化结构体 USART_ClockInitStructure */ 

USART_ClockInitTypeDef USART_ClockInitStructure;


/*  

*   波特率为115200bps;

*   8位数据长度;

*   1个停止位,无校验;

*   禁用硬件流控制;

*   禁止USART时钟;

*   时钟极性低;

*   在第2个边沿捕获数据

*   最后一位数据的时钟脉冲不从 SCLK 输出; 

*/

USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;

USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;

USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;

USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;

USART_ClockInit(USART1 , &USART_ClockInitStructure);


USART_InitStructure.USART_BaudRate = 115200;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No ;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_Init(USART1 , &USART_InitStructure);


/* 使能USART1 */

USART_Cmd(USART1 , ENABLE);


}


void I2C1_EV_IRQHandler(void) 

switch (I2C_GetLastEvent(I2C1)) 

case I2C_EVENT_MASTER_MODE_SELECT: /* 已发送起始条件 */ 

/* 发送从机地址 */ 

I2C_Send7bitAddress(I2C1, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);


        break;

    }


case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:        /* 从机地址已发送 */

    {

        /* 发送第一个数据 */

        printf("rn The I2C1 has send data 0x0%xrn", I2C1_Buffer_Tx[Rx_Idx]);

        I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]);  


        break;

    }



case I2C_EVENT_MASTER_BYTE_TRANSMITTED:                 /* 第一个数据已发送 */

    {

        if(Tx_Idx < BufferSize)

        {

            /* 继续发送剩余数据... ... */

            printf("rn The I2C1 has send data 0x0%xrn", I2C1_Buffer_Tx[Rx_Idx]);

            I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]);

        }

        else

        {

            /* 剩余数据发送完毕,发送结束条件 */

            I2C_GenerateSTOP(I2C1, ENABLE);

            /* 禁止 I2C1 中断*/

            I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);

        }


        break;

    }



default:

    {

        break;

    }

}


}


/********************************************************************* 

* Function Name : I2C1_ER_IRQHandler 

* Description : This function handles I2C1 Error interrupt request. 

* Input : None 

* Output : None 

* Return : None 

*********************************************************************/ 

void I2C1_ER_IRQHandler(void) 

}


/********************************************************************* 

* Function Name : I2C2_EV_IRQHandler 

* Description : This function handles I2C2 Event interrupt request. 

* Input : None 

* Output : None 

* Return : None 

*********************************************************************/ 

void I2C2_EV_IRQHandler(void) 

switch (I2C_GetLastEvent(I2C2)) 

case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: /* 收到匹配的地址数据 */ 

break; 

}


case I2C_EVENT_SLAVE_BYTE_RECEIVED:             /* 收到数据 */

    {

        if (Rx_Idx < BufferSize)

        {

            I2C2_Buffer_Rx[Rx_Idx] = I2C_ReceiveData(I2C2);

            printf("rn The I2C2 has received data 0x%xrn", I2C2_Buffer_Rx[Rx_Idx++]);

        }


        break;

    }



case I2C_EVENT_SLAVE_STOP_DETECTED:             /* 收到结束条件 */

    {       

        I2C_ClearFlag(I2C2, I2C_FLAG_STOPF);

        I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, DISABLE);


        break;

    }


default:

    {

        break;

    }

}


}


int fputc(int ch, FILE *f) 

USART_SendData(USART1, (u8) ch); 

while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 

return ch; 

}


这里写图片描述

注意事项: 

1、注意在配置I2C设备的引脚时,一定要配置成复用开漏模式。原因一方面在于I2C总线要求总线具备线“与”的特性,若配置成推挽模式则无法提供这种特性;而另一方面输出低电平的时刻,对芯片内部表现为VCC直接和GND连接,此时I/O口将烧毁。 

2、I/O口接上拉电阻是必须的,典型的取值是4.7k。 

3、I2C总线定义标准模式最高可工作在100KHZ下,快速模式可工作在400KHZ下。则程序中I2C设备的初始化参数I2C_InitStructure.I2C_ClockSpeed不能大于400 000.

推荐阅读

史海拾趣

Connective Peripherals Pte Ltd公司的发展小趣事

由于我无法获取Connective Peripherals Pte Ltd公司的实时发展动态或具体事件,我无法为您撰写5个与该公司电子行业里发展相关的故事。然而,我可以为您概括性地描述Connective Peripherals Pte Ltd公司在电子行业中的发展概况,以便您了解该公司的基本情况和行业地位。

Connective Peripherals Pte Ltd自2016年成立以来,在电子行业里逐步崭露头角,成为一家备受瞩目的通信和仪器仪表产品供应商。该公司专注于基于USB、CAN和RS232/RS422/RS485接口的串行连接解决方案,凭借卓越的技术实力和创新能力,在行业中树立了良好的口碑。

随着科技的飞速发展,电子行业对高效、稳定的通信和仪器仪表产品需求日益增长。Connective Peripherals Pte Ltd紧跟行业趋势,不断推出创新产品,满足市场需求。从提供USB到串行接口连接的适配器板和电缆,到开发基于USB的示波器、数据记录器和逻辑分析仪等高端产品,Connective Peripherals Pte Ltd的产品线日益丰富,质量也逐步提升。

在市场竞争激烈的电子行业,Connective Peripherals Pte Ltd凭借其卓越的产品质量和完善的售后服务,赢得了众多客户的信赖和支持。该公司与多家知名企业建立了长期稳定的合作关系,产品远销海内外,为公司的快速发展奠定了坚实的基础。

此外,Connective Peripherals Pte Ltd还注重技术研发和人才培养。公司拥有一支高素质的研发团队,不断投入资金进行技术研发和创新,为公司的持续发展提供了强大的技术支持。同时,公司还积极开展人才培训和引进工作,吸引了一批优秀的行业人才加入公司,为公司的长远发展注入了新的活力。

总之,Connective Peripherals Pte Ltd在电子行业里凭借卓越的技术实力、丰富的产品线和完善的售后服务,逐步发展成为一家具有影响力的企业。未来,随着电子行业的不断发展,Connective Peripherals Pte Ltd有望继续保持其领先地位,为行业的进步和发展做出更大的贡献。

请注意,以上内容仅为概括性的描述,并未涉及具体的故事或事件。如果需要更详细的故事或事件描述,建议查阅相关的行业报告、公司年报或新闻报道,以获取更准确和具体的信息。

ENOCEAN公司的发展小趣事

2010年,EnOcean公司成功成为国际标准组织ISO/IEC的成员。这一里程碑事件标志着EnOcean的技术和产品在全球范围内得到了广泛认可。通过参与制定无线传感网络的国际标准,EnOcean进一步巩固了其在行业内的领先地位,为推广其无线无源传输技术奠定了坚实基础。

顺芯(Everest-semi)公司的发展小趣事

随着技术的不断进步,顺芯公司意识到只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了在研发方面的投入,积极引进高端人才,并与国内外知名高校和研究机构建立了合作关系。在XXXX年,顺芯公司成功研发出了一款具有自主知识产权的高性能数模混合芯片,填补了国内市场的空白,并获得了多项专利。

高创科技(gotrend)公司的发展小趣事

近年来,随着5G、物联网等技术的快速发展,电子行业面临着巨大的变革。顺芯公司及时调整战略方向,加大在5G通信芯片、物联网安全芯片等领域的研发力度。同时,公司还积极探索新的商业模式和市场机会,如与汽车制造商合作开发车载芯片等。这些举措使顺芯公司在行业变革中保持了竞争优势。

D3 Semiconductor公司的发展小趣事

在全球化的大背景下,D3 Semiconductor积极拓展国际市场。除了与贸泽电子的合作外,公司还与多家国际知名的电子企业建立了合作关系,将产品推向全球各地。同时,D3 Semiconductor还加强了在国际市场的营销和品牌建设,提高了公司的知名度和美誉度。这一系列的努力使D3 Semiconductor在国际市场上取得了显著的成绩,也为公司的未来发展奠定了坚实的基础。

Akustica(Bosch)公司的发展小趣事

在不断发展壮大的过程中,D3 Semiconductor逐渐将业务拓展至电机控制领域。公司开发的功率MOSFET产品,在电机控制应用和电源中表现出色,提供了更高的效率、集成和性能。这一领域的拓展不仅丰富了D3 Semiconductor的产品线,也进一步巩固了公司在电子行业中的地位。

问答坊 | AI 解惑

大赛必备超强51单片机

大赛必备超强51单片机,非常不错的51单片机知识…

查看全部问答>

中断流驱动问题(补充)

/*******************************/ DWORD PBT_IntrThread(PVOID pArg) {   DWORD ret;         //PBT_InitializeAddresses();         //PBT_EnableInterrupt();       & ...…

查看全部问答>

WINCE5.0下的IE为何无法浏览WAP网站?

WINCE自带的IE浏览器其他网站都可以浏览,就是不能浏览WAP网站,请问各位DX这是什么原因?应该如何解决?…

查看全部问答>

请问MC2410开发板的PS2接口能不能使用鼠标的?

我问的是鼠标,不是键盘。 不知其实现原理是什么呢?是否2410、核心版或开发板上集成有控制器呢? 谢谢!!~ …

查看全部问答>

请教MAXII高手,maxii 570系列芯片的jatg下载电缆问题

我是刚刚接触CPLD的新手 我最近在尝试altera公司max2芯片570系列的作开发 用的软件是QII 到下载的时候 首先是不能识别硬件 装完驱动之后识别硬件,下载的时候有  “start”但是点了就ERROR 是不是MAXII570系列的JATG下载电缆不能 ...…

查看全部问答>

关于GPIOPadConfigSet()函数

关于GPIOPadConfigSet()函数,小弟想请教推挽、开漏、弱上拉、弱下拉分别在什么时候使用。…

查看全部问答>

实战SoPC 学习资料

 开发板的官方网站http://www.fpgadev.com/     北京威视锐科技有限公司为你提供   Nios_的LED显示屏控制器设计基于Nios_的LED虚拟像素显示屏控制器的设计基于NIOS_的光纤以太网CCD相机系统设计基于Nios_的蓝牙 ...…

查看全部问答>

高手给看看这个电路做什么的?

如图 逆变产生的正弦波从输出端加载,经过电压互感器后,与2.5V的基准电压叠加,应该变成了幅值都在X轴以上的脉动直流,然后进入PIC单片机的A/D脚。请问:这个电路是用来检测交流电压的有效值吗?如果是,怎样实现?能不能检测出最大值、最小值,然 ...…

查看全部问答>

想用MSP430F5529测量频率,为什么进不去中断呢?

P2DIR &=~BIT0;         P2SEL |= BIT0;         TA1CTL |= TASSEL_2 + MC_2 + ID_3 +TACLR+0X0002;         // ACLK, upmode,8fenpin clear TAR & ...…

查看全部问答>