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.

[参考译文] TM4C1290NCPDT:软件如何检测TM4C129的哪个部件(引脚)执行?

Guru**** 649970 points
Other Parts Discussed in Thread: TM4C129EKCPDT, TM4C1290NCPDT
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1099046/tm4c1290ncpdt-how-can-software-detect-which-tm4c129-part-pinout-it-is-executing-on

零件号:TM4C1290NCPDT
主题中讨论的其他部件:TM4C129EKCPDT

我正在使用一个PCB,它需要使用PWM驱动TM4C129 MCU的引脚62。  如果在编译时知道MCU部件号,这就足够简单了。  但我希望能够使用 TQFP封装的TM4C129变体,而无需更改软件。   大约一半的零件(例如  TM4C1290NCPDT)为某些引脚(51-63)分配的功能与其他部件(例如  TM4C129EKCPDT)。  引脚62在前者上为PK4/PWM6,在后者上为PK5/PWM7。  我希望能够在运行时检测需要将哪个端口/PWM配置为驱动引脚62。   

我通过直接读取MCU的器件识别寄存器并与数据表中的PARTNO值列表进行比较,了解了如何实现这一点,但我想知道是否有更好的方法。  理想情况下,我想使用 SysConcessalPresent()之类的命令来指示当前MCU使用的引脚,这样我就不必维护PARTNO值列表(实际上维护工作并不差, 但实际上测试我是否正确将需要使用八个不同MCU部件中的每一个来加载PCB)。

这就是我现在要做的:

				#define DeviceIdentification1 (*( (volatile uint32_t*) ( 0x400FE000 + 0x004 ) ) )
				const uint32_t ReadOfDID1 = DeviceIdentification1;					// Read the MCU's DID1 register.
				const uint32_t ReadOfPARTNO = ( ReadOfDID1 >> 16 ) & 0x000000FF;	// Extract the PARTNO field.

				tracepointLogWithCommentAndValueMacro("Device Identification 1 register: 0x%08X", ReadOfDID1 );
				tracepointLogWithCommentAndValueMacro("PARTNO field: 0x%08X", ReadOfPARTNO );

				// Parts with PK4/PWM6 on pin 62.
				#define PARTNO_TM4C1290NCPDT (0x19)

				// Parts with PK5/PWM7 on pin 62.
				#define PARTNO_TM4C129EKCPDT (0x35)

				#warning "Expand this to test more CPU variants."
				if( ReadOfPARTNO == PARTNO_TM4C1290NCPDT )
				{

谢谢!

Steve

附注 :FWIW,如果某些部件的MCU引脚59-62上的功能没有在另一半的部件上移动一个(到引脚60-63),这不是问题,但当然现在改变这种情况已经太晚了。

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

    您好,Steve,

     您正在对设备ID进行正确解码。 我认为 使用SysPeripheralPresent()本身并不是最好的方法。 外设可能出现在所有封装类型上,如果外设存在,您将无法通过读取来判断您的引脚。  

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

    这只是一个后续的更完整的代码实施了上面讨论的方法。  它仅在TM4C129EKCPDT上进行了测试,但我认为它应该在TQFP封装中的八个TM4C129部件中的任意一个针脚62上正确设置PWM。  检测MCU部件变体的部分在其他情况下可能很有用。

    // Detect the type of MCU at runtime and set up either PWM 6 or PWM 7, whichever one controls
    // pin 62 on the current MCU variant. 
    
    // PinMux could do some of this setup, but we need to make parts of it conditional on the MCU
    // variant, and other parts get auto-generated only if one of those is enabled.  So it is
    // easiest to just do it all here.
    
    // This set up is for the SYSCTL_PERIPH_PWM0 PWM "module", of which the MCU has only one.  It
    // contains four PWM "generator blocks".  Each PWM generator block has two PWM "output signals"
    // which correspond with the output number (0..7); they are not 0 and 1 for every block.
    // A single "control block" maps the pins and sets the pin polarities.
    MAP_SysCtlPeripheralEnable( SYSCTL_PERIPH_PWM0 );       // Enable the PWM module.
    SysCtlPWMClockSet( SYSCTL_PWMDIV_1 );                   // Set the clock divider for all PWM signals.
    
    // Set up PWM generator block 3, which conveniently controls both pin PWM6 and pin PWM7 making this
    // part the same regardless of the MCU variant.
    PWMGenConfigure( PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC );
    PWMGenPeriodSet( PWM0_BASE, PWM_GEN_3, 1831 );          // Sets to 60MHz/1831 = 32.7689787 KHz, almost 1Hz high.  That is an error of about 30 ppm.
    PWMGenEnable( PWM0_BASE, PWM_GEN_3 );                   // Start the timers in the PWM generator block.
    
    // Set up the PWM output signals (pins).  This part is dependent on the MCU variant.  I didn't
    // find a way to detect the variant using the TivaWare library (although SysCtlPeripheralPresent()
    // lets you test for the presence of various peripherals), but the Device Identification registers
    // in the MCU do provide that info.  I asked on the TI forum but didn't get any suggestions about
    // a better way to do this: e2e.ti.com/.../tm4c1290ncpdt-how-can-software-detect-which-tm4c129-part-pinout-it-is-executing-on
    #define DeviceIdentification1 (*( (volatile uint32_t*) ( 0x400FE000 + 0x004 ) ) )
    const uint32_t ReadOfDID1 = DeviceIdentification1;                  // Read the MCU's DID1 register.
    const uint32_t ReadOfPARTNO = ( ReadOfDID1 >> 16 ) & 0x000000FF;    // Extract the PARTNO field.
    
    // Parts with PK4/PWM6 on pin 62.
    #define PARTNO_TM4C1290NCPDT (0x19)
    #define PARTNO_TM4C1292NCPDT (0x1C)
    #define PARTNO_TM4C129CNCPDT (0x24)
    #define PARTNO_TM4C129DNCPDT (0x27)
    
    // Parts with PK5/PWM7 on pin 62.
    #define PARTNO_TM4C1294NCPDT (0x1F)
    #define PARTNO_TM4C129ENCPDT (0x2D)
    #define PARTNO_TM4C1294KCPDT (0x34)
    #define PARTNO_TM4C129EKCPDT (0x35)
    
    bool PK4_PWM6_on_pin_62 = ( ReadOfPARTNO == PARTNO_TM4C1290NCPDT )
                           || ( ReadOfPARTNO == PARTNO_TM4C1292NCPDT )
                           || ( ReadOfPARTNO == PARTNO_TM4C129CNCPDT )
                           || ( ReadOfPARTNO == PARTNO_TM4C129DNCPDT );
    
    if( PK4_PWM6_on_pin_62 )
    {
        // Enable pin PK4 for PWM0 M0PWM6.  For these parts it should drive pin 62.
        MAP_GPIOPinConfigure( GPIO_PK4_M0PWM6 );
        MAP_GPIOPinTypePWM( GPIO_PORTK_BASE, GPIO_PIN_4 );
        PWMPulseWidthSet( PWM0_BASE, PWM_OUT_6, 1831/2 );       // Can adjust this to get 50% duty cycle.
        PWMOutputState( PWM0_BASE, PWM_OUT_6_BIT, true );
    }
    else
    {
        // Enable pin PK5 for PWM0 M0PWM7.  For these parts it should drive pin 62.
        MAP_GPIOPinConfigure( GPIO_PK5_M0PWM7 );
        MAP_GPIOPinTypePWM( GPIO_PORTK_BASE, GPIO_PIN_5 );
        PWMPulseWidthSet( PWM0_BASE, PWM_OUT_7, 1831/2 );       // Can adjust this to get 50% duty cycle.
        PWMOutputState( PWM0_BASE, PWM_OUT_7_BIT, true );
    }