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:周期性中断、每秒闪烁蓝色 LED

Guru**** 2468460 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/662310/ccs-tm4c123gh6pm-periodic-interrupts-blinking-blue-led-every-second

器





件型号:TM4C123GH6PM 工具/软件:Code Composer Studio 您好、我尝试生成周期性中断来驱动蓝色 LED (使其每秒闪烁一次)。 
我已将时钟初始化为12.5MHz、因此根据该时钟计算了一个重新加载值、因此 SysTick 在生成中断之前会计时"重新加载值"次。
此外、我已经创建了一个处理程序来为中断提供服务、并要求中断闪烁。 我想问这是否正确、我正在等待我的板、但与此同时、我能够对此进行编码、
我希望有人能够指出任何错误、因为我还没有电路板、所以我无法测试。 下面是供参考的代码。 谢谢 #include #include #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "inc/tm4c123gh6a.h" void SysTick 初始化(unsigned long reload _value) { NVIC_ST_CTRL_R = 0;//禁用 SysTick NVIC_ST_RELOAD_R=RELOAD_VALUE;// SysTick 中断时间周期=(SysTK_LOAD+1)*时钟周期 NVIC_ST_CURRENT_R = 0; NVIC_SYS_PRI3_R = NVIC_SYS_PRI3_R&0x00FFFFFF;//优先级0 NVIC_ST_CTRL_R = 0x07;//启用 SysTick } void SysTick 处理程序(void) { IF (GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_2)) { GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3、0); } 其他 { GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、4); } } int main (void) { SysTick 初始化(12499999); SysCtlClockSet (SYSCTL_SYSDIV_16|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);//时钟频率为12.5MHz SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF); GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_4); GPIO_PORTF_LOCK_R = 0x4C4F434B; GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_4、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);//启用 F4的上拉电阻、驱动强度不会影响输入 GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_2); }

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

    以下几项建议:

    1) 1)注意嵌入式代码的运行方式。 通常、您需要在某个位置有一个 while (1)循环来保持执行;

    2)考虑一种更通用的方法、即在 SysTick ISR 中安装处理程序并使 LED 闪烁。 这将创建几个模块(在 GPIO 和 SysTick 上)、您可以在将来的程序中使用这些模块。

    就个人而言、我倾向于保持 SysTick 自由运行。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    使用"DRM"执行简单/不匆忙的"外设设置/配置"可能有何理由? 这会增加(不需要/不需要)复杂性-不是吗? 再次-达到"什么"可能的目的?

    您"尝试"解锁 PortF"-但它是否(仅)要求这样做的 PF0? (和在应用程序中显示为"未使用"。)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    为了跟进我的帖子,有两种方法显示了相同的行为:PF2高电平持续0.5秒,低电平持续0.5秒,高电平持续0.5秒…

    第一种方法是使用 SysTick 作为10ms 时基。 在 SysTick ISR 中、我们调用一个用户安装的处理程序、每50次翻转 PF2:50x10ms = 500ms。

    //闪烁 PF2。
    //时基:SysTick
    #include "tm4c123.h"//tm4c123
    
    //硬件配置
    #define LED_PORTGPIOF
    #define LED(1<2)//1=R、2=B、3=G
    #define LED_DLY(SystemCoreClock / 100)//1s/100 = 10ms INTERRUPT
    
    / OUT= CONFIGURAM-
    
    
    (CONFIGURAM-~引脚)、#define LED-DIO = END-(CONFIGURAM- CONFIGURAM= ENTRL)/ OUT-(CONFIGURAM= TOPINS)/ OUT-(CONTOPINS port->DIR |=(引脚);}while (0)
    #define IO_FLP (端口、引脚)port->data ^=(引脚)//map_GPIOPinWrite (端口、(引脚)、~IO_GET (端口、引脚))
    
    //空处理程序
    static void empty_handler (pins){
    //不执行
    任何操作}
    
    //全局变量/volatile rontinuatile r_tractors</tractu_rtotr=24*
    
    void (缺省值)
    //空处理程序指向 volatile r_rtotr_atile r_atile r_tractors/void_uatile r_truatile r_trlum_atile r// SysTick 计数器
    
    // SysTick 处理程序
    //将 SysTick 处理程序插入到矢量表
    中 void SysTick 处理程序(void){
    //清除标志
    //sykovf_counter += 1ul<24;//使 SysTick 计数器递增- 24位,1:1预分频
    器_isrpcounter_Systick ();//执行 Sykovf
    
    
    
    处理程序= 1个空 SysTick 处理程序(void
    );//执行 SysTick 处理程序= 24)// SysTick 是一个24位的递减计数
    器//用于在 CMSIS
    SysTick -> load =(周期-1)/* ticks*/& SysTick _load_reload _MSK 中未定义 SysTick _Config()的芯片; //设置重新加载寄存器*/
    NVIC_setpriority(SysTK_IRQn、(1< <__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
    	SysTick->Val =0; /*加载 SysTick 计数器值*/
    SysTick ->CTRL =SysTK_CTRL_CLKSOURCE_MSK |
    SysTK_CTRL_TICKINT_MSK |
    SysTK_CTRL_ENABLE_MSK; /*启用 SysTick IRQ 和 SysTick 计时器*////替代
    
    -用于 CMSIS-EquipedD 芯片
    //SysTK_Config (SysTK_LOAD_RELOAD_MSK);//重新加载所有24位
    
    }
    
    //安装 SysTick void
    SysTick 的用户处理程序(void) SysTick void (rpistr)(void)(rpistr_reload)(void))=
    
    
    50ms = 50ms;//安装
    
    静态处理程序= 50ms = 50ms;void =/void = 50ms;void = 50ms
    if (i++=50){io_FLP (LED_PORT、LED);i=0;}
    //
    
    重置 MCU
    void MCU_init (void){
    sysctl->RCGC2 |=(1<<5);//5->GPIOF/map_SysCtlPeripheralEnable (sysctl_Periptl){sysctl–/sychduld_rtc (
    默认值)/
    
    
    sysstick
    
    
    
    (默认值);/systemtunt)/sys_up (默认值)/systemtunt (默认值)/sytunt (默认值)/system_cort_click (mcu
    
    
    (默认值)/system_cort_up)//led 作为输出
    
    //ei();//启用中断
    while (1){
    }
    
    返回0;
    }
    
    
    

    我通常更喜欢自由运行的 SysTick、如下面的第二种方法。 它有一个自由运行的 SysTick。 我们在主循环中读取时间戳。 如果经过了足够的时间、我们翻转 PF2。

    //闪烁 PF2。
    //时基:SysTick
    #include "tm4c123.h"//tm4c123
    
    //硬件配置
    #define LED_PORTGPIOF
    #define LED(1<2)//1=R、2=B、3=G
    #define LED_DLY(SystemCoreClock / 2)//1s/2=500ms INTERRUPT
    
    / OUT-~引
    
    
    脚(CORED-端口)、#define LED_OUT (CONTOPins)/ CORED-(COL CONTOPINS)/CONTOPINS (CONTOPINS)/CONTOPINS (CONTOPLE= 500ms CONTOPs CONFIL) port->DIR |=(引脚);}while (0)
    #define IO_FLP (端口、引脚)port->data ^=(引脚)//map_GPIOPinWrite (端口、(引脚)、~IO_GET (端口、引脚))
    
    //空处理程序
    static void empty_handler (pins){
    //不执行
    任何操作}
    
    //全局变量/volatile rontinuatile r_tractors</tractu_rtotr=24*
    
    void (缺省值)
    //空处理程序指向 volatile r_rtotr_atile r_atile r_tractors/void_uatile r_truatile r_trlum_atile r// SysTick 计数器
    
    // SysTick 处理程序
    //将 SysTick 处理程序插入到矢量表
    中 void SysTick 处理程序(void){
    //清除标志
    sykovf_counter += 1ul<24;//使 SysTick 计数器递增- 24位、1:1预分频
    器// isrpick_SysTick ();//执行 SysTick 处理程序
    
    
    
    =
    1个空 SysTick 处理程序(void)// SysTick 是一个24位的递减计数
    器//用于在 CMSIS
    SysTick -> load =(周期-1)/* ticks*/& SysTick _load_reload _MSK 中未定义 SysTick _Config()的芯片; //设置重新加载寄存器*/
    NVIC_setpriority(SysTK_IRQn、(1< <__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
    	SysTick->Val =0; /*加载 SysTick 计数器值*/
    SysTick ->CTRL =SysTK_CTRL_CLKSOURCE_MSK |
    SysTK_CTRL_TICKINT_MSK |
    SysTK_CTRL_ENABLE_MSK; /*启用 SysTick IRQ 和 SysTick 计时器*////替代
    
    -用于 CMSIS-EquipedD 芯片
    //SysTK_Config (SysTK_LOAD_RELOAD_MSK);//重新加载所有24位
    
    }
    
    //安装 SysTick
    void SysTick 的用户处理程序(void (rpistr)(rpistr_reload));{_isot_uintr_32
    
    
    
    位/systick handler =/void 32位/syt_read/ut 计数;/systick
    
    
    
    //执行双读
    DO{
    m = systickovf_counter;
    f = SysTick ->VAL;
    }while (m ^ systickovf_counter);//保持原子性
    
    返回 m - f;
    }
    
    //每10次调用触发一次翻转= 10x10ms = 100ms
    void led_flp (void){
    static int i=0;
    if (i +)={fled+、= 10}(void);if (i = 10);if (i +)={fleD_port ={void = 10} i=0;}
    }//
    
    重置 MCU
    void MCU_init (void){
    sysctl->RCGC2 |=(1<5);//5->GPIOF/map_SysCtlPeripheralEnable (sysctl_Periph_GPIOF);
    SystemCoreClockUpdate ();//update systemeclock //map_Systl init/sytl init/nstick
    
    
    
    (time/time-tcockpit
    
    
    
    );//将 MCUt_time_stock<t/time_t</time_stock<trupt/time_t</t</t</trupt_time_time_time_t</t</t</trupt/nstock<t</t</t</t</t</t</emctrad_time_time/t</t</t</t</t</t</t</t</t</t</t</
    
    
    //led 作为输出
    
    //ei();//启用中断
    while (1){
    if (SysTK_get()- time0 >= LED_DLY){
    IO_FLP (LED_PORT,LED);//使 LED
    时间闪烁0+= LED_DLY;//Advance time0
    }
    
    
    返回0;
    }
    
    
    

    这两种方法都在 CMSIS 下完成。 但是、如果您选择使用 driverlib 来实现它、同样的概念也适用。 CMSIS 实现的优势在于、它可移植到其他提供 SysTick 计时器的 CMx 芯片。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的全面推理和方法。 当我发布这篇文章时、我对中断和哈德勒没有完全的了解、我花了一些时间在课堂上、我很清楚这是如何工作的。上面的这个对于中断和哈德勒来说也是很棒的、再次感谢