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 Theia、我当前正在尝试将16x2 LCD 与 LaunchPad MSPM0G3507板连接。
我不能使它完美的工作,因为我尝试了许多不同的方法在互联网上.
我面临的问题是我可以打印数字和符号、但不能打印任何字符。
正如您在代码中看到的、我要打印这两份文件、但都无法正常工作。
是由于时序问题导致它无法正常工作或其他问题。
如果您能够在此找到任何解决方案、或者您已经知道任何可正常使用的示例代码、请告诉我。
这是我的当前代码、但它不起作用。
/* * Copyright (c) 2020, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ti/devices/msp/m0p/mspm0g350x.h" #include "ti/driverlib/m0p/dl_core.h" #include "ti/driverlib/m0p/dl_systick.h" #include "ti_msp_dl_config.h" #include <machine/_stdint.h> #include <sys/_stdint.h> /* Pin definitions (customize based on your hardware) */ #define RS_PIN GPIO_GRP_0_RS_PIN // Example: Port 1, Pin 0 #define ENABLE_PIN GPIO_GRP_0_E_PIN // Example: Port 1, Pin 1 #define D4_PIN GPIO_GRP_0_D4_PIN // Example: Port 1, Pin 2 #define D5_PIN GPIO_GRP_0_D5_PIN // Example: Port 1, Pin 3 #define D6_PIN GPIO_GRP_0_D6_PIN // Example: Port 1, Pin 4 #define D7_PIN GPIO_GRP_0_D7_PIN // Example: Port 1, Pin 5 #define HIGH 1 #define LOW 0 #define LCD_PORT GPIO_GRP_0_PORT // Example: GPIO Port A #define MAX_TICKS 0xFFFFFF // Maximum ticks for SysTick (24-bit) /* Function prototypes */ void delayMiliseconds(uint32_t milliseconds); void delayMicroseconds(uint32_t microseconds); void digitalWrite(uint32_t pins, uint8_t state); // Function prototypes void LCD_Command(unsigned char cmd); void LCD_Data(unsigned char data); void LCD_Init(void); void LCD_String(char *str); void LCD_Clear(); int main(void) { SYSCFG_DL_init(); LCD_Init(); while (1) { DL_GPIO_togglePins(GPIO_GRP_1_PORT, GPIO_GRP_1_PIN_0_PIN); delayMiliseconds(3000); LCD_String("88"); LCD_Data(41); // Corresponding to 'A' in 4-bit mode delayMiliseconds(3000); LCD_Clear(); } } void delayMiliseconds(uint32_t milliseconds) { uint32_t ticks_per_ms = CPUCLK_FREQ / 1000; uint32_t max_delay_ms = MAX_TICKS / ticks_per_ms; while (milliseconds > 0) { uint32_t delayMiliseconds = (milliseconds > max_delay_ms) ? max_delay_ms : milliseconds; uint32_t ticks = delayMiliseconds * ticks_per_ms; DL_SYSTICK_init(ticks); DL_SYSTICK_enable(); // Wait until the COUNTFLAG is set while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) ; DL_SYSTICK_disable(); milliseconds -= delayMiliseconds; } } void delayMicroseconds(uint32_t microseconds) { uint32_t ticks = microseconds * (CPUCLK_FREQ / 1000000); // Ensure the reload value is within 24-bit range if (ticks > 0xFFFFFF) ticks = 0xFFFFFF; DL_SYSTICK_init(ticks); // Start SysTick DL_SYSTICK_enable(); // Wait until the COUNTFLAG is set while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) ; // Stop SysTick DL_SYSTICK_disable(); } void digitalWrite(uint32_t pins, uint8_t state) { if (state == HIGH) { DL_GPIO_setPins(LCD_PORT, pins); } else if (state == LOW) { DL_GPIO_clearPins(LCD_PORT, pins); } else { } } void LCD_Command(unsigned char cmd) { // Send the higher nibble digitalWrite(D4_PIN, (cmd & 0x10) >> 4); digitalWrite(D5_PIN, (cmd & 0x20) >> 5); digitalWrite(D6_PIN, (cmd & 0x40) >> 6); digitalWrite(D7_PIN, (cmd & 0x80) >> 7); digitalWrite(RS_PIN, LOW); // Command mode digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(1); // Send the lower nibble digitalWrite(D4_PIN, cmd & 0x01); digitalWrite(D5_PIN, (cmd & 0x02) >> 1); digitalWrite(D6_PIN, (cmd & 0x04) >> 2); digitalWrite(D7_PIN, (cmd & 0x08) >> 3); digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(30); } void LCD_Data(unsigned char data) { // Send the higher nibble digitalWrite(D4_PIN, (data & 0x10) >> 4); digitalWrite(D5_PIN, (data & 0x20) >> 5); digitalWrite(D6_PIN, (data & 0x40) >> 6); digitalWrite(D7_PIN, (data & 0x80) >> 7); digitalWrite(RS_PIN, HIGH); // Data mode digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(1); // Send the lower nibble digitalWrite(D4_PIN, data & 0x01); digitalWrite(D5_PIN, (data & 0x02) >> 1); digitalWrite(D6_PIN, (data & 0x04) >> 2); digitalWrite(D7_PIN, (data & 0x08) >> 3); digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(30); } void LCD_Init(void) { delayMiliseconds(50); digitalWrite(RS_PIN, LOW); // RS = 0 digitalWrite(ENABLE_PIN, LOW); // EN = 0 // // Initialize LCD in 4-bit mode LCD_Command(0x02); // Function set: Initialize LCD_Command(0x28); // Function set: 4-bit mode LCD_Command(0x01); // 2-line display, 5x8 dots LCD_Command(0x0c); // Display ON, Cursor OFF, Blink OFF LCD_Command(0x06); // Entry mode: Increment cursor } void LCD_String(char *str) { while (*str) { LCD_Data(*str++); } } void LCD_Clear() { LCD_Command(0x01); /*clear display screen*/ delayMiliseconds(3); }
我发现了这个问题、它与命令的时序有关。
我随附了更新后的代码。
/* * Copyright (c) 2020, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ti/devices/msp/m0p/mspm0g350x.h" #include "ti/driverlib/m0p/dl_core.h" #include "ti/driverlib/m0p/dl_systick.h" #include "ti_msp_dl_config.h" #include <machine/_stdint.h> #include <sys/_stdint.h> /* Pin definitions (customize based on your hardware) */ #define RS_PIN GPIO_GRP_0_RS_PIN // Example: Port 1, Pin 0 #define ENABLE_PIN GPIO_GRP_0_E_PIN // Example: Port 1, Pin 1 #define D4_PIN GPIO_GRP_0_D4_PIN // Example: Port 1, Pin 2 #define D5_PIN GPIO_GRP_0_D5_PIN // Example: Port 1, Pin 3 #define D6_PIN GPIO_GRP_0_D6_PIN // Example: Port 1, Pin 4 #define D7_PIN GPIO_GRP_0_D7_PIN // Example: Port 1, Pin 5 #define HIGH 1 #define LOW 0 #define LCD_PORT GPIO_GRP_0_PORT // Example: GPIO Port A #define MAX_TICKS 0xFFFFFF // Maximum ticks for SysTick (24-bit) /* Function prototypes */ void delayMiliseconds(uint32_t milliseconds); void delayMicroseconds(uint32_t microseconds); void digitalWrite(uint32_t pins, uint8_t state); // Function prototypes void LCD_Command(unsigned char cmd); void LCD_Data(unsigned char data); void LCD_Init(void); void LCD_String(char *str); void LCD_Clear(); int main(void) { SYSCFG_DL_init(); LCD_Init(); while (1) { DL_GPIO_togglePins(GPIO_GRP_1_PORT, GPIO_GRP_1_PIN_0_PIN); delayMiliseconds(3000); LCD_String("Hello Abhinav"); delayMiliseconds(3000); LCD_Clear(); } } void delayMiliseconds(uint32_t milliseconds) { uint32_t ticks_per_ms = CPUCLK_FREQ / 1000; uint32_t max_delay_ms = MAX_TICKS / ticks_per_ms; while (milliseconds > 0) { uint32_t delayMiliseconds = (milliseconds > max_delay_ms) ? max_delay_ms : milliseconds; uint32_t ticks = delayMiliseconds * ticks_per_ms; DL_SYSTICK_init(ticks); DL_SYSTICK_enable(); // Wait until the COUNTFLAG is set while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) ; DL_SYSTICK_disable(); milliseconds -= delayMiliseconds; } } void delayMicroseconds(uint32_t microseconds) { uint32_t ticks = microseconds * (CPUCLK_FREQ / 1000000); // Ensure the reload value is within 24-bit range if (ticks > 0xFFFFFF) ticks = 0xFFFFFF; DL_SYSTICK_init(ticks); // Start SysTick DL_SYSTICK_enable(); // Wait until the COUNTFLAG is set while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) ; // Stop SysTick DL_SYSTICK_disable(); } void digitalWrite(uint32_t pins, uint8_t state) { if (state == HIGH) { DL_GPIO_setPins(LCD_PORT, pins); } else if (state == LOW) { DL_GPIO_clearPins(LCD_PORT, pins); } else { } } void LCD_Command(unsigned char cmd) { // Send the higher nibble digitalWrite(D4_PIN, (cmd & 0x10) >> 4); delayMicroseconds(1); digitalWrite(D5_PIN, (cmd & 0x20) >> 5); delayMicroseconds(1); digitalWrite(D6_PIN, (cmd & 0x40) >> 6); delayMicroseconds(1); digitalWrite(D7_PIN, (cmd & 0x80) >> 7); delayMicroseconds(1); digitalWrite(RS_PIN, LOW); // Command mode delayMicroseconds(1); digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(1); // Send the lower nibble digitalWrite(D4_PIN, cmd & 0x01); delayMicroseconds(1); digitalWrite(D5_PIN, (cmd & 0x02) >> 1); delayMicroseconds(1); digitalWrite(D6_PIN, (cmd & 0x04) >> 2); delayMicroseconds(1); digitalWrite(D7_PIN, (cmd & 0x08) >> 3); delayMicroseconds(1); digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(30); } void LCD_Data(unsigned char data) { // Send the higher nibble digitalWrite(D4_PIN, (data & 0x10) >> 4); delayMicroseconds(1); digitalWrite(D5_PIN, (data & 0x20) >> 5); delayMicroseconds(1); digitalWrite(D6_PIN, (data & 0x40) >> 6); delayMicroseconds(1); digitalWrite(D7_PIN, (data & 0x80) >> 7); delayMicroseconds(1); digitalWrite(RS_PIN, HIGH); // Data mode digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(1); // Send the lower nibble digitalWrite(D4_PIN, data & 0x01); delayMicroseconds(1); digitalWrite(D5_PIN, (data & 0x02) >> 1); delayMicroseconds(1); digitalWrite(D6_PIN, (data & 0x04) >> 2); delayMicroseconds(1); digitalWrite(D7_PIN, (data & 0x08) >> 3); delayMicroseconds(1); digitalWrite(ENABLE_PIN, HIGH); delayMicroseconds(1); digitalWrite(ENABLE_PIN, LOW); delayMicroseconds(30); } void LCD_Init(void) { delayMiliseconds(50); digitalWrite(RS_PIN, LOW); // RS = 0 digitalWrite(ENABLE_PIN, LOW); // EN = 0 // Initialize LCD in 4-bit mode LCD_Command(0x02); // Function set: Initialize LCD_Command(0x28); // Function set: 4-bit mode LCD_Command(0x01); // 2-line display, 5x8 dots LCD_Command(0x0c); // Display ON, Cursor OFF, Blink OFF LCD_Command(0x06); // Entry mode: Increment cursor delayMiliseconds(2); LCD_Command(0x80); /* Cursor 1st row 0th position */ } void LCD_String(char *str) { while (*str) { LCD_Data(*str++); } } void LCD_Clear() { LCD_Command(0x01); /*clear display screen*/ delayMiliseconds(3); }