初中生
最后登录1970-1-1
在线时间 小时
注册时间2017-10-16
|
楼主 |
发表于 2018-3-27 22:05:55
|
显示全部楼层
这个可以用。
#include "./iic/bsp_iic.h"
#include "bsp_usart.h"
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*I2C1 and I2C2 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/*Configure I2C1 pins: SCL and SDA ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_6 | GPIO_Pin_7; //选择待设置的GPIO管脚 PB6 scl pb7 sda
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; //管脚速率50MHz
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_OD; //复用开漏输出
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
/*
void I2C_Master_Init(void)
{
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode= I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle= I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1= I2C1_SLAVE_ADDRESS7;
I2C_InitStructure.I2C_Ack= I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress= I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed= ClockSpeed;
I2C_Init(I2C1,&I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
*/
void I2C_Slave_Init(void)
{
I2C_InitTypeDef I2C_InitStructure;
/*I2C2 configuration ------------------------------------------------------*/
//模式
I2C_InitStructure.I2C_Mode =I2C_Mode_I2C;
//在快速模式下有意义
I2C_InitStructure.I2C_DutyCycle= I2C_DutyCycle_2;
//地址
I2C_InitStructure.I2C_OwnAddress1= I2C1_SLAVE_ADDRESS7;
//使能答应
I2C_InitStructure.I2C_Ack= I2C_Ack_Enable;
//7位
I2C_InitStructure.I2C_AcknowledgedAddress= I2C_AcknowledgedAddress_7bit;
//时钟速率
I2C_InitStructure.I2C_ClockSpeed= ClockSpeed;
I2C_Init(I2C1,&I2C_InitStructure);
// I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_ITConfig(I2C1,I2C_IT_ERR | I2C_IT_EVT| I2C_IT_BUF,ENABLE);
I2C_Cmd(I2C1, ENABLE);
}
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void I2C_Mode_Init(void)
{
I2C_GPIO_Config();
I2C_Slave_Init();
NVIC_Config();
}
//Clear ADDR by reading SR1, then SR2
void I2C_clear_ADDR(I2C_TypeDef* I2Cx)
{
I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR);
((void)(I2Cx->SR2));
}
//Clear STOPF by reading SR1, then writing CR1
void I2C_clear_STOPF(I2C_TypeDef* I2Cx)
{
I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF);
I2C_Cmd(I2Cx, ENABLE);
}
uint8_t data = 0;
void I2C1_EV_IRQHandler(void) {
// GPIO_SetBits(GPIOD, GREEN); //Show that we got here
// KV1=0;
//Clear AF from slave-transmission end
if(I2C_GetITStatus(I2C1, I2C_IT_AF)) {
I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
}
//Big state machine response, since doesn't actually keep state
switch(I2C_GetLastEvent(I2C1)) {
//SLAVE
//Receive
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //EV1 可以到这
printf("dao");
I2C_clear_ADDR(I2C1);
break;
case I2C_EVENT_SLAVE_BYTE_RECEIVED: //EV2
//Read it, so no one is waiting, clears BTF if necessary
data = I2C_ReceiveData(I2C1);
// LED1= !(data & 0x01);
// LED2= !(data & 0x02);
// LED3= !(data & 0x04);
// LED4= !(data & 0x08);
//Do something with it
if(I2C_GetFlagStatus(I2C1, I2C_FLAG_DUALF)) {//Secondary Receive
} else if(I2C_GetFlagStatus(I2C1, I2C_FLAG_GENCALL)) {//General Receive
} else {//Normal
}
break;
case I2C_EVENT_SLAVE_STOP_DETECTED: //End of receive, EV4
I2C_clear_STOPF(I2C1);
break;
//Transmit
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: //EV1
I2C_clear_ADDR(I2C1);
printf("dao1");
//Send first byte
I2C_SendData(I2C1, 0x26); //这个不能少,少了数据会发送错误
break;
case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: //EV3
//Determine what you want to send
//data = 5;
if(I2C_GetFlagStatus(I2C1, I2C_FLAG_DUALF)) {//Secondary Transmit
} else if(I2C_GetFlagStatus(I2C1, I2C_FLAG_GENCALL)) {//General Transmit
} else {//Normal
}
//Read flag and write next byte to clear BTF if present
I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF);
I2C_SendData(I2C1,0x26);
break;
case I2C_EVENT_SLAVE_ACK_FAILURE://End of transmission EV3_2
//TODO: Doesn't seem to be getting reached, so just
//check at top-level
I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
break;
//Alternative Cases for address match
case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: //EV1
break;
case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: //EV1
break;
case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: //EV1
break;
//MASTER
case I2C_EVENT_MASTER_MODE_SELECT: //EV5, just sent start bit
break;
//Receive
case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: //EV6, just sent addr
break;
case I2C_EVENT_MASTER_BYTE_RECEIVED: //EV7
break;
//Transmit
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: //EV6, just sent addr
break;
case I2C_EVENT_MASTER_BYTE_TRANSMITTING: //EV8, about to send data
break;
case I2C_EVENT_MASTER_BYTE_TRANSMITTED: //EV8_2, just sent data
break;
//Alternative addressing stuff, not going to worry about
case I2C_EVENT_MASTER_MODE_ADDRESS10: //EV9
break;
default:
//How the FUCK did you get here?
//I should probably raise some error, but fuck it,
//it's late
break;
}
}
void I2C1_ER_IRQHandler(void) {
// GPIO_SetBits(GPIOD, RED);
// LED3=0;
//Can't use nice switch statement, because no fxn available
if(I2C_GetITStatus(I2C1, I2C_IT_SMBALERT)) {
} else if(I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT)) {
} else if(I2C_GetITStatus(I2C1, I2C_IT_PECERR)) {
} else if(I2C_GetITStatus(I2C1, I2C_IT_OVR)) {
//Overrun
//CLK stretch disabled and receiving
//DR has not been read, b4 next byte comes in
//effect: lose byte
//should:clear RxNE and transmitter should retransmit
//Underrun
//CLK stretch disabled and I2C transmitting
//haven't updated DR since new clock
//effect: same byte resent
//should: make sure discarded, and write next
} else if(I2C_GetITStatus(I2C1, I2C_IT_AF)) {
//Detected NACK
//Transmitter must reset com
//Slave: lines released
//Master: Stop or repeated Start must must be generated
//Master = MSL bit
//Fixup
I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
} else if(I2C_GetITStatus(I2C1, I2C_IT_ARLO)) {
//Arbitration Lost
//Goes to slave mode, but can't ack slave address in same transfer
//Can after repeat Start though
} else if(I2C_GetITStatus(I2C1, I2C_IT_BERR)) {
//Bus Error
//In slave mode: data discarded, lines released, acts like restart
//In master mode: current transmission continues
}
}
//void I2C1_EV_IRQHandler(void)
//{
//// printf("Ylq"); //到这
////
//// //check EV1 and clear it
//// while(!I2C_CheckEvent(I2C1,I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED));
//// //send data
//// printf("a");
//// I2C_SendData(I2C1,0x13);
//// printf("a");
//// while(!I2C_CheckEvent(I2C1,I2C_EVENT_SLAVE_BYTE_TRANSMITTED));
//// //clear EV3
//// I2C_SendData(I2C1,0);
//// printf("b");
//// while(!I2C_CheckEvent(I2C1,I2C_EVENT_SLAVE_ACK_FAILURE));
//// //clear i2c af flag
//// I2C_ClearFlag(I2C1,I2C_FLAG_AF);
//// printf("c");
// //printf("8");
// switch(I2C_GetLastEvent(I2C1))
// {
// case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
// {
// //i2c is ready
// I2C_GenerateSTOP(I2C1, DISABLE);
// printf("地址匹配");
// break;
// }
//
// case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: //发送数据
// {
// I2C_SendData(I2C1,0x13);
// printf("发送数据");
// break;
// }
// // 发送数据,要发送,不然锁死,不过 master 没收到
// case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
// {
// I2C_SendData(I2C1,0x13);
// printf("发送完");
// break;
// }
// case I2C_EVENT_SLAVE_STOP_DETECTED: //收到结束条件
// {
// I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
// printf("10");
// I2C_GenerateSTOP(I2C1, ENABLE);
// printf("12");
// break;
// }
// case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
// {
// printf("4");
// break;
// }
// case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:
// { printf("5");
// break;
// }
// case I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED:
// {
// printf("6");
// break;
// }
// default: {break;}
// }
//}
|
|