kl46z problem with the LCD

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

kl46z problem with the LCD

1,498 Views
floridjam
Contributor II

Hi,

I'am currently programming with my freedom kl46z board and I spend a few day trying to use the LCD.

First I find on the internet a library that allow to use the LCD in very simple mode on this website :

https://eewiki.net/display/microcontroller/Using+the+Segment+LCD+Controller+on+the+Kinetis+KL46 

This code work when I implement it on an example like hello world. But when I do an empty project the code don't work at all. I suspect I forget to initialize something but I can't figure out what.

In my project I'am able to use the Led and switch but the LCD don't want to work. 

I hope I have been clear if not please ask me question.

Tags (1)
5 Replies

1,062 Views
floridjam
Contributor II

Thanks a lot for your answer. It works now !

0 Kudos

1,062 Views
kerryzhou
NXP TechSupport
NXP TechSupport

OK, if your problem is solved, please help us to mark the correct answer  to close this case.

Thank you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,062 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Florian,

     About the SLCD code for FRDM-KL46, you also can refer to the sample code for FRDM-KL46, please download the code from this link:

http://cache.nxp.com/files/32bit/software/KL46_SC.exe 

  After you install it, you can find the SLCD code in folder:kinetis_kl46_sc_rev2\klxx-sc-baremetal\build\iar\sLCD_freedom

  This code is very simple to understand and transplant.

If you still meet problem, just contact me!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,062 Views
mjbcswitzerland
Specialist V

Hi

See
http://www.utasker.com/kinetis/FRDM-KL46Z.html
http://www.utasker.com/kinetis/TWR-KL46Z48M.html
and
http://www.utasker.com/docs/uTasker/uTasker_SLCD.pdf
and
https://www.youtube.com/watch?v=nm2DmZv1rj8

With these nothing can go wrong. Possibly when you mix examples you have indeed skipped some initialiation but also it may be that there are port conflicts.

Regards

Mark
Kinetis for professionals: http://www.utasker.com/kinetis.html

1,062 Views
mjbcswitzerland
Specialist V

As reference - this is initialisation code for the SLCD on the FRDM-KL46

// Use MCGIRCLK (fast IRC) as SLCD source
//
#define CONFIGURE_SLCD()      MCG_C1 &= ~(MCG_C1_IREFS); MCG_C1 |= (MCG_C1_IRCLKEN | MCG_C1_IREFSTEN); \
                              POWER_UP(5, SIM_SCGC5_SLCD); \
                              LCD_GCR = (LCD_GCR_RVEN | (0x08000000 & LCD_GCR_RVTRIM_MASK) | LCD_GCR_CPSEL | LCD_GCR_LADJ_MASK | LCD_GCR_VSUPPLY | LCD_GCR_SOURCE | LCD_GCR_LCLK_1 | LCD_GCR_DUTY_4BP); \
                              LCD_AR = (LCD_AR_BRATE_MASK & 3); \
                              LCD_BPENL = (SLCD_PIN_19 | SLCD_PIN_18); \
                              LCD_BPENH = (SLCD_PIN_H_52 | SLCD_PIN_H_40); \
                              LCD_PENL = ((SLCD_PIN_17 | SLCD_PIN_11 | SLCD_PIN_10 | SLCD_PIN_8 | SLCD_PIN_7) | (SLCD_PIN_19 | SLCD_PIN_18)); \
                              LCD_PENH = ((SLCD_PIN_H_53 | SLCD_PIN_H_38 | SLCD_PIN_H_37) | (SLCD_PIN_H_52 | SLCD_PIN_H_40)); \
                              fnClearSLCD(); \
                              WRITE_SLCD(43TO40, 0x00000001); \
                              WRITE_SLCD(55TO52, 0x00000002); \
                              WRITE_SLCD(19TO16, 0x04080000); \
                              LCD_GCR = (LCD_GCR_LCDEN | LCD_GCR_RVEN | (0x08000000 & LCD_GCR_RVTRIM_MASK) | LCD_GCR_CPSEL | LCD_GCR_LADJ_MASK | LCD_GCR_VSUPPLY | LCD_GCR_SOURCE | LCD_GCR_LCLK_1 | LCD_GCR_DUTY_4BP)

// The SLCD controller may retain segment settings across resets so this initialisation routine is used to ensure all are cleared when starting
//
extern void fnClearSLCD(void)
{
    unsigned long *ptrSegments = LCD_WF3TO0_ADDR;
    int i = 0;
    while (i++ < SEGMENT_REGISTER_COUNT) {
        *ptrSegments++ = 0;
    }
}

And the following is a clock display updated every second by a 1s interrupt (eg. from RTC)

static void _rtc_second_interrupt(void)                                  // seconds interrupt call-back handler
{
    RTC_SETUP rtc_setup;
    rtc_setup.command = RTC_GET_TIME;
    fnConfigureRTC(&rtc_setup);                                          // get the present time
    if (IS_POWERED_UP(5, SIM_SCGC5_SLCD)) {                              // display time as long as the SLCD has been enabled
        fnTimeDisplay(rtc_setup.ucHours, rtc_setup.ucMinutes, rtc_setup.ucSeconds);
    }
}

with the complete SLCD code below to allow digits to be simply displayed.

// Register LCD_WF19TO16 and LCD_WF39TO36 (tens of hours)
//
#define SEVEN_SEGMENT_0_TOP         0x00000800                           // 17-8
#define SEVEN_SEGMENT_0_MID         0x00000400                           // 37-4
#define SEVEN_SEGMENT_0_BOT         0x00000100                           // 37-1
#define SEVEN_SEGMENT_0_T_L         0x00000800                           // 37-8
#define SEVEN_SEGMENT_0_B_L         0x00000200                           // 37-2
#define SEVEN_SEGMENT_0_T_R         0x00000400                           // 17-4
#define SEVEN_SEGMENT_0_B_R         0x00000200                           // 17-2

#define SEVEN_SEGMENT_0_17          (SEVEN_SEGMENT_0_TOP | SEVEN_SEGMENT_0_T_R | SEVEN_SEGMENT_0_B_R)
#define SEVEN_SEGMENT_0_37          (SEVEN_SEGMENT_0_MID | SEVEN_SEGMENT_0_BOT | SEVEN_SEGMENT_0_T_L | SEVEN_SEGMENT_0_B_L)
#define SEVEN_SEGMENT_0_0           (SEVEN_SEGMENT_0_17 | SEVEN_SEGMENT_0_37)

#define SEVEN_SEGMENT_0_1           (SEVEN_SEGMENT_0_T_R | SEVEN_SEGMENT_0_B_R)
#define SEVEN_SEGMENT_0_2           ((SEVEN_SEGMENT_0_TOP | SEVEN_SEGMENT_0_T_R | SEVEN_SEGMENT_0_MID | SEVEN_SEGMENT_0_B_L | SEVEN_SEGMENT_0_BOT) & SEVEN_SEGMENT_0_17)


// Register LCD_WF11TO8 and LCD_WF7TO4 (hours)
//
#define SEVEN_SEGMENT_1_TOP         0x00000008                           // 8-8
#define SEVEN_SEGMENT_1_MID         0x04000000                           // 7-4
#define SEVEN_SEGMENT_1_BOT         0x01000000                           // 7-1
#define SEVEN_SEGMENT_1_T_L         0x08000000                           // 7-8
#define SEVEN_SEGMENT_1_B_L         0x02000000                           // 7-2
#define SEVEN_SEGMENT_1_T_R         0x00000004                           // 8-4
#define SEVEN_SEGMENT_1_B_R         0x00000002                           // 8-2

#define SEVEN_SEGMENT_1__7          (SEVEN_SEGMENT_1_MID | SEVEN_SEGMENT_1_BOT | SEVEN_SEGMENT_1_T_L | SEVEN_SEGMENT_1_B_L)
#define SEVEN_SEGMENT_1__8          (SEVEN_SEGMENT_1_TOP | SEVEN_SEGMENT_1_T_R | SEVEN_SEGMENT_1_B_R)
#define SEVEN_SEGMENT_1             (SEVEN_SEGMENT_1__7 | SEVEN_SEGMENT_1__8)

#define SEVEN_SEGMENT_1_0           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_MID))
#define SEVEN_SEGMENT_1_1           (SEVEN_SEGMENT_1_T_R | SEVEN_SEGMENT_1_B_R)
#define SEVEN_SEGMENT_1_2           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_T_L | SEVEN_SEGMENT_1_B_R))
#define SEVEN_SEGMENT_1_3           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_T_L | SEVEN_SEGMENT_1_B_L))
#define SEVEN_SEGMENT_1_4           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_TOP | SEVEN_SEGMENT_1_B_L | SEVEN_SEGMENT_1_BOT))
#define SEVEN_SEGMENT_1_5           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_B_L | SEVEN_SEGMENT_1_T_R))
#define SEVEN_SEGMENT_1_6           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_T_R))
#define SEVEN_SEGMENT_1_7           (SEVEN_SEGMENT_1_T_R | SEVEN_SEGMENT_1_B_R | SEVEN_SEGMENT_1_TOP)
#define SEVEN_SEGMENT_1_8           SEVEN_SEGMENT_1
#define SEVEN_SEGMENT_1_9           (SEVEN_SEGMENT_1 & ~(SEVEN_SEGMENT_1_B_L))

// Registers LCD_WF39TO36 and LCD_WF55TO52 (tens of minutes)
//
#define SEVEN_SEGMENT_2_TOP         0x00080000                           // 38-8
#define SEVEN_SEGMENT_2_MID         0x00000400                           // 53-4
#define SEVEN_SEGMENT_2_BOT         0x00000100                           // 53-1
#define SEVEN_SEGMENT_2_T_L         0x00000800                           // 53-8
#define SEVEN_SEGMENT_2_B_L         0x00000200                           // 53-2
#define SEVEN_SEGMENT_2_T_R         0x00040000                           // 38-4
#define SEVEN_SEGMENT_2_B_R         0x00020000                           // 38-2

#define SEVEN_SEGMENT_2_38          (SEVEN_SEGMENT_2_TOP | SEVEN_SEGMENT_2_T_R | SEVEN_SEGMENT_2_B_R)
#define SEVEN_SEGMENT_2_53          (SEVEN_SEGMENT_2_MID | SEVEN_SEGMENT_2_BOT | SEVEN_SEGMENT_2_T_L | SEVEN_SEGMENT_2_B_L)
#define SEVEN_SEGMENT_2             (SEVEN_SEGMENT_2_38 | SEVEN_SEGMENT_2_53)

#define SEVEN_SEGMENT_2_0           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_MID))
#define SEVEN_SEGMENT_2_1           (SEVEN_SEGMENT_2_T_R | SEVEN_SEGMENT_2_B_R)
#define SEVEN_SEGMENT_2_2           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_T_L | SEVEN_SEGMENT_2_B_R))
#define SEVEN_SEGMENT_2_3           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_T_L | SEVEN_SEGMENT_2_B_L))

#define SEVEN_SEGMENT_2_4           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_TOP | SEVEN_SEGMENT_2_B_L | SEVEN_SEGMENT_2_BOT))

#define SEVEN_SEGMENT_2_5           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_B_L | SEVEN_SEGMENT_2_T_R))

#define SEVEN_SEGMENT_2_6           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_T_R))

#define SEVEN_SEGMENT_2_7           (SEVEN_SEGMENT_2_T_R | SEVEN_SEGMENT_2_B_R | SEVEN_SEGMENT_2_TOP)
#define SEVEN_SEGMENT_2_8           (SEVEN_SEGMENT_2)
#define SEVEN_SEGMENT_2_9           (SEVEN_SEGMENT_2 & ~(SEVEN_SEGMENT_2_B_L))

// Register LCD_WF11TO8 (minutes)
//
#define SEVEN_SEGMENT_3_TOP         0x08000000                           // 11-8
#define SEVEN_SEGMENT_3_MID         0x00040000                           // 10-4
#define SEVEN_SEGMENT_3_BOT         0x00010000                           // 10-1
#define SEVEN_SEGMENT_3_T_L         0x00080000                           // 10-8
#define SEVEN_SEGMENT_3_B_L         0x00020000                           // 10-2
#define SEVEN_SEGMENT_3_T_R         0x04000000                           // 11-4
#define SEVEN_SEGMENT_3_B_R         0x02000000                           // 11-2

#define SEGMENT_COLON               0x01

#define SEVEN_SEGMENT_3             (SEVEN_SEGMENT_3_TOP | SEVEN_SEGMENT_3_MID | SEVEN_SEGMENT_3_BOT | SEVEN_SEGMENT_3_T_L | SEVEN_SEGMENT_3_B_L | SEVEN_SEGMENT_3_T_R | SEVEN_SEGMENT_3_B_R)

#define SEVEN_SEGMENT_3_0           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_MID))
#define SEVEN_SEGMENT_3_1           (SEVEN_SEGMENT_3_T_R | SEVEN_SEGMENT_3_B_R)
#define SEVEN_SEGMENT_3_2           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_T_L | SEVEN_SEGMENT_3_B_R))
#define SEVEN_SEGMENT_3_3           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_T_L | SEVEN_SEGMENT_3_B_L))
#define SEVEN_SEGMENT_3_4           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_TOP | SEVEN_SEGMENT_3_B_L | SEVEN_SEGMENT_3_BOT))
#define SEVEN_SEGMENT_3_5           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_B_L | SEVEN_SEGMENT_3_T_R))
#define SEVEN_SEGMENT_3_6           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_T_R))
#define SEVEN_SEGMENT_3_7           (SEVEN_SEGMENT_3_T_R | SEVEN_SEGMENT_3_B_R | SEVEN_SEGMENT_3_TOP)
#define SEVEN_SEGMENT_3_8           SEVEN_SEGMENT_3
#define SEVEN_SEGMENT_3_9           (SEVEN_SEGMENT_3 & ~(SEVEN_SEGMENT_3_B_L))


static const unsigned long ulSegment1[] = {                             // hours 0..9
    SEVEN_SEGMENT_1_0,
    SEVEN_SEGMENT_1_1,
    SEVEN_SEGMENT_1_2,
    SEVEN_SEGMENT_1_3,
    SEVEN_SEGMENT_1_4,
    SEVEN_SEGMENT_1_5,
    SEVEN_SEGMENT_1_6,
    SEVEN_SEGMENT_1_7,
    SEVEN_SEGMENT_1_8,
    SEVEN_SEGMENT_1_9,
};

static const unsigned long ulSegment2[] = {                              // tens of minutes 0..5
    SEVEN_SEGMENT_2_0,
    SEVEN_SEGMENT_2_1,
    SEVEN_SEGMENT_2_2,
    SEVEN_SEGMENT_2_3,
    SEVEN_SEGMENT_2_4,
    SEVEN_SEGMENT_2_5,
};

static const unsigned long ulSegment3[] = {                              // minutes 0..9
    (SEVEN_SEGMENT_3_0 >> 0),
    (SEVEN_SEGMENT_3_1 >> 0),
    (SEVEN_SEGMENT_3_2 >> 0),
    (SEVEN_SEGMENT_3_3 >> 0),
    (SEVEN_SEGMENT_3_4 >> 0),
    (SEVEN_SEGMENT_3_5 >> 0),
    (SEVEN_SEGMENT_3_6 >> 0),
    (SEVEN_SEGMENT_3_7 >> 0),
    (SEVEN_SEGMENT_3_8 >> 0),
    (SEVEN_SEGMENT_3_9 >> 0),
};

static void fnTimeDisplay(unsigned char ucHours, unsigned char ucMinutes, unsigned char ucSeconds)
{
    unsigned long ulRegister;
    
    ulRegister = LCD_WF19TO16;
    ulRegister &= ~(SEVEN_SEGMENT_0_17);
    switch (ucHours/10) {
    case 1:
        ulRegister |= (SEVEN_SEGMENT_0_B_R | SEVEN_SEGMENT_0_T_R);       // set the tens of hours ('1')
        break;
    case 2:
        ulRegister |= (SEVEN_SEGMENT_0_TOP | SEVEN_SEGMENT_0_T_R);       // set the tens of hours ('2')
        break;
    }
    WRITE_SLCD(19TO16, ulRegister);                                      // tens of hours (part 1)
    ulRegister = LCD_WF39TO36;
    ulRegister &= ~(SEVEN_SEGMENT_0_37);
    switch (ucHours/10) {
    case 2:
        ulRegister |= (SEVEN_SEGMENT_0_MID | SEVEN_SEGMENT_0_B_L | SEVEN_SEGMENT_0_BOT); // set the tens of hours ('2')
        break;
    }
    WRITE_SLCD(39TO36, ulRegister);                                      // tens of hours (part 2)

    ucHours -= ((ucHours/10) * 10);
    ulRegister = LCD_WF7TO4;
    ulRegister &= ~(SEVEN_SEGMENT_1__7);
    ulRegister |= (ulSegment1[ucHours] & SEVEN_SEGMENT_1__7);            // set the hours
    WRITE_SLCD(7TO4, ulRegister);                                        // hours (part 1)

    ulRegister = LCD_WF11TO8;
    ulRegister &= ~(SEVEN_SEGMENT_1__8);
    ulRegister |= (ulSegment1[ucHours] & SEVEN_SEGMENT_1__8);            // set the hours
    WRITE_SLCD(11TO8, ulRegister);                                       // hours (part 2)

    ulRegister = LCD_WF39TO36;
    ulRegister &= ~(SEVEN_SEGMENT_2_38);
    ulRegister |= (ulSegment2[ucMinutes/10] & SEVEN_SEGMENT_2_38);       // set the tens of minutes
    WRITE_SLCD(39TO36, ulRegister);                                      // tens of minutes (part 1)
    ulRegister = LCD_WF55TO52;
    ulRegister &= ~(SEVEN_SEGMENT_2_53);
    ulRegister |= (ulSegment2[ucMinutes/10] & SEVEN_SEGMENT_2_53);       // set the tens of minutes
    WRITE_SLCD(55TO52, ulRegister);                                      // tens of minutes (part 2)

    ulRegister = LCD_WF11TO8;
    ulRegister &= ~(SEVEN_SEGMENT_3);
    ucMinutes -= ((ucMinutes/10) * 10);
    ulRegister |= ulSegment3[ucMinutes];
    WRITE_SLCD(11TO8, ulRegister);                                       // minutes
    TOGGLE_SLCD(11, SEGMENT_COLON);                                      // toggle ':'
}

And finally, what it looks like when run in the uTasker simulator:

pastedImage_2.png

Regards

Mark