原创 CVAVR编译器内部LCD函数

2009-2-17 17:31 5131 10 10 分类: 通信

使用内部code vision AVR自带函数,程序精简。


/*****************************************************
Chip type           : ATmega48V
Clock frequency     : 4.000000 MHz
Memory model        : Small
External RAM size   : 0
Data Stack size     : 128
*****************************************************/


#include <mega48.h>
#include <delay.h>
#asm
   .equ __lcd_port=0x0B ;PORTD
#endasm
#include <lcd.h>
#define uchar unsigned char
uchar disp[]="      ";//6个空格
uchar *ss="MA";


void c_ascii(uchar canshu)
 {
  
   disp[0]=canshu/100+0x30;
   disp[1]=(canshu%100)/10+0x30;
   disp[2]=canshu%10+0x30;
   disp[3]=0x20;
 }
void main(void)
{
  uchar j,k;
  uchar *i=disp;
  #pragma optsize-
  CLKPR="0x80";
  CLKPR="0x00";
  #ifdef _OPTIMIZE_SIZE_
  #pragma optsize+
  #endif
  j="235";
  c_ascii(j);
  lcd_init(16);    // initialize the LCD for 2 lines & 16 columns
  lcd_clear();     // clere the LCD
  lcd_putsf("he is old_a.c"); // display the message
  lcd_gotoxy(0,1);    // go on the second LCD line
  while(*i!=0x20) //*i!=0x20
   lcd_putchar(*i++);
  lcd_puts(ss);


   
}


 


使用外部驱动:


include <mega48.h>
#include <delay.h>


#define  uchar unsigned char    
#define  uint  unsigned int
#define  SCAN_CYCLE 100


#define LCM_Data  PORTD
#define Busy      0x80
#define LCM_RS PORTC.1
#define LCM_RW PORTC.2
#define LCM_E PORTC.3


void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,uchar BuysC);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);
void port_init(void);
void nop(int num);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
void LCMInit(void);


unsigned char uctech[] = {">>fujianfu<<"};
unsigned char net[] = {">liao-shao-hua<"};



void main(void)
{


 #pragma optsize-
 CLKPR=0x80;
 CLKPR=0x00;                //系统时钟无分频
 #ifdef _OPTIMIZE_SIZE_
 #pragma optsize+
 #endif
 port_init(); 
 delay_ms(400); //启动等待,等LCM讲入工作状态
 LCMInit(); //LCM初始化
 delay_ms(5); //延时片刻(可不要)
 DisplayListChar(0, 0, uctech);
 DisplayListChar(0, 1, net);
 ReadDataLCM();//测试用句无意义
 while(1);
}


void LCMInit(void) //LCM初始化
{
 LCM_Data = 0;
 WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
 delay_ms(5);
 WriteCommandLCM(0x38,0);
 delay_ms(5);
 WriteCommandLCM(0x38,0);
 delay_ms(5);


 WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
 WriteCommandLCM(0x08,1); //关闭显示
 WriteCommandLCM(0x01,1); //显示清屏
 WriteCommandLCM(0x06,1); // 显示光标移动设置
 WriteCommandLCM(0x0C,1); // 显示开及光标设置
}


void nop(int num)
{
  int i;
  for(i=0;i<num*8;i++){
    #asm("nop");
  }
}


void port_init(void)
{
 PORTB = 0x00;
 DDRB  = 0xFF;
 PORTC = 0x00;
 DDRC  = 0xFF;
 PORTD = 0x00;
 DDRD  = 0xFF;
}


//写数据
void WriteDataLCM(unsigned char WDLCM)
{
 ReadStatusLCM(); //检测忙
 nop(1);
 LCM_Data = WDLCM;
 nop(1);
 LCM_RS=1;
 nop(1);
 LCM_RW=0;
 nop(1);
 LCM_E=0; //若晶振速度太高可以在这后加小的延时
 LCM_E=0; //延时
 nop(1);
 nop(1);
 nop(1);
 LCM_E=1;
 nop(1);
}


//写指令
void WriteCommandLCM(unsigned char WCLCM,uchar BuysC) //BuysC为0时忽略忙检测
{
 if (BuysC) ReadStatusLCM(); //根据需要检测忙
 nop(1);
 LCM_Data = WCLCM;
 nop(1);
 LCM_RS=0;
 nop(1);
 LCM_RW=0;
 nop(1);
 LCM_E=0;
 LCM_E=0;
 nop(1);
 nop(1);
 nop(1);
 LCM_E=1;
 nop(1);
}


//读数据
unsigned char ReadDataLCM(void)
{
 uchar temp;
 LCM_RS=1;
 nop(1);
 LCM_RW=1;
 nop(1);
 LCM_E=0;
 LCM_E=0;
 nop(1);
 nop(1);
 LCM_E=1;
 nop(1);
 DDRD = 0x00;
 temp = PIND;
 DDRD = 0xff;
 nop(1);
 return(temp);
}


//读状态
unsigned char ReadStatusLCM(void)
{
 uchar temp;
 LCM_Data = 0xFF;
 nop(1);
 LCM_RS=0;
 nop(1);
 LCM_RW=1;
 nop(1);
 LCM_E=0;
 LCM_E=0;
 nop(1);
 nop(1);
 nop(1);
 LCM_E=1;
 nop(1);
 DDRD = 0x00;
 nop(1);
 while (PIND & Busy); //检测忙信号
 temp=LCM_Data;
 nop(1);
 DDRD = 0xff;
 return(temp);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
 Y &= 0x1;
 X &= 0xF; //限制X不能大于15,Y不能大于1
 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
 X |= 0x80; // 算出指令码
 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
 WriteDataLCM(DData);
}


//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
 unsigned char ListLength;


  ListLength = 0;
 Y &= 0x1;
 X &= 0xF; //限制X不能大于15,Y不能大于1
 while (DData[ListLength]!=0) //若到达字串尾则退出
  {
   if (X <= 0xF) //X坐标应小于0xF
    {
     DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
     ListLength++;
     X++;
    }
  }
}


结论:用AVR单片机,使用CV AVR编译器,驱动LCD非常便利,而且可以把英文字符LCD1602生成中文字提示。要知道中文LCD12232价格比1602贵很多。再说了CV AVR还有底层驱动接口。应用灵活。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
10
关闭 站长推荐上一条 /3 下一条