標(biāo)題:
stm32 iic,硬件iic主模式使用查詢模式,從模式使用中斷模式,已驗(yàn)證能正常收發(fā)數(shù)據(jù)
[打印本頁]
作者:
zxp123456
時(shí)間:
2019-7-26 10:27
標(biāo)題:
stm32 iic,硬件iic主模式使用查詢模式,從模式使用中斷模式,已驗(yàn)證能正常收發(fā)數(shù)據(jù)
int main(void)
{
u8 i = 0;
u16 temp = 0;
RCC_Configuration(); //時(shí)鐘配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
IIC_Configuration1();
I2C_Configuration2();
gpio_init();
// TIM2_Int_Init(719,999); // 配置定時(shí)器TIM1每10ms產(chǎn)生中斷,定時(shí)器計(jì)數(shù)頻率為1kHz=72M/72000。
//GPIO_SetBits(GPIOB,GPIO_Pin_0);
while(1)
{
temp++;
I2C_Master_BufferWrite(I2C1, I2C1_Buffer_Tx, 8, 0x20);
__nop();
for(i=0;i<8;i++)
{
I2C1_Buffer_Tx[i] = 0;
}
I2C_Master_BufferRead( I2C1, I2C1_Buffer_Tx,8, 0x20);
for(i=0;i<8;i++)
{
I2C1_Buffer_Tx[i] = temp+i;
}
}
}
#include "i2c1.h"
#include "delay.h"
#include"stm32f10x.h"
u8 Tx_Idx1 = 0;
u8 Rx_Idx1 = 0;
u8 I2C1_Buffer_Tx[8] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
u8 I2C1_Buffer_Rx[8] = {0};
u8 ReadingFlag = 0;
/*IIC1從機(jī)模式*/
void gpio_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//配置IO接口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_5; //READY1/READY2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //Waring
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//void I2C_Configuration1(void)
//{
// GPIO_InitTypeDef GPIO_InitStructure;
// I2C_InitTypeDef I2C_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
// //使能時(shí)鐘
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
//
// //配置IO接口
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //PB6/PB7
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //
// GPIO_Init(GPIOB, &GPIO_InitStructure);
//
// I2C_InitStructure.I2C_ClockSpeed=400000; //I2C數(shù)據(jù)傳輸速度
// I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; //I2C模式設(shè)置 ,I2C模式,SMBus主模式,SMBus從模式
// I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
// I2C_InitStructure.I2C_OwnAddress1 =0x20; //設(shè)備地址
// I2C_InitStructure.I2C_Ack =I2C_Ack_Enable;
// I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit ; //尋址模式,7bit或者10bit
// I2C_Init(I2C1,&I2C_InitStructure);
// NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;//事件中斷
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
// NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;//錯(cuò)誤中斷
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
// I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT |I2C_IT_ERR, ENABLE);
// I2C_Cmd(I2C1, ENABLE);
//
//}
//void I2C1_EV_IRQHandler(void) //I2C1事件中斷響應(yīng)函數(shù) ,主要完成對(duì)上位機(jī)指令的響應(yīng)
//{
// switch(I2C_GetLastEvent(I2C1))
// {
// case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
// {
//// I2C_GenerateSTOP(I2C2, DISABLE);
// I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
// I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
// break;
// }
// case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
// I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx1++]);
// break;
// case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: //EV3
// I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx1++]);
// break;
// case I2C_EVENT_SLAVE_BYTE_RECEIVED:
// I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
// I2C1_Buffer_Rx[Rx_Idx1++] = I2C_ReceiveData(I2C1);
// break;
// case I2C_EVENT_SLAVE_STOP_DETECTED:
// I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
// I2C_GenerateSTOP(I2C1, DISABLE);
// Rx_Idx1=0;
// //i2c_event = EVENT_OPCOD_NOTYET_READ;
// break;
// default:
// break;
// }
//}
//
//void I2C1_ER_IRQHandler(void) //I2C2錯(cuò)誤事件中斷響應(yīng)函數(shù)
//{
// if (I2C_GetITStatus(I2C1, I2C_IT_AF))
// {
// I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
//
// Tx_Idx1 = 0;
// //i2c_event = EVENT_OPCOD_NOTYET_READ;
//
// }
//
// if (I2C_GetITStatus(I2C1, I2C_IT_BERR))
// {
// I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
// }
//}
/*IIC1主機(jī)模式*/
#define DEVICE_ADDRESS 0x20
/*******************************************************************************
* Function Name : IIC_Configuration
* Description : 初始化IIC2外設(shè)
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void IIC_Configuration1(void)
{
//先定義結(jié)構(gòu)體
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
//要開了對(duì)應(yīng)的gpio的時(shí)鐘還有其他的外設(shè)的時(shí)鐘,然后你配置寄存器才可以,軟件仿真里面開時(shí)鐘先后沒有影響,但是實(shí)物里面,要先開時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能APB2外設(shè)的GPIOB的時(shí)鐘,I2C2是PB_10 SCL,PB_11 SDA上面的復(fù)用
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 ,ENABLE); //開啟時(shí)鐘
//要對(duì)上面定義的兩個(gè)結(jié)構(gòu)體進(jìn)行定義,首先PB要定義為復(fù)用的才行,而且是開漏復(fù)用
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //選擇PB_6是SCL引腳
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管腳頻率為50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //輸出模式為復(fù)用開漏輸出
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化GPIOB寄存器
//配置I2C
I2C_DeInit(I2C1);//I2C1寄存器復(fù)位
I2C_InitStructure.I2C_ClockSpeed = 400000; /*I2C的時(shí)鐘頻率100kHz ,不是I2C輸入時(shí)鐘的頻率*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /*設(shè)置CCR寄存器的,占空比 快速模式下0:Tlow/Thigh = 2;1:Tlow/Thigh = 16/9 */
I2C_InitStructure.I2C_OwnAddress1 = 0x20 ; /*這句話說的是stm32作為從機(jī)的時(shí)候它的地址,如果沒有做從機(jī)不用理會(huì)這個(gè)值*/
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; /*應(yīng)答使能 */
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* */
I2C_Init(I2C1,&I2C_InitStructure);
//使能I2C
I2C_Cmd(I2C1, ENABLE);
}
/*******************************************************************************
主機(jī)發(fā)送數(shù)據(jù)的流程:
1) 主機(jī)在檢測(cè)到總線為“空閑狀態(tài)”(即 SDA、SCL 線均為高電平)時(shí),發(fā)送一個(gè)啟動(dòng)信號(hào)“S”,開始一次通信的開始
2) 主機(jī)接著發(fā)送一個(gè)命令字節(jié)。該字節(jié)由 7 位的外圍器件地址和 1 位讀寫控制位 R/W組成(此時(shí) R/W=0)
3) 相對(duì)應(yīng)的從機(jī)收到命令字節(jié)后向主機(jī)回饋應(yīng)答信號(hào) ACK(ACK=0)
4) 主機(jī)收到從機(jī)的應(yīng)答信號(hào)后開始發(fā)送第一個(gè)字節(jié)的數(shù)據(jù)
5) 從機(jī)收到數(shù)據(jù)后返回一個(gè)應(yīng)答信號(hào) ACK
6) 主機(jī)收到應(yīng)答信號(hào)后再發(fā)送下一個(gè)數(shù)據(jù)字節(jié)
7) 當(dāng)主機(jī)發(fā)送最后一個(gè)數(shù)據(jù)字節(jié)并收到從機(jī)的 ACK 后,通過向從機(jī)發(fā)送一個(gè)停止信號(hào)P結(jié)束本次通信并釋放總線。從機(jī)收到P信號(hào)后也退出與主機(jī)之間的通信。
主機(jī)發(fā)送數(shù)據(jù)的程序
*******************************************************************************//**/
uint8_t I2C_Master_BufferWrite(I2C_TypeDef * I2Cx, uint8_t* pBuffer, uint32_t NumByteToWrite, uint8_t SlaveAddress)
{
if(NumByteToWrite==0)
return 1;
/* 1.開始,發(fā)送一個(gè)s,也就是起始信號(hào)*/
I2C_GenerateSTART(I2Cx, ENABLE);
///判斷EV5,看下函數(shù)定義可以發(fā)現(xiàn),該事件是SB=1,MSL=1,BUSY=1 意思是起始條件已經(jīng)發(fā)送了,然后是主模式,總線在通訊
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* 2.設(shè)備地址·/寫 */
I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* 3.連續(xù)寫數(shù)據(jù) */
while(NumByteToWrite--)
{
I2C_SendData(I2Cx, *pBuffer);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
pBuffer++;
}
/* 4.停止 */
I2C_GenerateSTOP(I2Cx, ENABLE);//產(chǎn)生停止信號(hào)P,結(jié)束本次通訊釋放總線
while ((I2Cx->CR1&0x200) == 0x200);//完成當(dāng)前字節(jié)傳輸后釋放 SCL 和 SDA 線
return 0;
}
/*******************************************************************************
IIC主機(jī)讀取數(shù)據(jù)的具體流程:
1) 主機(jī)發(fā)送啟動(dòng)信號(hào)后,接著發(fā)送命令字節(jié)(其中 R/W=1)
2) 對(duì)應(yīng)的從機(jī)收到地址字節(jié)后,返回一個(gè)應(yīng)答信號(hào)并向主機(jī)發(fā)送數(shù)據(jù)
3) 主機(jī)收到數(shù)據(jù)后向從機(jī)反饋一個(gè)應(yīng)答信號(hào)
4) 從機(jī)收到應(yīng)答信號(hào)后再向主機(jī)發(fā)送下一個(gè)數(shù)據(jù)
5) 當(dāng)主機(jī)完成接收數(shù)據(jù)后,向從機(jī)發(fā)送一個(gè)“非應(yīng)答信號(hào)(ACK=1)”,從機(jī)收到ACK=1 的非應(yīng)答信號(hào)后便停止發(fā)送
6) 主機(jī)發(fā)送非應(yīng)答信號(hào)后,再發(fā)送一個(gè)停止信號(hào),釋放總線結(jié)束通信.
*******************************************************************************/
uint8_t I2C_Master_BufferRead(I2C_TypeDef * I2Cx, uint8_t* pBuffer, uint32_t NumByteToRead, uint8_t SlaveAddress)
{
if(NumByteToRead==0)
return 1;
///等待總線空閑
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
///在接受一個(gè)字節(jié)(匹配地址或數(shù)據(jù))之后返回應(yīng)答
I2C_AcknowledgeConfig(I2Cx, ENABLE);
/* 1.開始 */
I2C_GenerateSTART(I2Cx, ENABLE);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* 2.設(shè)備地址·/寫 */
I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
/* 3.開始*/
I2C_GenerateSTART(I2Cx, ENABLE);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* 4.設(shè)備地址·/讀 */
I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* 5.連續(xù)寫數(shù)據(jù) */
while (NumByteToRead)
{
if(NumByteToRead==1)
{
I2C_AcknowledgeConfig(I2Cx, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);//6.停止,非應(yīng)答
}
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
*pBuffer++ = I2C_ReceiveData(I2Cx);
NumByteToRead--;
}
I2C_AcknowledgeConfig(I2Cx, ENABLE);
return 0;
}
復(fù)制代碼
全部資料51hei下載地址:
stm32 IIC2.7z
(190.48 KB, 下載次數(shù): 44)
2019-7-26 22:46 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
月之光芒
時(shí)間:
2019-7-31 10:32
下下來用了下不太行啊兄弟
作者:
jayzay008
時(shí)間:
2019-10-11 15:55
試一下行不行
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1