兄弟们帮我看看PIC16F877四线驱动LCD1602问题

2020-02-10 08:42发布

兄弟们,我的控制线用RB0—RB2驱动正常,为什么换成RE0—RE2就不正常了?四线驱动的下面有程序
#include <pic.h>
//#include <pic1687x.h>
//#define _16F877
__CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS & DEBUGEN);
/******************************************************************************/
#define uint8                   unsigned char
#define int8                    char
#define uint16                  unsigned int
#define int16                   int
#define uint32                  unsigned long
#define int32                   long
/******************************************************************************/
#define LCD_CMD_WR                                                   (1 << 0)
#define LCD_DATA_WR                                                   (1 << 0)
#define LCD_BUSY_RD                                                   (1 << 1)//0x02
#define LCD_DATA_RD                                                   0x03
                     
//LCD Commands        
#define LCD_CLS                                                                   0x01
#define LCD_HOME                                                           0x02
#define LCD_SETMODE                                                   0x04
#define LCD_SETVISIBLE                                   0x08
#define LCD_SHIFT                                                           0x10
#define LCD_SETFUNCTION                                   0x20
#define LCD_SETCGADDR                                           0x40
#define LCD_SETDDADDR                                           0x80
                                          
#define E_PIN_MASK                                 (1 << 2)
/******************************************************************************/
#define DATA_DDR_ON                                                   DATA_DDR&=0x0F// = 0x00
#define DATA_DDR_OFF                                           DATA_DDR|=0xF0// = 0xFF
                                           
#define DATA_PORT_ON                                           DATA_PORT|=0xF0// = 0xFF
#define DATA_PORT_OFF                                           DATA_PORT&=0x0F// = 0x00     
                                           
#define DATA_DDR                                        TRISD     
#define DATA_PORT                                        PORTD
                                              
#define CORTROL_DDR                                        TRISE
#define CORTROL_PORT                                        PORTE
/******************************************************************************/
uint8 flag;
/******************************************************************************/
uint8 pacmanopen[] = {0x0E,0x07,0x03,0x01,0x03,0x07,0x0E,0x00,' '};
uint8 pacmanshut[] = {0x00,0x0F,0x1F,0x01,0x1F,0x0F,0x00,0x00,' '};
uint8 text[] = {'4','-','B','i','t',' ','L','C','D',' ','M','o','d','e', ' ',' '};
/*************************************************************/
void delay_us (uint16 disp_time) //
{
        do
        {
                   disp_time--;
           }
        while(disp_time>0);
}
/*************************************************************/
void delay_ms (uint16 disp_time)
{
        while(disp_time>0)
        {
                delay_us(1000);
                disp_time--;
          }
}
/*************************************************************/
void wrcmd (uint8 cmdcode)
{
                //lcd_wait();
        DATA_DDR&=0x0F;
        DATA_PORT&=0x0F;
           DATA_PORT |= (cmdcode & 0xF0);                          // Get the most significant nibble first.
    //CORTROL_PORT = CORTROL_DDR = 0;
           CORTROL_DDR &= ~(1 << 0);
           CORTROL_DDR &= ~(1 << 1);
           CORTROL_DDR &= ~(1 << 2);
          
           CORTROL_PORT &= ~(1 << 0);
           CORTROL_PORT &= ~(1 << 1);
           CORTROL_PORT &= ~(1 << 2);          
          
          
           CORTROL_PORT &= ~LCD_CMD_WR;                               // Specify a command write operation.
           CORTROL_PORT |= E_PIN_MASK;                               // Toggle the 'E' pin to send the command.
           asm("NOP");asm("NOP");asm("NOP");
           CORTROL_PORT &= ~E_PIN_MASK;
          
           DATA_DDR&=0x0F;
           DATA_PORT&=0x0F;
           DATA_PORT |= ((cmdcode << 4)&0xF0);                     // Repeat for least significant nibble.
           CORTROL_PORT &= ~LCD_CMD_WR;
           CORTROL_PORT |= E_PIN_MASK;
           asm("NOP");asm("NOP");asm("NOP");
           CORTROL_PORT &= ~E_PIN_MASK;         
                                            // Call the wait routine.
}
/*************************************************************/     
void wrdata (uint8 data)
{
                //lcd_wait();
        DATA_DDR&=0x0F;
        DATA_PORT&=0x0F;
           DATA_PORT |= (data & 0xF0);                         // Get the most significant nibble first.
           //CORTROL_PORT = LCD_DATA_WR;                         // Specify a data write operation.
           CORTROL_PORT |= (1 << 0);
           CORTROL_PORT &= ~(1 << 1);
           CORTROL_PORT &= ~(1 << 2);
           CORTROL_PORT |= E_PIN_MASK;                         // Toggle the 'E' pin to send the command.
           asm("NOP");asm("NOP");asm("NOP");
           CORTROL_PORT &= ~E_PIN_MASK;
          
           DATA_DDR&=0x0F;
           DATA_PORT&=0x0F;
           DATA_PORT |= ((data << 4)&0xF0);                         // Repeat for least significant nibble.
           //CORTROL_PORT = LCD_DATA_WR;
           CORTROL_PORT |= (1 << 0);
           CORTROL_PORT &= ~(1 << 1);
           CORTROL_PORT &= ~(1 << 2);
           CORTROL_PORT |= E_PIN_MASK;
           asm("NOP");asm("NOP");asm("NOP");
           CORTROL_PORT &= ~E_PIN_MASK;                                          // Call the wait routine.
}
/******************************************************************************/
void lcd_set_xy( uint8 x, uint8 y )  //写地址函数
{
    uint8 address;
    if (y == 0)
    {
             address = 0x80 + x;
           }
    else if (y == 1)
    {
            address = 0xc0 + x;
    }
    else if (y == 2)
    {
            address = 0x94 + x;
    }
    else
    {
            address = 0xD4 + x;
    }
    wrcmd( address);
}
/******************************************************************************/
void lcd_write_onechar(uint8 X1,uint8 Y1,uint8 data) //列x=0~15,行y=0,1
{
          lcd_set_xy( X1, Y1 ); //写地址
          wrdata(data);
}
/*************************************************************/
void lcd_init ()
{
                 DATA_DDR_ON;
                 DATA_PORT_ON;
                  
          //wrcmd(0x28);   
           wrcmd(0x28);
           wrcmd(0x28);
          wrcmd(0x0c);
          wrcmd(0x01);
}
/*************************************************************/  
void LCD_write_string(uint8 X,uint8 Y,uint8 *s) //列x=0~15,行y=0,1
{
    lcd_set_xy( X, Y ); //写地址   
    while (*s)  // 写显示字符
    {
      wrdata( *s );
      s ++;
    }
      
}
/******************************************************************************/
void main(void)  
{  
                ADCON1=0x87;       //转换结果右移,及ADRESH 寄存器的高6 位为"0"
   
           lcd_init();                             // Initialise the LCD Display
           lcd_write_onechar(0,1,0x38);
          for (;;)                                // Loop Forever.
          {       
                   lcd_write_onechar(0,1,0x38);
                   LCD_write_string(0,0,text);
   }  
}
/******************************************************************************/
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
9条回答
nieccyyy
2020-02-11 11:38
#define DPORT          PORTB        // 定义数据端口为B端口
#define DTRIS          TRISB                // 定义数据端口的方向
#define CTRIS_E  TRISC0        // 定义端口的方向
#define CTRIS_RS TRISC1        // 定义端口的方向
#define RS    RC1       
#define E     RC0

void LCD_WriteComm(unsigned int TheComm){
// 定义向LCD写一个指令字的函数
        CTRIS_RS = 0;                // 定义端口为写状态
        CTRIS_E = 0;               
        DTRIS = 0x00;               
        DPORT = TheComm;        // 把数据输出到端口,实际上只是高4位
        RS    = 0;
        E     = 0;
        E     = 0;                        // 多了一个指令,是为了让信号电平有足够得时间稳定
        E     = 1;
        DPORT = TheComm<<4;        // 将数据的低4位移位到高4位,输出到端口
        RS    = 0;
        E     = 0;
        E     = 0;
        E     = 1;
}

void LCD_WriteDate(unsigned int Hang,unsigned int No,unsigned char TheDate){
// 定义向LCD的第Hang行的第No个位置,写字符TheDate
// Hang:0,1; No:0-15;
        unsigned char tmpi;
        tmpi = Hang*0x40+No+0x80;        // 计算地址指针
        LCD_NoBusy();
        CTRIS_RS = 0;               
        CTRIS_E = 0;               
        DTRIS = 0x00;               
        DPORT = tmpi;
        RS    = 0;
        E     = 0;
        E     = 0;
        E     = 1;
        DPORT = tmpi<<4;
        E     = 0;
        E     = 0;
        E     = 1;
       
        LCD_NoBusy();
        DTRIS = 0x00;                       
        DPORT = TheDate;
        RS    = 1;               
        E     = 0;
        E     = 0;
        E     = 1;
        DPORT = TheDate<<4;
        E     = 0;
        E     = 0;
        E     = 1;
}

void LCD_NoBusy(){
        delay(2);
}

void LCD_init()
// 初始化LCD显示屏
{
       
        delay(20);                        //1、延时大约20ms
        CTRIS_RS = 0;               
        CTRIS_E = 0;               
        DTRIS = 0x00;               
        DPORT = 0x30;
        RS    = 0;               
        E     = 0;
        E     = 0;
        E     = 1;
        delay(5);               
        DPORT = 0x30;
        RS    = 0;               
        E     = 0;
        E     = 0;
        E     = 1;
        delay(2);               
        DPORT = 0x30;
        RS    = 0;               
        E     = 0;
        E     = 0;
        E     = 1;
        delay(2);               
        DPORT = 0x20;
        RS    = 0;               
        E     = 0;
        E     = 0;
        E     = 1;
        delay(2);               

        LCD_WriteComm(0x28);       
        delay(4);
        LCD_WriteComm(0x08);        //4、写指令08H,关闭LCD       
        LCD_NoBusy();
        LCD_WriteComm(0x01);        //5、写指令01H,清屏LCD
        LCD_NoBusy();
        LCD_WriteComm(0x06);        //6、写指令06H
        LCD_NoBusy();
        LCD_WriteComm(0x0C);        //7、写指令0CH
};
这个是实测能用的。PIC16F877A,

一周热门 更多>