This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TM4C123GH6PM:我的 i2c 驱动程序有问题

Guru**** 2606375 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/749707/ccs-tm4c123gh6pm-i-have-problem-with-my-i2c-driver

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

我遇到的问题是、除了 I2CMDR 和 I2CMCS 之外、所有配置都完成了、即使是写入它们的 IAM 也不会被修改

所有寄存器都有屏幕截图

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、您能提供更多详细信息吗? 您的软件是什么样的? 您是否正在使用 TivaWare 驱动程序?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    没有 IAM 从零写入我自己的驱动程序
    我写过 GPIO 计时器 UART 驱动程序、它们工作正常

    存在 I2C.c

    /*
    * ICC.c
    *
    *创建时间:2018年10月30日
    * 作者:Morgan
    */
    
    #include "icc.h"
    
    
    gICCError_t initAppreateICCPins (SICC_t ICC)
    {
    gICCError_t state=ICC_pass;
    if (icc=ICC0_MOD)
    {
    //PB2 PB3
    clockGatingICC (ICC0_MOD);
    时钟门控(GPIOB);
    pinAlternateFunctionSel (base_B、2、高电平);
    pinAlternateFunctionSel (base_B、3、高电平);
    pinDigitalEnable (base_B、2、高电平);
    PinDigitalEnable (base_B、3、高电平);
    GPIOPinControl (BASE_B、2、3);
    GPIOPinControl (BASE_B、3、3);
    pinOpenDrainEnable (base_B、3、true);
    
    }else if (icc=ICC1_MOD)
    {
    //PA6 PA7
    clockGatingICC (ICC1_MOD);
    时钟门控(GPIOA);
    pinAlternateFunctionSel (base_a、6、高电平);
    pinAlternateFunctionSel (base_a、7、高电平);
    pinDigitalEnable (base_a、6、高电平);
    pinDigitalEnable (base_a、7、高电平);
    GPIOPinControl (BASE_A、6、3);
    GPIOPinControl (BASE_A、7、3);
    pinOpenDrainEnable (base_a、7、true);
    
    }else if (icc=ICC2_MOD)
    {
    //PE4 PE5
    clockGatingICC (ICC2_MOD);
    时钟门控(GPIOE);
    pinAlternateFunctionSel (base_E、4、高电平);
    pinAlternateFunctionSel (base_E、5、高电平);
    GPIOPinControl (BASE_E、4、3);
    GPIOPinControl (BASE_E、5、3);
    pinOpenDrainEnable (base_E、5、true);
    }else if (icc=ICC3_MOD)
    {
    //PD0 PD1
    clockGatingICC (ICC3_MOD);
    时钟门控(GPIOD);
    pinAlternateFunctionSel (base_D、0、高电平);
    pinAlternateFunctionSel (base_D、1、高电平);
    GPIOPinControl (BASE_D、0、3);
    GPIOPinControl (BASE_D、1、3);
    pinOpenDrainEnable (base_D、1、true);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError_t initMaster (uint32 icc)
    {
    gICCError_t state = ICC_pass;
    if ((icc=ICC0)||(icc=ICC1)||(icc=ICC2)||(icc=ICC3)
    {
    HW_WRITE_BIT (ICC+I2CMCR、4、高电平);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError _t setSCLclock (uint32 icc、gicc_clock_t speed、uint8 sysclockinMHZ)
    {
    uint8 temp =0;
    gICCError_t state=ICC_pass;
    if ((icc=ICC0)||(icc=ICC1)||(icc=ICC2)||(icc=ICC3)
    {
    if (speed=standard_mode)
    {
    if (sysclockinMHZ=2||sysclockinMHZ==4||sysclockinMHZ=8||
    sysclockinMHZ=16||sysclockinMHZ==20||sysclockinMHZ==40||
    sysclockinMHZ==80)
    {
    temp=(sysclockinMHZ/2)-1;
    HW_WRITE_REG_32位(ICC+I2CMTPR、temp);
    }否则
    STATE =错误的 SYS_CLOCK;
    }else if (speed=highspeed_mode)
    {
    if (sysclockinMHZ==40)
    {
    HW_WRITE_REG_32位(ICC+I2CMTPR、1);
    }else if (sysclockinMHZ=80)
    {
    HW_WRITE_REG_32位(ICC+I2CMTPR、3);
    }否则
    STATE =错误的 SYS_CLOCK;
    }否则
    STATE =错误的速度模式;
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    
    }
    gICCError _t setMasterSlaveAddress (uint32 icc、uint8从器件)
    {
    gICCError_t state= icc_pass;
    if ((icc=ICC0)||(icc=ICC1)||(icc=ICC2)||(icc=ICC3)
    {
    HW_WRITE_HIBRATE_REG (ICC+I2CMSA、从机、1、0xFE);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError_t selectOperation (uint32 icc、gicc_operation_t operation)
    {
    gICCError_t state = ICC_pass;
    if ((ICC =ICC0)||(ICC =ICC1)||(ICC =ICC2)||(ICC =ICC3))
    {
    if (OPERATION =发送)
    {
    HW_WRITE_BIT (ICC+I2CMSA、0、0);
    }else if (operation==receeve)
    {
    HW_WRITE_BIT (ICC+I2CMSA、0、1);
    }否则
    State=wrong_ICC_OPERATION;
    }
    其他
    状态= ICC_MODULE_NOT 存在;
    返回状态;
    }
    
    gICCError_t readI2CErrrorBit (uint32 icc、uint8 *错误)
    {
    gICCError_t state = ICC_pass;
    if ((ICC =ICC0)||(ICC =ICC1)||(ICC =ICC2)||(ICC =ICC3))
    {
    *error=hw_read_bit (ICC+I2CMCS、1);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError _t readI2CBusyBit (uint32 icc、uint8 *忙)
    {
    gICCError_t state = ICC_pass;
    if ((ICC =ICC0)||(ICC =ICC1)||(ICC =ICC2)||(ICC =ICC3))
    {
    *BUSY=HW_READ_BIT (ICC+I2CMCS、0);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError_t writeByte (uint32 icc、uint8 data、uint8 start、uint8 run、uint8 stop)
    {
    gICCError_t state = ICC_pass;
    uint8 BUSY=0;
    uint8错误;
    if ((ICC =ICC0)||(ICC =ICC1)||(ICC =ICC2)||(ICC =ICC3))
    {
    HW_WRITE_REG_32位(ICC+I2CMDR、DATA);
    HW_WRITE_BIT (ICC+I2CMCS、0、运行);
    HW_WRITE_BIT (ICC+I2CMCS、1、START);
    HW_WRITE_BIT (ICC+I2CMCS、2、STOP);
    readI2CBusyBit (ICC、BUSY);
    while (忙!=0);
    readI2CerrorBit (icc、&error);
    if (error==1)
    {
    HW_WRITE_BIT (ICC+I2CMCS、2、STOP);
    UARTprintf ("通过 i2c 发送错误");
    }
    }否则
    状态= ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError _t MasterReadByte (uint32 icc、uint8 * data、uint8 start、uint8 run、uint8 stop)
    {
    gICCError_t state = ICC_pass;
    uint8 BUSY=0;
    uint8错误;
    if ((ICC =ICC0)||(ICC =ICC1)||(ICC =ICC2)||(ICC =ICC3))
    {
    HW_WRITE_BIT (ICC+I2CMCS、0、运行);
    HW_WRITE_BIT (ICC+I2CMCS、1、START);
    HW_WRITE_BIT (ICC+I2CMCS、2、STOP);
    if (stop=0)
    {
    HW_WRITE_BIT (ICC+I2CMCS、3、1);
    }else if (stop=1)
    {
    HW_WRITE_BIT (ICC+I2CMCS、2、0);
    }
    readI2CBusyBit (ICC、BUSY);
    while (忙!=0);
    readI2CerrorBit (icc、&error);
    if (error=0)
    {
    *数据= hw_read_masked_byte_REG (ICC+I2CMDR、0、0xFF);
    }否则
    {
    HW_WRITE_BIT (ICC + I2CMCS、2、STOP);
    UARTprintf ("通过 i2c 发送错误");
    }
    }否则
    状态= ICC_MODULE_NOT 存在;
    返回状态;
    }
    
    gICCError_t ICCenableLoopBack (uint32 icc)
    {
    gICCError_t state = ICC_pass;
    if ((icc=ICC0)||(icc=ICC1)||(icc=ICC2)||(icc=ICC3)
    {
    HW_WRITE_BIT (ICC+I2CMCR、0、高电平);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError_t ICCInitSlave (uint32 icc、uint8 slaveAddress)
    {
    gICCError_t state = ICC_pass;
    if ((icc=ICC0)||(icc=ICC1)||(icc=ICC2)||(icc=ICC3)
    {
    HW_WRITE_BIT (ICC+I2CMCR、5、高电平);
    HW_WRITE_BIT (ICC+I2CSCSR、0、高电平);
    HW_WRITE_HIBRATE_REG (ICC+I2CSOAR、slaveAddress、0、0x7F);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError_t slaveRecievedData (uint32 icc、uint8 *状态)
    {
    gICCError_t state = ICC_pass;
    if ((ICC =ICC0)||(ICC =ICC1)||(ICC =ICC2)||(ICC =ICC3))
    {
    *STATUS=HW_READ_BIT (ICC+I2CSCSR、0);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    gICCError_t slaveReadByte (uint32 icc、uint8 *数据)
    {
    gICCError_t state = ICC_pass;
    uint8状态;
    slaveRecievedData (ICC、状态);
    if ((icc=ICC0)||(icc=ICC1)||(icc=ICC2)||(icc=ICC3)
    {
    while (status!=0);
    *数据= hw_read_masked_byte_REG (ICC+I2CSDR、0、0xFF);
    }否则
    State=ICC_MODULE_NOT 存在;
    返回状态;
    }
    
    
    
    
    
    

    ________________________________________________________________
    在主 iAM 中、使用环回模式测试 i2c 

    我非常抱歉、我第一次在这里发布时格式化

    _________________________________________________________________________________________
    /**
    * main.c
    */
    #include 
    #include 
    #include "app/app_gpio.h"
    #include "HAL/timers.h"
    #include "app/app_uart.h"
    #include "HL/can.h"
    #include "HL/icc.h"
    int main (void)
    {
    uint8 TXdata [2];
    uint8 RXdata [2];
    uint8索引;
    const uint8从机=0x3C;
    setSysClock (internal_16M、c20MHZ);
    gGPIOObj_t inPin;
    gUARTCFG_t UARTobj;
    UARTobj.FIFOSEnable=false;
    UARTobj.clockSource=system_clock;
    UARTobj.parityEnable=false;
    UARTobj.stopbits=one_stop_bit;
    UARTobj.wordLength =八位;
    UARTobj.integarDiv=130;
    UARTobj.fractionaldiv=13;
    UARTobj.UART=UART0_MODULE;
    inPin.base=base_F;
    inPin.dir=输入;
    inPin.PIN_num=0;
    inPin.configPadObj.reype=pull_up_RES;
    inPin.configPadObj.lockFlag=false;
    inPin.configPadObj.currentVal=Current_2mA;
    initPort (inPin、0b11101110);
    initUART (UARTobj);
    //I2C 初始化
    适当的 ICCPins (ICC1_MOD);
    initMaster (ICC1);
    setSCLclock (ICC1、standard_mode、20);
    ICCenableLoopBack (ICC1);
    ICCInitSlave (ICC1、从器件);
    setMasterSlaveAddress (ICC1、从器件);
    selectOperation (ICC1、Transmit);
    TXDATA[0]='I';
    TXDATA[1]='2';
    TXDATA[2]='C';
    对于(索引= 0;索引<= 2;索引++)
    {
    RXDATA[index]= 0;
    }
    对于(索引= 0;索引<= 2;索引++)
    {
    UARTprintf ("正在发送... %c\n\r\n"TXDATA[index]);
    writeByte (ICC1、TXDATA[索引]、1、1、1);
    slaveReadByte (ICC1、&RXDATA[index]);
    UARTprintf ("已收到... %c\n\r\n"RXDATA[index]);
    }
    
    
    返回0;
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、我不知道当您可以访问 IC 供应商编写的、经过测试和验证的免费驱动程序时、为什么您选择编写自己的驱动程序。

    您可以想象、我们在该论坛上收到许多帮助请求。 为了尽可能高效并尽可能多地帮助用户、我们鼓励每个人都使用 TivaWare 驱动程序。 我们不会花时间调试那些选择不使用提供的驱动程序的用户的工作。 希望您能理解。 您会发现、当存在适当的 TivaWare 驱动程序时、很少(如果有)有经验的社区成员编写自己的驱动程序。 提供了每个 TivaWare 驱动程序的源代码。 如果您的目标是了解硬件寄存器及其使用情况、请查看 TivaWare 驱动程序如何写入硬件寄存器。