[Xiaohei Embedded System Lesson 9] PSoC 5LP first experiment - LED and character LCD display experiment

Previous lesson:
[Xiaohei Embedded System Lesson 8] First introduction to PSoC Creator™ development - About PSoC Creator&Download, create projects, hello world in microcontroller (Light up an LED)
Next lesson:
[Xiaohei Embedded System Lesson 10] Overview of μC/OS-III - Real-time Operating System Features, basic concepts (kernel & tasks & interrupts), relationship with hardware & implementation


1 Experimental purpose

  • Master the basic process of PSoC 5LP entry project development;
  • Familiar with the main structure of the PSoC 5LP I/O system;
  • Be familiar with the structure of PSoC 5LP GPIO and master its input and output control methods;
  • Be familiar with the basic display control methods of character LCD modules;
  • Realize a basic human-machine interface composed of independent buttons, LED, and character LCD.

2 Experimental requirements

(1) Combined with the LED running water lamp example project, learn and become familiar with the basic structure of the PSoC 5LP I/O system, especially the structure of GPIO, and master the input and output control implementation method of GPIO;
(2) Combined with the HelloWorld_Blinky sample project that comes with the Creator software, learn and become familiar with the basic display control implementation method of the HD44780 character LCD module;
(3) Design a PSoC 5LP project, < /span>:Achieve the following functions

  • a. Able to correctly judge the pressed and released status of keys SW2 and SW3 (and eliminate the effect of jitter during key action through software delay re-judgment);
  • b. LED3 ~ LED2 flash at the same time (brightness can be adjusted. Tip: based on PWM principle);
  • c. Use SW2 to adjust the brightness of LED3. Each time you press it, the brightness increases or decreases by 1 level. Use LED4 to turn on to indicate that LED3 is currently at the lowest or highest brightness, and LED4 will be off at other brightnesses;
  • d. Use SW3 to adjust the brightness of LED2. Each time you press it, the brightness increases or decreases by 1 level. LED1 is on to indicate that LED2 is currently at the lowest brightness or highest brightness, and LED1 is off at other brightnesses;
  • e. The first line of the LCD displays the brightness percentage value of LED3, and the second line displays the brightness percentage value of LED2.

(4) The above functions can be fully implemented in software, or some functions can be implemented in hardware, such as button debounce (refer to application note AN60024) and LED display.
More display effects:
(5) Make the display of LCD content more friendly

3 Experimental equipment

CY8CKIT-050 Experimental Board
PC with PSoC Creator software installed

4 Experimental principles

1. LED brightness control based on PWM principle

This experiment requires the use of a digital I/O port to connect and control the LED. Since the digital output port can only output two levels, high and low, and cannot output an intermediate voltage, it cannot directly control the brightness of the LED, so the PWM method is used to achieve brightness control.

If the LED is fully lit for a period of time and then off for a period of time, this process repeats itself over and over again. If the repetition frequency is high enough (>60Hz), due to the persistence of vision phenomenon of the human eye, the human eye cannot distinguish the presence or absence of the LED. Blinking, the phenomenon you see is that the LED is always on at an intermediate brightness. The greater the proportion of full brightness to the entire cycle, the brighter the LED. This ratio is called the duty cycle (assuming it is bright when the high level is high), and its value The range is 0~100%. Obviously, when the duty cycle is 0, the LED is off, and when the duty cycle is 100%, the LED is at full brightness.

When we need the LED to turn on, we let the digital output port connected to it output a PWM waveform, so that the LED appears to be on with a certain brightness; when we need the LED to turn off, we let the digital output port output a low level (assuming low power). usually off). When the LED needs to flash, let these two processes be repeated alternately. The repetition frequency is set low enough (such as 1Hz) so that the human eye can see the LED flashing.

Schematic diagram of the brightness-controlled LED flashing principle:
Insert image description here
Brightness-controlled LED flashing waveform (the left picture shows one flash cycle, the right picture is an enlargement of part of the PWM waveform):

Insert image description here

2. Measurement of time

To measure the length of a period of time, a reference clock with a finer time granularity (such as a clock with a period of 1ms) is always needed.

(1) If you usehardware timer (Creator provides a timer component) to implement timing, provide this reference clock to the hardware Timer, the count value in the timer will increase (or decrease) synchronously with the reference clock, then the difference between the count values ​​at t1 and t2, multiplied by the reference clock period, is the length of time from t1 to t2. The need for time measurement is very common, and all processor chips will contain at least one hardware timer.

(2) If you simply use software to implement timing, you will inevitably think of using software delay functions. Creator provides < /span> functions, these delay functions are implemented by letting the CPU execute meaningless instructions to simply consume time. If the CPU only executes these delayed functions and is not interrupted by interrupts, then the delays are accurate. CyDelay(), CyDelayUs()

For the requirements of this experiment, on the one hand, when the LED is on (brightness is controlled), when the PWM waveform output is high and when the output is low, timing is required; on the other hand, the LED flashing effect, when the LED is on and when it is off, also needs to be timed. Timing is required. How does software use delay functions to implement various timing requirements? The program cannot always perform various delays, because other things cannot be processed during the delay period. Instead, it should construct a periodic reference clock modeled on the hardware timer. A reasonable implementation method is shown in Figure 3. In the main() function main loop, the code of software delay, task 1, task 2,...task m is added serially. If the execution time of all tasks is It is much less time-consuming than the delay code. The time-consuming of one main loop (one main loop cycle) is approximately equal to the time-consuming of the delay code. In this way, the main loop can be used as a reference clock for timing. If the program runs through n rounds of the main loop, the length of time it takes is: n * main loop period.

Of course, what needs to be reminded and easily seen is that the timing accuracy of this solution cannot be very high. Even if you want to take the execution time of each task into account to improve timing accuracy, it is difficult to do so, because when implementing a certain task, it is often difficult to achieve the same task execution time, but it will fluctuate with different branches of the task process. If there is an interrupt, the timing will be extended by interrupt processing and fluctuate. In short, this solution is suitable for less precise timing needs.

Insert image description here
Therefore, for timing the LED on (brightness controlled), you need to set a variable to count the number of main loop passes, which can be named tmr_pwm3 (similar to the hardware timer The count value in is equivalent); for the timing of LED flashing effect, you also need to set a variable to count the number of main loops passed, which can be named tmr_led3blink.

In addition, as shown in Figure 1, the high → low transition moment of the PWM waveform determines the duty cycle, which needs to be adjusted in the program, so a variable needs to be set, which can be named tmout_pwm3comp . The PWM waveform period and LED flashing period are generally fixed. In Figure 1, they are defined by macros TMOUT_PWMPRD and TMOUT_LED3BLINKPRD respectively, and the unit is the main cycle period.

3. Elimination of the effects of key jitter

Due to the poor contact of the contact piece, a mechanical button will repeatedly switch on and off within a short period of time when it is pressed or released, which is calledButton jitter< /span>. The duration of the key jitter period is generally **<20ms**, and then the key is in a stable on or off state. The button status waveform is shown in Figure 4.

In order to eliminate the impact of button jitter, a simple and effective method is to regularly sample the button status (the sampling period needs to be greater than the jitter duration, generally 20ms). This method can be implemented in software or hardware. As shown in Figure 4, each grid of the waveform is 10ms, and the arrow represents the sampling time and sampling value. It is obvious that the various sampling value sequences in the figure only appear once 1→0, corresponding to one button press (assuming (high level when the key is released) action, thus eliminating the effect of key jitter.

Insert image description here
It can be concluded from the above that as long as the current sampling value of the key (sw2_cur) and the previous sampling value (sw2_prev) are recorded, the current The key status includes continuous release (sw2_prev=1 and sw2_cur=1), pressing action (sw2_prev=1 and sw2_cur=0), continuous pressing (sw2_prev=0 and sw2_cur=0), release action occurs (sw2_prev=0 and a>sw2_cur=1).

When is it necessary to perform key sampling to read the key status? Timing is required. If you simply use software to implement this timing, as described in Section "1.2.(2)", you also need to set a variable to count the number of main loops passed, which can be named tmr_debouncer, if the sampling period is fixed, you can use the macro TMOUT_DEBOUNCER to define it (the unit is the main cycle period) .

5 Design Implementation

(1) Hardware connection:

TopDesign:

Insert image description here
Insert image description here

PWM1 and PWM2 control the brightness and flicker of LED2 and LED3 respectively. When the button is pressed, the button outputs an interrupt through pin SW2 or SW3. The interrupt program adjusts the duty cycle of the PWM output and outputs it to the pins of LED3 and LED2 to realize LED3 and LED2. The brightness changes, and the LCD displays characters related to the LED brightness.

(1) Output port

Configure 4 identical output ports, corresponding to four LED lights respectively. Two provide external physical connections and are connected to the PWM output (LED_2, LED_3) to adjust the brightness. Two ports are left floating, corresponding to the two indicator lights (LED_1, LED_4). Set the initial state to low level to increase the external current sink for the LED later.

Insert image description here

(2) Input port

Configure two input ports corresponding to two buttons (SW_2, SW_3), connect two interrupts, the interrupt source is whether the button is pressed, software debouncing is required here, which can increase the recognition accuracy of button actions. When a button press is detected When down, an interrupt is generated and fed back to PWM for action.

Insert image description here

(3) PWM module

Configure two PWM modules (PWM1, PWM2). pwm1 and pwm2 control the brightness and flicker of LED2 and LED3 respectively. Because I want to realize the LED brightness from low to high later, the initial duty cycle is set to 0. In the program, 25% four-level increase, increasing the clock for PWM counting and timing.

Insert image description here

(2) Software design

1 Overall design

Insert image description here

  1. CyGlobalIntEnable;
    Enables global interrupts and allows interrupt events to trigger handlers.
    2.uint8_t led3_brightness = 0;
    uint8_t led2_brightness = 0;
    Initialize the brightness of LED3 and LED2 to 0, that is, initial In this state, the LED light is off.
  2. LCD_Char_Start();
    LCD_Char_Position(0, 0);
    LCD_Char_PrintString(“LED3 Bright:”);
    LCD_Char_Position(1,0);
    LCD_Char_PrintString("LED2 Bright:");
    Start the LCD display and display "LED3 Bright" on the first line :", displays "LED2 Bright:" on the second line.
  3. PWM_1_Start();
    PWM_2_Start();
    Start the PWM module to control the brightness of the LED.
  4. if(!SW_2_Read()) // If SW2 is pressed
    Detect whether the SW2 button is pressed.
  5. led3_brightness+=25;
    PWM_1_WriteCompare(led3_brightness);
    Increase the brightness of LED3 and set the new brightness value to the duty cycle of PWM , thereby controlling the brightness of LED3.
    7.while(!SW_2_Read());
    Wait for the key to be released to avoid key jitter.
  6. if(led3_brightness == 100)
    { LED_4_Write(1); } When the brightness of LED3 reaches 100%, light up another LED (LED4) .


  7. The same operation and logic applies to LED2 and SW3.
  8. LCD_Char_Position(0, 12);
    LCD_Char_PrintNumber(led3_brightness);
    LCD_Char_PrintString(“%”);
    Used to update the LCD display to display the brightness percentage of LED3.
  9. CyDelay(100); // Delay to eliminate key jitter
    Introduce delay to eliminate key jitter.

2 Detailed design

#include <project.h>
#include <stdio.h>

int main()
{
    
    
    CyGlobalIntEnable; /* Enable global interrupts. */

    uint8_t led3_brightness = 0; // 初始化LED3亮度为50%
    uint8_t led2_brightness = 0; // 初始化LED2亮度为50%
    
    LCD_Char_Start(); // 启动LCD
    LCD_Char_Position(0, 0);
    LCD_Char_PrintString("LED3 Bright:");
    LCD_Char_Position(1,0);
    LCD_Char_PrintString("LED2 Bright:");

    PWM_1_Start();
    PWM_2_Start();
    for(;;)
    {
    
    
        if(!SW_2_Read()) // 如果按下SW2
        {
    
    
            if(led3_brightness < 100) // 增加LED3亮度
            {
    
    
                led3_brightness+=25;
                PWM_1_WriteCompare(led3_brightness); // 设置PWM占空比
            }
            while(!SW_2_Read()); // 等待按键释放
            if(led3_brightness == 100)
            {
    
    
                LED_4_Write(1);
            }
        }
        
        if(!SW_3_Read()) // 如果按下SW3
        {
    
    
            if(led2_brightness < 100) // 增加LED2亮度
            {
    
    
                led2_brightness+=25;
                PWM_2_WriteCompare(led2_brightness); // 设置PWM占空比
            }
            while(!SW_3_Read()); // 等待按键释放
            if(led2_brightness == 100)
            {
    
    
                LED_1_Write(1);
            }
            
        }
        
        // 更新LCD显示
        LCD_Char_Position(0, 12);
        LCD_Char_PrintNumber(led3_brightness);
        LCD_Char_PrintString("%");
        
        LCD_Char_Position(1, 12);
        LCD_Char_PrintNumber(led2_brightness);
        LCD_Char_PrintString("%");
        
        CyDelay(100); // 延时消除按键抖动
    }
}

6 Testing and Analysis

(1)Initial state: All four LED lights are off, and the brightness of LED2 and LED3 is displayed on the LCD as 0% .

Insert image description here
(2)Brightness increase stage: SW2 and SW3 control the brightness of LED3 and LED2 respectively, each time the brightness increases by 25%, as follows You can see the difference in brightness between the two photos.

Insert image description here
Insert image description here
(3)Maximum brightness stage: When the brightness of LED2 reaches the maximum, the LED1 prompt light will light up. When the brightness of LED3 reaches the maximum, , the LED4 reminder light will light up.

Insert image description here

Guess you like

Origin blog.csdn.net/Goforyouqp/article/details/134511393