TMS320F28377D库函数操作(IIC初始化及使用)

目录

1.背景

2.TI的IIC的特别

3.程序

4.实际效果


 

 

1.背景

IIC作为低速环境下使用非常广泛的协议,还是要学一学滴。TI的IIC是硬件(看什么看,说的就是你ST,这么大一个厂一个硬件IIC做的还有bug)这两年TI还是不错的,以前TI做的IIC还是专属,鬼知道怎么搞,非常难调。不过这两年TI貌似光明正大地说起来了(难道是NXP开发出来I3C后对I2C管控放松了?不应该吧)虽说与正点原子写的软件IIC还是有区别和不理解,但是最终还是调出来了,回过头来看程序还算能理解吧。

 

2.TI的IIC的特别

如果各位写过模拟IIC再看TI的IIC会有一种特别的感觉。

首先的话就是各个通信模块都有FIFO和中断(ST:?)

33082c6f18ff44f2baba8eeb65798e6e.png

 

其次IIC有占空比33%和55%两种模式,老实说以前写模拟IIC的时候还真没考虑过这个问题

4f217290ea2645898da3ca313e64c695.png

 

至此TI的IIC的特别点我都介绍过了,下面我们就正式开始写程序吧。

 

3.程序

//
// initI2C - Function to configure I2C A in FIFO mode.
//
void initI2C1(void)
{
    //
    // Must put I2C into reset before configuring it
    //
    I2C_disableModule(I2CA_BASE);

    //
    // I2C configuration. Use a 400kHz I2CCLK with a 33% duty cycle.
    //
    I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 1000, I2C_DUTYCYCLE_33);
    I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
    I2C_setSlaveAddress(I2CA_BASE, 0x50);
    I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);

    //
    // Enable stop condition and register-access-ready interrupts
    //
    I2C_enableInterrupt(I2CA_BASE, I2C_INT_STOP_CONDITION |
                        I2C_INT_REG_ACCESS_RDY);

    //
    // FIFO configuration
    //
    I2C_enableFIFO(I2CA_BASE);
    I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);

    //
    // Configuration complete. Enable the module.
    //
    I2C_enableModule(I2CA_BASE);

    GPIO_setPinConfig(GPIO_32_SDAA);
    GPIO_setPadConfig(32, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(32, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(GPIO_33_SCLA);
    GPIO_setPadConfig(33, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(33, GPIO_QUAL_ASYNC);

    //
    // Interrupts that are used in this example are re-mapped to ISR functions
    // found within this file.
    //
    Interrupt_register(INT_I2CA, &i2cAISR);
}

上面的是IIC初始化,其中比较重要的有三句话

I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 10000, I2C_DUTYCYCLE_50);
    I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
    I2C_setSlaveAddress(I2CA_BASE, 0x50);
    I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);

第一个函数的第三个参数是通信速率,第四个参数占空比

第二个函数的第二个参数是位数

第三个函数的第二个参数是从机的地址(其实设置没什么影响)

第四个函数的第二个参数是设置仿真模式,我推荐各位使用freerun模式,对应的是我们正常使用的模式,我没试过其他模式

 

//
// writeData - Function to send the data that is to be written to the EEPROM
//
void I2cWriteData1(unsigned int i2c1data)
{
    //
    // Wait until the STP bit is cleared from any previous master
    // communication. Clearing of this bit by the module is delayed until after
    // the SCD bit is set. If this bit is not checked prior to initiating a new
    // message, the I2C could get confused.
    //
    if(I2C_getStopConditionStatus(I2CA_BASE))
    {
        return;
    }

    //
    // Setup slave address
    //
    I2C_setSlaveAddress(I2CA_BASE, 0x78);

    //
    // Check if bus busy
    //
    if(I2C_isBusBusy(I2CA_BASE))
    {
        return;
    }

    //
    // Setup number of bytes to send msgBuffer and address
    //
    I2C_setDataCount(I2CA_BASE, 1);

    //
    // Setup data to send
    //
    I2C_putData(I2CA_BASE, i2c1data);

    //
    // Send start as master transmitter
    //
    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
    I2C_sendStartCondition(I2CA_BASE);
    I2C_sendStopCondition(I2CA_BASE);

}

上面的程序就是发送一个数据的程序,其中最为注意的是三个地方

I2C_setSlaveAddress(I2CA_BASE, 0x78);

这个函数的第二个参数就是从机的地址,每次发送是依照这里的地址而非初始化的地址

 

//
    // Setup number of bytes to send msgBuffer and address
    //
    I2C_setDataCount(I2CA_BASE, 1);

    //
    // Setup data to send
    //
    I2C_putData(I2CA_BASE, i2c1data);

这是发送一个数据的程序,注意第一个函数的第二个参数因该与下面发送的个数匹配,否则芯片会认为发送任务没有完成而一直等待从而死机。

 

假如我要一次性发送两个数据呢?比如0.96寸的oled

void OLED4WriteCmd(unsigned char I2C_Command)//写命令
{
    //
    // Wait until the STP bit is cleared from any previous master
    // communication. Clearing of this bit by the module is delayed until after
    // the SCD bit is set. If this bit is not checked prior to initiating a new
    // message, the I2C could get confused.
    //
    if(I2C_getStopConditionStatus(I2CA_BASE))
    {
        return;
    }

    //
    // Setup slave address
    //
    I2C_setSlaveAddress(I2CA_BASE, 0x78);

    //
    // Check if bus busy
    //
    if(I2C_isBusBusy(I2CA_BASE))
    {
        return;
    }

    //
    // Setup number of bytes to send msgBuffer and address
    //
    I2C_setDataCount(I2CA_BASE, 2);

    //
    // Setup data to send
    //
    I2C_putData(I2CA_BASE, 0x00);
    I2C_putData(I2CA_BASE, I2C_Command);

    //
    // Send start as master transmitter
    //
    I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
    I2C_sendStartCondition(I2CA_BASE);
    I2C_sendStopCondition(I2CA_BASE);
}

注意看其中的区别

//
    // Setup number of bytes to send msgBuffer and address
    //
    I2C_setDataCount(I2CA_BASE, 2);

    //
    // Setup data to send
    //
    I2C_putData(I2CA_BASE, 0x00);
    I2C_putData(I2CA_BASE, I2C_Command);

可以对比发送一个字节,相信大家能理解,如果还要发送更多以此类推就行,TI给的例程中EEPROM就是一次发送10个字节,大家再看看肯定能理解了

//
// i2cAISR - I2C A ISR (non-FIFO)
//
__interrupt void
i2cAISR(void)
{
    I2C_InterruptSource intSource;

    //
    // Read interrupt source
    //
    intSource = I2C_getInterruptSource(I2CA_BASE);

    //
    // Interrupt source = stop condition detected
    //
    if(intSource == I2C_INTSRC_STOP_CONDITION){;}
    //
    // Interrupt source = Register Access Ready
    //
    // This interrupt is used to determine when the EEPROM address setup
    // portion of the read data communication is complete. Since no stop bit
    // is commanded, this flag tells us when the message has been sent
    // instead of the SCD flag.
    //
    else if(intSource == I2C_INTSRC_REG_ACCESS_RDY){;}

    //
    // Issue ACK to enable future group 8 interrupts
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
}

 这是中断服务函数,用来异常处理,我这里没有写,大家如有需要可以对照官方文件,也挺好理解的。

void main(void)
{
      init_CPU1();                        //初始化CPU1
//    CLA_init();                         //初始化CLA1
//
//    initCPUTimer0(100000);              //初始化timer0
//    initCPUTimer1(200000);              //初始化timer1
//    initCPUTimer2(100);                 //初始化timer2
//
//    EPWM_init();                        //初始化EPWM模块
//    initEPWM1();                        //初始化EPWM1
//    initEPWM_for_dac(EPWM8_BASE);       //初始化EPWM8给DACA
//
//    initDMA6_DAC();                     //初始化DMA6给DAC
//    initADC1();                         //初始化ADC1
//    start_epwm12_adc1();                //初始化EPWM12给adc1
//    initDACA();                         //初始化DACA
//    initDACC();                         //初始化DACC
//
//    init_uart1(115200);                 //初始化串口1
    initI2C1();                     //初始化IIC1
//    init_spi1();                    //初始化SPI1
//    Init_LEDV3();                       //初始化LEDV3管脚
//
    ENINT;                              //启用全局中断和实时中断
    OLED4_Init();                       //4针IIC的oled初始化

//    CLA_runTest(1);                     //启动CLA任务1
//    CLA_runTest(2);
//    ESTOP0;                             //软件断点
//
//    for(fftmov=0;fftmov<520;fftmov++)
//    {
//        fftout[fftmov]=fabsf(IOBuffer[fftmov]);
//        __asm(" NOP");
//    }

//    ESTOP0;                             //软件断点

    while(1)
    {
//        SPI_writeDataNonBlocking(SPIA_BASE, 257);
        ;
    }
}

这里我就以初始化0.96寸的OLED为例来完成实际效果的演示了。

 

4.实际效果

 

f4c981fec83f44fdad09b36b3d05ea6d.jpg

022329e5881c4c3b9152cfee06cef21b.jpg

 c03cf161628245ec85001cf02e62a5a6.png

48829cce325f4fb48bb72aee3f82ee69.png

 c34cd6949ebe4193b7a96b5c63bacaad.png

 1a0010c1692f45608ea8db66c43287ee.png

 可以看到波形和结果非常漂亮

下面我们再看一下占空比

9ec30386dc004b169908c735e569467b.png

 2a3fa5cd140c4ee99c715f2496c695fd.png

 这里设置的是50占空比

9dbe478c86b34ed986248f2c774b7ddb.png

8ab9da6d5a5a46b6a635df3c1e041bce.png

这是设置成33占空比

大家除了直观观察还可以看时间

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值