说明
该模块音频传输使用5G通信频率,内部集成双向数据透传功能及低音量静音功能,I2C端口均采用GPIO模拟的方式
STM8代码
GPIO初始化
GPIO_Init(I2C_SCL_PORT, (GPIO_Pin_TypeDef)I2C_SCL_PINS, GPIO_MODE_OUT_OD_LOW_FAST);
GPIO_Init(I2C_SDA_PORT, (GPIO_Pin_TypeDef)I2C_SDA_PINS, GPIO_MODE_OUT_OD_LOW_FAST);
宏定义
#define I2C_SCL_PORT (GPIOB)
#define I2C_SCL_PINS (GPIO_PIN_4)
#define I2C_SDA_PORT (GPIOB)
#define I2C_SDA_PINS (GPIO_PIN_5)
#define SDA2_IN() {GPIOB->DDR&=~(1<<(5));(GPIOB->DDR|=(0<<(5)));}
#define SDA2_OUT() {GPIOB->DDR&=~(1<<(5));(GPIOB->DDR|=(1<<(5)));}
#define SCL2_IN() {GPIOB->DDR&=~(1<<(4));(GPIOB->DDR|=(0<<(4)));}
#define SCL2_OUT() {GPIOB->DDR&=~(1<<(4));(GPIOB->DDR|=(1<<(4)));}
#define READ_SDA2 GPIO_ReadInputPin(I2C_SDA_PORT,I2C_SDA_PINS)
#define READ_SCL2 GPIO_ReadInputPin(I2C_SCL_PORT,I2C_SCL_PINS)
#define __delay_us(x) delay_us(x*10)
#define i2c_Start() i2c_Restart()
#define ev01s 0x68
#define I2C_TM_SCL_HIGH 1
#define I2C_TM_SCL_LOW 3
#define I2C_TM_START_HD 24
#define I2C_TM_DATA_SU 5
#define I2C_TM_SCL_TO_DATA 5 /* SCL low to data valid */
#define I2C_TM_STOP_SU 40
#define I2C_TM_SCL_TMO 10 /* clock time out */
#define de_ack 0
#define de_non_ack 1
#define I2C_ERROR (-1)
I2C基础代码
/*
* Send (re)start condition
* - ensure data is high then issue a start condition
* - see also i2c_Start() macro
*/
void
i2c_Restart(void)
{
SCL_HIGH(); /* ensure clock is low */
SDA_HIGH(); /* ensure data is high */
__delay_us(10);
SCL_LOW(); /* ensure clock is low */
SDA_HIGH(); /* ensure data is high */
__delay_us(I2C_TM_DATA_SU);
SCL_HIGH(); /* clock pulse high */
__delay_us(I2C_TM_SCL_HIGH);
SDA_LOW(); /* the high->low transition */
__delay_us(I2C_TM_START_HD);
return;
}
/*
* Send stop condition
* - data low-high while clock high
*/
void
i2c_Stop(void)
{
SCL_LOW();
SDA_LOW(); /* ensure data is low first */
__delay_us(I2C_TM_DATA_SU);
SCL_HIGH(); /* float clock high */
__delay_us(I2C_TM_STOP_SU);
SDA_HIGH(); /* the low->high data transistion */
return;
}
/*
* Check for an acknowledge
* - returns ack or ~ack, or ERROR if a bus error
*/
signed char
i2c_ReadAcknowledge(void)
{
unsigned char ack;
SCL_LOW(); /* make clock is low */
__delay_us(I2C_TM_SCL_TO_DATA); /* SCL low to data out valid */
SDA_HIGH();
if(fg_i2c_ev01s)
{
__delay_us(50);//50
}
else
{
__delay_us(5);
}
SCL_HIGH();
__delay_us(I2C_TM_DATA_SU);
SDA2_IN(); //SDA设置为输入
ack = READ_SDA2; /* read the acknowledge */
SDA2_OUT();
return ack;
}
/*
* Send a byte to the slave
* - returns true on error
*/
unsigned char
i2c_SendByte(unsigned char byte)
{
signed char i;
for(i=7; i>=0; i--)
{
SCL_LOW(); /* drive clock low */
if ((byte>>i)&0x01)
{ /* bit to send */
SDA_HIGH();
}
else
{
SDA_LOW();
}
__delay_us(3);
SCL_HIGH();
__delay_us(I2C_TM_SCL_HIGH); /* clock high time */
}
return FALSE;
}
/*
* wait for the clock line to be released by slow slaves
* - returns TRUE if SCL was not released after the
* time out period.
* - returns FALSE if and when SCL released
*/
unsigned char
i2c_WaitForSCL(void)
{
SCL2_IN();
/* SCL_DIR should be input here */
if(!READ_SCL2)
{
__delay_us(I2C_TM_SCL_TMO);
/* if the clock is still low -> bus error */
if(!READ_SCL2){
SCL2_OUT();
return TRUE;
}
}
SCL2_OUT();
return FALSE;
}
/*
* Read a byte from the slave
* - returns the byte, or I2C_ERROR if a bus error
*/
int
i2c_ReadByte(void)
{
unsigned char i;
unsigned char byte = 0;
unsigned char x;
SCL_LOW();
if(fg_i2c_ev01s)
{
__delay_us(50);//50
}
for(i=0; i<8; i++)
{
SCL_LOW(); /* drive clock low */
__delay_us(1); /* min clock low period */
SDA_HIGH(); /* release data line */
__delay_us(1);
SCL_HIGH(); /* float clock high */
__delay_us(1); /* min clock low period */
if(i2c_WaitForSCL())
return I2C_ERROR;
__delay_us(1);
byte = byte << 1; /* read the next bit */
SDA2_IN();
//x=READ_SDA2&0x01;
if(READ_SDA2)
{
x=0x01;
}
else
{
x=0x00;
}
SDA2_OUT();
byte |=x;
}
return (int)byte;
}
/*
* send an address and data direction to the slave
* - 7-bit address (lsb ignored)
* - direction (FALSE = write )
*/
unsigned char
i2c_SendAddress(unsigned char address, unsigned char rw)
{
return i2c_SendByte(address | (rw?1:0));
}
/*
* Opens communication with a device at address. mode
* indicates I2C_READ or I2C_WRITE.
* - returns TRUE if address is not acknowledged
*/
unsigned char
i2c_Open(unsigned char address, unsigned char mode)
{
i2c_Start();
i2c_SendAddress(address, mode);
if(i2c_ReadAcknowledge())
return TRUE;
return FALSE;
}
/*
* Send an (~)acknowledge to the slave
* - status of I2C_LAST implies this is the last byte to be sent
*/
void
i2c_SendAcknowledge(unsigned char status)
{
SCL_LOW();
if ( status & 0x01) {
SDA_LOW(); /* drive line low -> more to come */
}else {
SDA_HIGH();
}
__delay_us(I2C_TM_DATA_SU);
SCL_HIGH(); /* float clock high */
__delay_us(3);
return;
}
/*
* Get a byte from the slave and acknowledges the transfer
* - returns true on I2C_ERROR or byte
*/
int
i2c_GetByte(unsigned char more)
{
int byte;
if((byte = i2c_ReadByte()) == I2C_ERROR)
return I2C_ERROR;
i2c_SendAcknowledge(more);
return byte;
}
/*
* Send a byte to the slave and acknowledges the transfer
* - returns I2C_ERROR, ack or ~ack
*/
signed char
i2c_PutByte(unsigned char data)
{
// if(i2c_SendByte(data))
// return I2C_ERROR;
i2c_SendByte(data);
return i2c_ReadAcknowledge(); /* returns ack, ~ack */
}
void i2c_send_dada(unsigned char A,unsigned char B,unsigned char C)
{
disableInterrupts();
unsigned char f=5;
if(fg_i2c_ev01s)
{
f=50;
}
__delay_us(f);
i2c_Open(A,0);
i2c_PutByte(B);
i2c_PutByte(C);
i2c_Stop();
enableInterrupts();
}
//************************************************
//* I2C check data *
//************************************************
void i2c_read_dada(unsigned char a,unsigned char b,unsigned char c)
{
unsigned char z=0;
unsigned char y;
unsigned char t;
t=5;
disableInterrupts();
if(fg_i2c_ev01s)
{
t=50;
}
__delay_us(t);
i2c_Open(a,0);
i2c_PutByte(b);
if(a==ev01s)
{
i2c_Stop();
}
__delay_us(t);
i2c_Open(a,1);
for(;z<c;z++)
{
y=de_non_ack;
if((z+1)==c)
{
y=de_ack;
}
ev01s_rcv_buf[z]=i2c_GetByte(y);
}
i2c_Stop();
enableInterrupts();
}
注意:模块对i2C时序有一定要求,具体可参考数据手册
STM32代码
GPIO初始化
void IIC2_Init(void)
{
GPIO_InitPara GPIO_InitStructure;
RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_PIN_8 | GPIO_PIN_9);
}
/*模块接收中断,外部中断线初始化*/
void ev01s_it_Init(void)
{
EXTI_InitPara EXTI_InitStructure;
GPIO_InitPara GPIO_InitStructure;
NVIC_InitPara NVIC_InitStructure;
RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_CFG, ENABLE);//使能外部中断时钟
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_0;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_IN; //推挽输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_PULLUP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SYSCFG_EXTILine_Config(EXTI_SOURCE_GPIOB, EXTI_SOURCE_PIN0);
EXTI_InitStructure.EXTI_LINE = EXTI_LINE0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //配置中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LINEEnable = ENABLE; //使能中断
EXTI_Init(&EXTI_InitStructure);
NVIC_PRIGroup_Enable(NVIC_PRIGROUP_3);
NVIC_InitStructure.NVIC_IRQ = EXTI0_1_IRQn;
NVIC_InitStructure.NVIC_IRQPreemptPriority = 2;//优先级
NVIC_InitStructure.NVIC_IRQSubPriority = 1;
NVIC_InitStructure.NVIC_IRQEnable = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
宏定义
//IO方向设置
#define SDA2_IN() {GPIOB->CTLR&=~(3<<(9*2));GPIOB->CTLR|=0<<9*2;}
#define SDA2_OUT() {GPIOB->CTLR&=~(3<<(9*2));GPIOB->CTLR|=1<<9*2;}
#define SCL2_IN() {GPIOB->CTLR&=~(3<<(8*2));GPIOB->CTLR|=0<<8*2;}
#define SCL2_OUT() {GPIOB->CTLR&=~(3<<(8*2));GPIOB->CTLR|=1<<8*2;}
//IO操作函数
#define IIC2_SCL(x) (x==0)?GPIO_ResetBits(GPIOB, GPIO_PIN_8):GPIO_SetBits(GPIOB, GPIO_PIN_8)// PBout(8) //SCL
#define IIC2_SDA(x) (x==0)?GPIO_ResetBits(GPIOB, GPIO_PIN_9):GPIO_SetBits(GPIOB, GPIO_PIN_9)// PBout(9) //SDA
#define READ_SDA2 GPIO_ReadInputBit(GPIOB,GPIO_PIN_9)//PBin(9) //输入SDA
#define READ_SCL2 GPIO_ReadInputBit(GPIOB,GPIO_PIN_8)//PBin(8) //输入SCL
#define SCL_LOW() IIC2_SCL(0)
#define SCL_HIGH() IIC2_SCL(1)
#define SDA_HIGH() IIC2_SDA(1)
#define SDA_LOW() IIC2_SDA(0)
#define ev01s 0x68
#define I2C_TM_SCL_HIGH 1
#define I2C_TM_SCL_LOW 3
#define I2C_TM_START_HD 24
#define I2C_TM_DATA_SU 5
#define I2C_TM_SCL_TO_DATA 5 /* SCL low to data valid */
#define I2C_TM_STOP_SU 40
#define I2C_TM_SCL_TMO 10 /* clock time out */
#define de_ack 0
#define de_non_ack 1
#define I2C_ERROR (-1)
#define __delay_us(x) delay_us(x*10)
#define i2c_Start() i2c_Restart()