[求助] 关于PIC控制LCD 显示字符串问题

wsy412571405   2012-3-13 10:00 楼主
我以前用的51的一段显示字符串子函数:
  void print(uchar *str)
{
        while(*str!='\0')
        {
                LCD_Write(*str);    //写函数 写单个字符 好用。
                str++;
        }
}
但 搬到PIC 这怎么不好用呢    我PIC 用的是 PIC16F877
求高手帮忙 万分感激

回复评论 (11)

各位大侠 帮帮忙吧!

各位大侠 帮忙看看吧!
点赞  2012-3-13 10:24

。。。

怎么可以直接搬到PIC 上去呢!!pic 编程不一样的。。
点赞  2012-4-12 10:54

877A的LCD程序

#include <htc.h>
//#include <pic.h>
//#include <pic1687x.h>
//#include <pic16f91x.h>
#define uchar unsigned char
#define uint  unsigned int
#define TESTBIT(a,b) ((a)&(1<<(b)))

__CONFIG(WDTDIS & LVPDIS & HS & PWRTDIS & BORDIS);//设置877配置位
//__CONFIG(WDTDIS &  HS & PWRTDIS & BORDIS);//设置配置位


#define  LCD_RS  RA0
#define  LCD_RW  RA1
#define  LCD_EN      RA2
 
/************************定义显示字符*****************************************/

uchar tab[] = {" Welcome A Use  PIC Study Board "};

/************************声明函数*********************************************/
void DelayUS(uint);
void Delay_ms(uint delay);
uchar Chk_1602_busy(void);
void Write_1602_command(uchar gcmd,uchar gvalue);
void Write_1602_data(uchar gdata);
void INIT_1602(void);
void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata);
void Display_1602(uchar x,uchar y,uchar gdata);


/*******************************************************************************
* 函 数 名: DelayUS(uint8 delay)
* 函数功能: 微秒延时 
* 入口参数: delay
* 返    回: 无
*******************************************************************************/

void DelayUS(uint delay)   
{
   for(;delay;)
   {
      NOP();
      delay--;
   }
}

/*******************************************************************************
* 函 数 名: DelayMS(uint16 delay)
* 函数功能: 毫秒延时 
* 入口参数: delay
* 返    回: 无
*******************************************************************************/

void Delay_ms(uint delay) 
{
   uint i;

   for(i=0;i<delay;i++)
       DelayUS(1000);
}

/*******************************************************************************
* 函 数 名: Read_LCD_Busy(void)
* 函数功能: 读液晶忙通道数据
* 入口参数: 无
* 返    回: 无
*******************************************************************************/
uchar Chk_1602_busy(void)
{
   uint gR_data;
   uint gwait_time=0xff;   //设置忙超时数

   LCD_RS=0;         //表示状态
   LCD_RW=1;         //选择读
   LCD_EN=1;
   TRISC = 0xFF;   //接收口设为输入口
   DelayUS(30);
   gR_data=PORTC;

   while(TESTBIT(gR_data,7))  //表示busy
   {
      --gwait_time;
      if(!gwait_time)
      { LCD_EN=0;TRISC = 0x00; return 0; }
   }

    LCD_EN=0;
    TRISC = 0x0;   //恢复为输出口
    return 1;
}

/******************************************************************************
* 函 数 名: Write_LCD_Comd(uint8 commond)
* 函数功能: 写指令
* 入口参数: commond指令
* 返    回: 无
*******************************************************************************/

void Write_1602_command(uchar gcmd,uchar gvalue)
{
   if(gvalue)             //写命令时大部分情况下是在LCD空闲模式下写
   {
      if(Chk_1602_busy())
      {
         LCD_RS=0;         //选择指令
         LCD_RW=0;         //选择写
         PORTC=gcmd;       //赋指令
         LCD_EN=1;         //使能
         DelayUS(30);
         LCD_EN=0;
      }
   }

   else
   {
      LCD_RS=0;         //选择指令
      LCD_RW=0;         //选择写
      PORTC=gcmd;       //赋指令
      LCD_EN=1;         //使能
      DelayUS(30);
      LCD_EN=0;
   }
}

/******************************************************************************
* 函 数 名: Write_LCD_Data(uint8 Data)
* 函数功能: 写数据
* 入口参数: Data数据
* 返    回: 无
*******************************************************************************/

/*----------- 写数据 -------------*/
void Write_1602_data(uchar gdata)
{
   if(Chk_1602_busy())     //写数据必须是在LCD空闲模式下才能写
   {
      LCD_RS=1;             //选择数据
      LCD_RW=0;             //选择写
      PORTC=gdata;
      LCD_EN=1;             //使能
      DelayUS(30);
      LCD_EN=0;
      DelayUS(10);
   }
}

/******************************************************************************
* 函 数 名: LCD1602_Init(void)
* 函数功能: 初始化1602LCD
* 入口参数: 无
* 返    回: 无
*******************************************************************************/

/*-----------1602初始化函数-------------*/
void INIT_1602(void)
{
   Delay_ms(15);
   Write_1602_command(0x38,0);  //设置16X2显示,5X7点阵,8位数据传送,不检测忙信号
   Delay_ms(5);
   Write_1602_command(0x38,0);
   Delay_ms(5);
   Write_1602_command(0x38,0);  //设置16X2显示,5X7点阵,8位数据传送,不检测忙信号
   Write_1602_command(0x38,1);  //设置16X2显示,5X7点阵,8位数据传送,检测忙信号
   Write_1602_command(0x08,1);  //关闭显示、无光标、检测忙信号
   Write_1602_command(0x01,1);  //清屏、光标归位、AC=0、检测忙信号
   Write_1602_command(0x06,1);  //显示光标右移位置、检测忙信号
   Write_1602_command(0x0c,1);  //显示功能开、无光标

}

/******************************************************************************
* 函 数 名: Write_LCD_Mult_Byte(uint8 addr,uint8* pointer,uint8 index,uint8 num)
* 函数功能: 写多字节字符
* 入口参数: addr起始地址,pointer指针地址,index下标,num个数
* 返    回: 无
*******************************************************************************/

/*-----------显示字符串-------------*/
//                                开始地址  行号        数据长度      数组元素
void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata)
{
   uchar gaddress;
   uchar *pdat;
   uchar gcount=0;

   uchar glongth=glength-gadd_start;  //真正需要写的数据长度
   pdat=pdata+gadd_start;

   if(gline)                          //第0行
   { gaddress=0x80+gadd_start; }      //地址对应
   else
   { gaddress=0xc0+gadd_start; }      //第一行

   for(;gcount<glongth;gcount++)
   {
      Write_1602_command(gaddress,1);        //设定数据地址
      Write_1602_data(*pdat);  //取设定地址里的数据
      gaddress++;
      pdat++;
   }
}

/*-----------指定位置显示字符-------------*/
void Display_1602(uchar x,uchar y,uchar gdata)
{
   uchar gaddress;

   if(y)
   { gaddress=0x80+x; }

   else
   { gaddress=0xc0+x; }

   Write_1602_command(gaddress,1);   //设定数据地址
   Write_1602_data(gdata);
}


/******************************************************************************
* 函 数 名: main()
* 函数功能: LCD显示字符
* 入口参数: 无
* 返    回: 无
*******************************************************************************/

void main()

    //ANSEL = 0x00;
    ADCON1 = 0x87;   //设置PORTA为普通IO口
 TRISA0 = 0;
 TRISA1 = 0;
 TRISA2 = 0;

    TRISA3 = 0;

 TRISC = 0x00;   //设置PORTC为输出
 INIT_1602();
 while(1)
 {
   Display_1602(0,1,'2');
     
      RA3 = 1;Delay_ms(100);RA3 = 0;
     
      Display_1602_string(0,1,16,tab);
    
      RA3 = 0;Delay_ms(100);RA3 = 1;
 } 
}

[ 本帖最后由 544852010 于 2012-4-24 11:08 编辑 ]
点赞  2012-4-24 11:06
谢谢了!收藏了!
点赞  2012-4-27 13:30
void LCD_wrstr(const rom char *s)/*写入要显示的字符串*/
{
for(;*s!='\0';s++)LCD_wrchar(*s);
}
点赞  2016-9-15 18:19
你调试一下看看原因,可能是字符串结束符不一样吧
点赞  2016-9-15 20:04
问题解决了没有啊
MICROCHIP  IR STMAXIM代理 QQ:776514862
点赞  2016-11-11 14:56
遇到了同样的问题,字符串指针在PIC里传地址,会传ROM里的地址,仿真时看出
点赞  2018-8-9 13:39
请问是如何说不好用的?编译不通过,还是程序执行问题?
点赞  2018-8-9 15:38
请问是如何说不好用的?编译不通过,还是程序执行问题?浏览器问题,发两次同样内容了 本帖最后由 dingzy_2002 于 2018-8-9 15:39 编辑
点赞  2018-8-9 15:38
找到原因,6楼正解,函数默认调用ram区地址
点赞  2018-8-9 16:48
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复