各位朋友,请问msp430f149可以直接驱动LCD1602A吗?为啥我的程序驱动不了lcd1602啊?把程序烧进去后,LCD1602有时可以显示鬼影,但只能显示右半部分,左半部分显示不出来,好奇怪啊。调节对比度要显示的字符还是显示不出来啊。。。
- #include<msp430x14x.h> //包含单片机寄存器的头文件
- #define CPU_F ((double)8000000)
- #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
- #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
- #define DataDir P3DIR
- #define DataPort P3OUT
- #define DataIn P3IN
- #define Busy 0x80
- #define CtrlDir P2DIR
- #define RS_L P2OUT&=(~BIT7)
- #define RS_H P2OUT|=BIT7
- #define RW_L P2OUT&=(~BIT6)
- #define RW_H P2OUT|=BIT6
- #define EN_L P2OUT&=(~BIT5)
- #define EN_H P2OUT|=BIT5
- #define BG_H P5OUT|=BIT2
- unsigned char *s="0123456789";
- /*****************************************************
- 函数功能:判断液晶模块的忙碌状态
- 返回值:result。result=1,忙碌;result=0,不忙
- ***************************************************/
- unsigned char BusyTest(void)
- {
- unsigned char result;
- DataDir&=0x00;
- RS_L; //根据规定,RS为低电平,RW为高电平时,可以读状态
- RW_H;
- EN_H; //E=1,才允许读写
- delay_us(2);
- if((DataIn & Busy)!=0)
- {
- result=1;
- }
- EN_L;
- DataDir|=0xff;
- return result;
- }
- /*****************************************************
- 函数功能:将模式设置指令或显示地址写入液晶模块
- 入口参数:dictate
- ***************************************************/
- void WriteInstruction (unsigned char dictate)
- {
- //while(BusyTest()==1); //如果忙就等待
- RS_L; //根据规定,RS和R/W同时为低电平时,可以写入指令
- delay_us(50);
- RW_L;
- delay_us(50);
- EN_L; //E置低电平(根据表8-6,写指令时,E为高脉冲,
- // 就是让E从0到1发生正跳变,所以应先置"0"
- delay_us(50); //空操作两个机器周期,给硬件反应时间
- DataPort=dictate; //将数据送入P0口,即写入指令或地址
- delay_us(50); //空操作四个机器周期,给硬件反应时间
- EN_H; //E置高电平
- delay_us(50); //空操作四个机器周期,给硬件反应时间
- EN_L; //当E由高电平跳变成低电平时,液晶模块开始执行命令
- }
- /*****************************************************
- 函数功能:将数据(字符的标准ASCII码)写入液晶模块
- 入口参数:y(为字符常量)
- ***************************************************/
- void WriteData(unsigned char y)
- {
- // while(BusyTest()==1); //如果忙就等待
- RS_H; //RS为高电平,RW为低电平时,可以写入数据
- delay_us(50);
- RW_L;
- delay_us(50);
- EN_L; //E置低电平(根据表8-6,写指令时,E为高脉冲,
- // 就是让E从0到1发生正跳变,所以应先置"0"
- delay_us(50);
- DataPort=y; //将数据送入P0口,即将数据写入液晶模块
- delay_us(50); //空操作四个机器周期,给硬件反应时间
- EN_H; //E置高电平
- delay_us(50); //空操作四个机器周期,给硬件反应时间
- EN_L; //当E由高电平跳变成低电平时,液晶模块开始执行命令
- }
- /*****************************************************
- 函数功能:对LCD的显示模式进行初始化设置
- ***************************************************/
- void LcdInitiate(void)
- {
- P5DIR=0xff;
- CtrlDir|=0xe0;
- DataDir=0xff;
- BG_H;
- delay_ms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
- WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
- delay_ms(5); //延时5ms
- WriteInstruction(0x38);
- delay_ms(5);
- WriteInstruction(0x38);
- delay_ms(5);
- WriteInstruction(0x38);
- delay_ms(5);
- WriteInstruction(0x0f); //显示模式设置:显示开,有光标,光标闪烁
- delay_ms(5);
- WriteInstruction(0x06); //显示模式设置:光标右移,字符不移
- delay_ms(5);
- WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除
- delay_ms(80);
- }
- /*******************************************
- 函数名称:LocateXY
- 功 能:向液晶输入显示字符位置的坐标信息
- 参 数:x--位置的列坐标
- y--位置的行坐标
- 返回值 :无
- ********************************************/
- void LocateXY(unsigned char x,unsigned char y)
- {
- unsigned char temp;
- temp = x&0x0f;
- y &= 0x01;
- if(y) temp |= 0x40; //如果在第2行
- temp |= 0x80;
- WriteInstruction(temp);
- }
- /*******************************************
- 函数名称:Disp1Char
- 功 能:在某个位置显示一个字符
- 参 数:x--位置的列坐标
- y--位置的行坐标
- data--显示的字符数据
- 返回值 :无
- ********************************************/
- void Disp1Char(unsigned char x,unsigned char y,unsigned char data)
- {
- LocateXY( x, y );
- WriteData( data );
- }
- /*******************************************
- 函数名称:DispNchar
- 功 能:让液晶从某个位置起连续显示N个字符
- 参 数:x--位置的列坐标
- y--位置的行坐标
- n--字符个数
- ptr--指向字符存放位置的指针
- 返回值 :无
- ********************************************/
- void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr)
- {
- unsigned char i;
- for (i=0;i<n;i++)
- {
- Disp1Char(x++,y,ptr[i]);
- if (x == 0x0f)
- {
- x = 0;
- y ^= 1;
- }
- }
- }
- /***********************************************
- 函数名称:DispStr
- 功 能:让液晶从某个位置起连续显示一个字符串
- 参 数:x--位置的列坐标
- y--位置的行坐标
- ptr--指向字符串存放位置的指针
- 返回值 :无
- ***********************************************/
- void DispStr(unsigned char x,unsigned char y,unsigned char *ptr)
- {
- unsigned char *temp;
- unsigned char i,n = 0;
- temp = ptr;
- while(*ptr++ != ' ') n++; //计算字符串有效字符的个数
- for (i=0;i<n;i++)
- {
- Disp1Char(x++,y,temp[i]);
- if (x == 0x0f)
- {
- x = 0;
- y ^= 1;
- }
- }
- }
- /********************************************************************
- * 名称 : L1602_char(uchar hang,uchar lie,char sign)
- * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
- L1602_char(1,5,'b')
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无
- ***********************************************************************
- void L1602_char(unsigned char hang,unsigned char lie,char sign)
- {
- unsigned char a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- WriteInstruction(a);
- WriteData(sign);
- }
- ********************************************************************
- * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
- * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
- L1602_string(1,5,"ab cd ef;")
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无
- ***********************************************************************
- void L1602_string(unsigned char hang,unsigned char lie,unsigned char *p)
- {
- unsigned char a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0xc0;
- a = a + lie - 1;
- WriteInstruction(a);
- while(1)
- {
- if(*p == ' ') break;
- WriteData(*p);
- p++;
- }
- }*/
- void clock_set()
- {
- unsigned int i;
- BCSCTL1 &=~XT2OFF;
- do
- {
- IFG1 &= ~OFIFG; //clear invalidation flag
- for (i=0xff;i>0;i--);
- }
- while ((IFG1 & OFIFG));//FLAG is exist
- BCSCTL2 |=SELM_2+SELS; //MCLK=LFXT2
- }
- void main(void) //主函数
- {
- P4DIR=P4DIR | BIT0;
- WDTCTL=WDTPW + WDTHOLD; // STOP WATCHDOG
- clock_set();
- LcdInitiate(); //调用LCD初始化函数
- DispStr(5,0,s);
- //Disp1Char(5,1,'A');
- while(1)
- {
- //Disp1Char(5,1,'A');
- P4OUT^=0x01;
- delay_ms(500);
- //L1602_string(1,1,"0123456789");
- }
- }
复制代码
一周热门 更多>