我用的是MC9S12HY48的16位单片机,用硬件自带的IIC模块,出现了一个问题就是,发送完一个字节后,检测IBSR_IBIF=1,不通过
下面是我的程序
/*
**************************************************************
** name : IIC_Init();
** function:
** paramage
**************************************************************
*/
void IIC_Init() {
PTSRR |= 0x02; // IIC_SDA--PR5 IIC_SCL -- PR6
IIC_IBCR &= (unsigned char)~(unsigned char)0x40U; /* Disable interrupts before change */
/* IIC_IBSR: IBIF=1 */
IIC_IBSR |= (unsigned char)0x02U; /* Clear the interrupt flag */
/* IIC_IBFD: IBC7=0,IBC6=0,IBC5=0,IBC4=1,IBC3=0,IBC2=1,IBC1=0,IBC0=0 */
IIC_IBFD = 0x14U; /* Timing setting */
/* IIC_IBCR2: GCEN=0,ADTYPE=0,ADR10=0,ADR9=0,ADR8=0 */
IIC_IBCR2 = 0x00U;
/* IIC_IBAD: ADR7=0,ADR6=0,ADR5=0,ADR4=0,ADR3=0,ADR2=0,ADR1=0 */
IIC_IBAD = 0x00U; /* Slave address setting */
/* IIC_IBCR: IBEN=1 */
IIC_IBCR |= (unsigned char)0x80U; /* Enable the module */
/* IIC_IBCR: IBEN=1,IBIE=0,MS_SL=0,TX_RX=0,TXAK=0,RSTA=0,IBSWAI=0 */
IIC_IBCR = 0x80U; /* Control register setting */
/* ### */
}
uint8 IIC_Check_ACK() {
uint8 ErrTime = 250;
while(IIC_IBSR_RXAK==1) {
ErrTime--;
if(!ErrTime)
return 1;
}
return 0;
}
uint8 IIC_Write_Byte(uint8 slaAddr, uint8 subAddr, uint8 tdata) {
uint8 status = 0;
uint8 ErrTime = 250;
IIC_IBCR_TXAK = 0;
IIC_IBCR_TX_RX = 1;
IIC_Start();
while(!IIC_IBSR_IBB);
/*
IIC_Send_Data(slaAddr & 0xfe);
IIC_Check_ACK();
IIC_Send_Data(subAddr);
IIC_Check_ACK();
IIC_Send_Data(tdata);
IIC_Check_ACK();*/
IIC_IBSR_IBIF = 1;
IIC_IBDR = slaAddr & 0xfe;
while(IIC_IBSR_IBIF==0);
//IIC_IBSR_IBIF = 1;
//while(IIC_IBSR_RXAK==1);
IIC_Check_ACK();
IIC_IBSR_IBIF = 1;
IIC_IBDR = subAddr;
while(IIC_IBSR_IBIF==0);
//IIC_IBSR_IBIF = 1;
//while(IIC_IBSR_RXAK==1);
IIC_Check_ACK();
IIC_IBSR_IBIF = 1;
IIC_IBDR = tdata;
while(IIC_IBSR_IBIF==0);
//IIC_IBSR_IBIF = 1;
//while(IIC_IBSR_RXAK==1);
IIC_Check_ACK();
IIC_Stop();
return 1;
}
/*
**************************************************************
** name : IIC_Read_Byte();
** function: IIC bus 发送一个字节
** paramage: slaAddr --> IIC设备的器件地址
subAddr --> IIC设备的内部存储地址
tdata --> 主机要写入IIC设备的数据
**************************************************************
*/
uint8 IIC_Read_Byte(uint8 slaAddr, uint8 subAddr, uint8 *rx_data) {
uint8 ErrTime = 250;
IIC_Init();
IIC_IBCR_TXAK = 0; // 主机接收数据后不应答
IIC_IBCR_TX_RX = 1; // IIC主机发送模式
IIC_Start(); // IIC bus start
while(!IIC_IBSR_IBB); // IIC bus inter busy status
PTU |= 1<<2;
IIC_IBSR_IBIF = 1;
IIC_IBDR = slaAddr & 0xfe; // transmit Slave Address
while(IIC_IBSR_IBIF==0); // wait for transmit over A BYTE
//IIC_IBSR_IBIF = 1; // 清零 IBIF 标志 等待下次接收
IIC_Check_ACK(); // 检测从机发回的校验值
PTU |= 1<<1;
IIC_IBSR_IBIF = 1;
IIC_IBDR = subAddr;
while(IIC_IBSR_IBIF==0); //
//IIC_IBSR_IBIF = 1;
IIC_Check_ACK();
IIC_IBCR_RSTA = 1; // RSTA=1, IIC bus 重新开始
IIC_IBSR_IBIF = 1;
IIC_IBDR = slaAddr | 0x01; // 从机地址, 处于Read模式下
while(IIC_IBSR_IBIF==0);
//IIC_IBSR_IBIF = 1;
IIC_Check_ACK();
IIC_IBCR_TX_RX = 0; // 主机接收数据
IIC_IBSR_IBIF = 1;
*rx_data = IIC_IBDR; // 读出IIC_IBDR,等待接收数据
while(IIC_IBSR_IBIF==0)
{
ErrTime --;
if(ErrTime==0)
return 1;
}
IIC_IBSR_IBIF = 1;
*rx_data = IIC_IBDR;
PTU |= 1<<4;
IIC_IBCR_TXAK = 1;
IIC_Stop();
*rx_data = IIC_IBDR;
return 1;
}
此帖出自
小平头技术问答
一周热门 更多>