SCTimer implement traffic signal
The State Configurable Timer (SCTimer/PWM) is a peripheral that is unique to NXP Semiconductors. It can operate like most traditional timers, but also adds a state machine to give it a higher degree of configurability and control, in another word, the SCTimer/PWM can be considered as consist of Stand Timer and State/Event Logic (Fig 1). This allows the SCT to be configured as multiple PWMs, a PWM with dead-time control, and a PWM with reset capability, in addition to many other configurations that can’t be duplicated with traditional timers. Once the SCTimer/PWM has been configured, it can run autonomously from the microcontroller core, unless the SCTimer/PWM interrupt has been enabled which requires the core to service the interrupt.
Fig 1
The first time you look at the SCTimer/PWM, it may appear to be a very complex peripheral, but you will see that it is actually not that difficult to use. Understanding the Event and State is critical to understanding the SCTimer/PWM.
The following conditions define possible events: a counter match condition, an input (or output) condition, a combination of a match and/or an input/output condition in a specified state, and the count direction. Events can control outputs, interrupts, DMA requests and the SCTimer/PWM states. They can also cause timer limit, halt, start, or stop conditions to occur.
The state variable is the main feature that distinguishes the SCTimer/PWM from other counter/timer/PWM blocks. Events can be made to occur only in certain states. Events, in turn, can perform the following actions:
Regarding the event and state mechanism (Fig 2 show a basic example), The SCT allows the user to group and filter events, thereby selecting some events to be enabled together while others are disabled. A group of enabled and disabled events can be described as a state, and several states with different sets of enabled and disabled events are allowed. Changing from one state to another is event driven as well and can happen without software intervention. Formally, the SCTimer/PWM can be programmed as state machine generator. The ability to perform switching between groups of events provides the SCT the unique capability to be utilized as a highly complex State Machine engine. Events identify the occurrence of conditions that warrant state changes and determine the next state to move to. This provides an extremely powerful control tool - particularly when the SCT inputs and outputs are connected to other on-chip resources (comparators, ADC triggers, other timers etc.) in addition to general-purpose I/O.
Fig 2
Fig 3 illustrates the application of the SCT to simulate the traffic signal.
Fig 3
LPCOpen is an extensive collection of free software libraries (drivers and middleware) and example programs that enable developers to create multifunctional products based on LPC microcontrollers. In this article, I will illustrate the steps of creating a new demo in the LPCOpen, for instance, create a demo by using the IAR IDE. Since the selected hardware board is the LPCXpresso824, the creating work is based on the corresponding LPCOpen.
Fig 4
2. Create the example and lib groups, then add the startup and board initialization files under the example group and add the library files: board_nxp_lpcxpresso_824.a and chip_82x_lib.a under the lib group. Next, create a main.c file: traffic_signal_demo.c.
Fig 5
3. Add the corresponding paths
$PROJ_DIR$\..\..\..\..\..\..\software\lpc_core\lpc_chip\chip_8xx\config_82x $PROJ_DIR$\..\..\..\..\..\..\software\lpc_core\lpc_chip\chip_common $PROJ_DIR$\..\..\..\..\..\..\software\lpc_core\lpc_chip\chip_8xx $PROJ_DIR$\..\..\..\..\..\..\software\lpc_core\lpc_board\board_common $PROJ_DIR$\..\..\..\..\..\..\software\lpc_core\lpc_board\boards_8xx\nxp_lpcxpresso_824 $PROJ_DIR$\..\..\..\..\..\..\software\CMSIS\CMSIS\Include |
4. Miscellaneous settings
For instance, target selecting, adds the linker file, add other c files (Fig 6),etc.
Fig 6
Table 1 main.c
/** * @brief Application main program * @return Nothing (This function will not return) */ int main(void) { /* Generic Initialization */ SystemCoreClockUpdate();
/*Set system clock div as 30*/ Chip_Clock_SetSysClockDiv(30);
/*Assign SCT_out to board LED pin*/ Chip_SWM_MovablePinAssign(SWM_SCT_OUT1_O, 13); // assign SCTOUT_0 to P0_13 YELLOW_LED Chip_SWM_MovablePinAssign(SWM_SCT_OUT2_O, 27); // assign SCTOUT_0 to P0_27 GREEN_LED Chip_SWM_MovablePinAssign(SWM_SCT_OUT0_O, 17); // assign SCTOUT_0 to P0_17 RED_LED
/* Initialize the SCT clock and reset the SCT */ Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SCT); Chip_SYSCTL_PeriphReset(RESET_SCT);
/*Initialize SCT*/ sct_fsm_init();
/* Start the SCT counter by clearing Halt_L in the SCT control register */ Chip_SCT_ClearControl(LPC_SCT, SCT_CTRL_HALT_L);
/* Enter sleep mode */ while (1) { __WFI(); } } |
Table 2 sct_fsm_init(void)
void sct_fsm_init (void) { /*The SCT operates as a unified 32-bit counter*/ LPC_SCT->CONFIG = (LPC_SCT->CONFIG & ~0x00060001) | 0x00000001; /* UNIFIED */
/* MATCH/CAPTURE registers */ LPC_SCT->REGMODE_L = 0x00000000;
LPC_SCT->MATCH[0].U = entry_mat; /* entry_match */ LPC_SCT->MATCHREL[0].U = entry_mat; LPC_SCT->MATCH[1].U = flash; /* flash_mat0 */ LPC_SCT->MATCHREL[1].U = flash; LPC_SCT->MATCH[2].U = flash1; /* flash_mat1 */ LPC_SCT->MATCHREL[2].U = flash1; LPC_SCT->MATCH[3].U = delay; /* match0 */ LPC_SCT->MATCHREL[3].U = delay; LPC_SCT->MATCH[4].U = yel_delay; /* yel_delay_mat */ LPC_SCT->MATCHREL[4].U = yel_delay; LPC_SCT->MATCH[5].U = yel_flash; /* yel_flash_mat */ LPC_SCT->MATCHREL[5].U = yel_flash;
/* OUTPUT registers */ /*Event 1 set the output*/ LPC_SCT->OUT[5].SET = 0x00000002; /* out_track */ /*Event 3 clear the output*/ LPC_SCT->OUT[5].CLR = 0x00000008; /*Event 0 and 3 set the output*/ LPC_SCT->OUT[2].SET = 0x00000009; /* turn_green */ /*Event 7 clear the output*/ LPC_SCT->OUT[2].CLR = 0x00000080; /*Event 1 set the output*/ LPC_SCT->OUT[0].SET = 0x00000002; /* turn_red */ /*Event 0 and 6 clear the output*/ LPC_SCT->OUT[0].CLR = 0x00000041; /*Event 0, 2, 4, 5, 6 and 7 set the output*/ LPC_SCT->OUT[1].SET = 0x000000F5; /* turn_yellow */ /*Event 1, 3, 4, 5 set the output*/ LPC_SCT->OUT[1].CLR = 0x0000003A; /* Unused outputs must not be affected by any event */ LPC_SCT->OUT[3].SET = 0; LPC_SCT->OUT[3].CLR = 0; LPC_SCT->OUT[4].SET = 0; LPC_SCT->OUT[4].CLR = 0;
/* Conflict resolution register */ LPC_SCT->RES = (LPC_SCT->RES & ~0x0000000C) | 0x0000000C;
/* Set COMBMODE = 0x1. Event 0 uses match condition only. Set STATEV bits to 1 and the STATED bit to 1. Event 0 changes the */ LPC_SCT->EV[0].CTRL = 0x0000D000; /* U: --> state RED */ LPC_SCT->EV[0].STATE = 0x00000001; /* Set COMBMODE = 0x1. Event 1 uses match condition only. Set STATEV bits to 2 and the STATED bit to 1. Event 1 changes the */ LPC_SCT->EV[1].CTRL = 0x00015003; /* U: --> state YELLOW */ LPC_SCT->EV[1].STATE = 0x00000002; /* Set COMBMODE = 0x1. Event 1 uses match condition only. Set STATEV bits to 4 and the STATED bit to 1. Event 1 changes the */ LPC_SCT->EV[2].CTRL = 0x00025004; /* U: --> state YELLOW_FLASH */ LPC_SCT->EV[2].STATE = 0x00000004; /* Set COMBMODE = 0x1. Event 1 uses match condition only. Set STATEV bits to 2 and the STATED bit to 1. Event 1 changes the */
LPC_SCT->EV[3].CTRL = 0x00015003; /* U: --> state YELLOW */ LPC_SCT->EV[3].STATE = 0x00000008; /* Set COMBMODE = 0x3. Event 6 uses when match and I/O condition occur. Set OUTSEL = 1. Select output. Set IOSEL = 5. Select output 5. Set STATEV bits to 1 and the STATED bit to 1. Event 1 changes the */ LPC_SCT->EV[6].CTRL = 0x0000F165; /* U: --> state RED */ LPC_SCT->EV[6].STATE = 0x00000010; /* Set COMBMODE = 0x3. Event 6 uses when match and I/O condition occur. Set OUTSEL = 1. Select output. Set IOSEL = 5. Select output 5. Set STATEV bits to 3 and the STATED bit to 1. Event 7 changes the */ LPC_SCT->EV[7].CTRL = 0x0001FD65; /* U: --> state GREEN */ LPC_SCT->EV[7].STATE = 0x00000010; /* Set COMBMODE = 0x1. Event 1 uses match condition only. Set STATEV bits to 4 and the STATED bit to 1. Event 1 changes the */ LPC_SCT->EV[4].CTRL = 0x00025001; /* U: --> state YELLOW_FLASH */ LPC_SCT->EV[4].STATE = 0x00000010; /* Set COMBMODE = 0x1. Event 1 uses match condition only. Set STATEV bits to 4 and the STATED bit to 1. Event 1 changes the */ LPC_SCT->EV[5].CTRL = 0x00025002; /* U: --> state YELLOW_FLASH */ LPC_SCT->EV[5].STATE = 0x00000010;
/* STATE registers */ LPC_SCT->STATE_L = 0;
/* state names assignment: */ /* State U 0: U_ENTRY */ /* State U 1: RED */ /* State U 2: YELLOW */ /* State U 3: GREEN */ /* State U 4: YELLOW_FLASH */
/* CORE registers */ LPC_SCT->START_L = 0x00000000; LPC_SCT->STOP_L = 0x00000000; LPC_SCT->HALT_L = 0x00000000; /* Event0, 1, 2, 3, 6 and 7 reset the counter register */ LPC_SCT->LIMIT_L = 0x000000CF; LPC_SCT->EVEN = 0x00000000; LPC_SCT->DMAREQ0 = 0x00000000; LPC_SCT->DMAREQ1 = 0x00000000;
} |
The demo runs on the LPCXpresso824-MAX board, and using the Blue led replaces the Yellow led, and the video shows the demo working.
Fig 7 LPCXpresso824-MAX board
Video's link:
I'm new to this kind of programming and this environment. I do understand that you are assigning GPIO pins to the SWM_CTL_OUT, but how do you get these hex values to talk to the actual pins? Because I'm working on an LPC824 and I try to toggle GPIO_17 on event 0, and this seems to fail.