⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c8051f020.c

📁 这是单片机c8051f020的液晶显示程序调试已通过
💻 C
字号:
//2007年3月21日
//前四行按要求显示了,后面的还有问题!
//3月22日修改调试通过数组写错了!

#include <C8051F020.h>
#include <intrins.h>


#define BAUDRATE 4800                                //波特率bps
#define CLKOUT 22118400                              //外部晶振,修改也要修改OSCXCN
#define SMODVAL 0                                    //SMOD的值,修改请也修改PCONVAL
#define PCONVAL 0x00                                 //PCON的值,=0x00时SMOD0=0; =0x80时SMOD0=1
#define TXVAL (256-CLKOUT*(SMODVAL+1)/BAUDRATE/384)  //定时器初值
#define MAX_LEN 86

#define width      20     //显示区宽度
#define addr_w     0x0000   //文本显示区首地址
#define addr_t     0x01e0   //图形显示区首地址
#define data_ora   P2       //MCU P2<------> LCM
#define uchar      unsigned char
#define uint       unsigned int

sbit wr =P3^0;  //Data Write into T6963C,L有效
sbit rd =P3^1;  //Data Read from T6963C,L有效
sbit ce =P3^2;  //使能信号,L有效
sbit cd =P3^3;  //当wr=L,cd=H:写命令,cd=L:写数据;当rd=L,cd=H:读状态,cd=L:读数据
sbit rst=P3^4;  //Lcm reset,低有效

sbit bf0 =P2^0;
sbit bf1 =P2^1;
sbit bf3 =P2^3;

void SYSCLK_Init(void);
void PORT_Init(void);
void wr_comm (uchar comm);	
void wr_data (uchar dat);
void chk_busy (uchar autowr);
void Delay(uint x);
void wr_od (uchar dat,uchar comm);
void wr_td (uchar datl,uchar dath,uchar comm);
void wr_xd (uint dat,uchar comm);
void wr_auto (uchar dat);
void init_lcd (void);
void clrram (void);
void disp_dat (uchar *dat);
void UART0_Init(void);                       //串口UART0初始化
void Display1(void);

bit  readFlag = 0;                           //读标志
uchar readCounts = 0;                        //已经读取的字符个数,与MAX_LEN比较
uchar idata trdata[MAX_LEN];                 //要接收/发送的字符串
uchar code num[]={0x20,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x30,0x41,0x42,0x58,0x59,0x5a,0x2b,0x2d,0x2e,0x61,0x62,0x78,0x79,0x7a};  //“ 、数字1~0、A、B、X、Y、Z、+、-、.、a、b、x、y、z”
uchar code LCDtab[]={0x00,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
0x10,0x21,0x22,0x38,0x39,0x3a,0x0b,0x0d,0x0e,0x41,0x42,0x58,0x59,0x5a};
uchar Display[MAX_LEN];


/*---------------延时子程序----------------*/
void Delay(uint x) 
{ 
  uint j; 
  uchar i; 
  for(j=0;j<x;j++) 
  { 
    for(i=0;i<120;i++); 
  } 
}
/*------------写命令或数据到LCD--------------*/
void wr_od (uchar dat,uchar comm)       //写一个数据和一个命令
{
  wr_data(dat);
  wr_comm(comm);
}
void wr_td (uchar datl,uchar dath,uchar comm)  //写两个数据和一个命令
{
  wr_data(datl);
  wr_data(dath);
  wr_comm(comm);
}
void wr_xd (uint dat,uchar comm)       //写一个16进制数据和一个命令
{
  uchar datl,dath;
  datl=dat;
  dath=dat>>8;
  wr_data(datl);
  wr_data(dath);
  wr_comm(comm);
}
void wr_auto (uchar dat)               //自动写数据
{
  chk_busy (1);
  cd=0;
  rd=1;
  data_ora=dat;
  wr=0;
  Delay(10);
  wr=1;
}

void wr_comm (uchar comm)       //写命令
{
  chk_busy (0);
  cd=1;
  rd=1;
  data_ora=comm;
  wr=0;
  Delay(10);
  wr=1;
}
void wr_data (uchar dat)       //写数据
{
  chk_busy (0);
  cd=0;
  rd=1;
  data_ora=dat;
  wr=0;
  Delay(10);
  wr=1;
}
void chk_busy (uchar autowr)    //测状态
{
  data_ora=0xff;
  cd=1;
  wr=1;
  rd=0;
  if(autowr)
    {while(bf3==0);}
  else
    {while((bf0==0)||(bf1==0));}
  rd=1;
}
/*------------------初始化-----------------*/
void init_lcd (void)
{
  rst=0;
  ;
  rst=1;
  ce=0;
  wr=1;
  rd=1;
  wr_xd(addr_w,0x40);                   //文本显示区首地址
  wr_xd(addr_t,0x42);                   //图形显示区首地址
  wr_td(width,0x00,0x41);               //文本显示区宽度
  wr_td(width,0x00,0x43);               //图形显示区宽度
  wr_comm(0x81);                        //逻辑"异或"
  wr_td(0x02,0x00,0x22);                //CGRAM偏置地址设置
  wr_comm(0x9c);                        //启用文本显示,启用图形显示
}
/*--------------清RAM------------------*/
void clrram (void)
{
  uchar i,j;
  wr_xd(addr_w,0x24);
  wr_comm(0xb0);                      //自动写开始
  for(j=0;j<144;j++)
  {
    for(i=0;i<width;i++)
      wr_auto(0x00);
  }
  wr_comm(0xb2);                     //自动写结束
}

/*--------------显示字符------------------*/
void disp_dat (uchar *dat)
{
  uchar i;
  for(i=0;i<MAX_LEN;i++)
  {
     if(dat[i]==0x38)
	 {
	    wr_xd(0x0007,0x24);   //第一行
	 }
	 else if(dat[i]==0x39)
	 {
	    wr_xd(0x001b,0x24);   //2
	 }
	 else if(dat[i]==0x3a)
	 {
	    wr_xd(0x002f,0x24);    //3
	 }
	 else if(dat[i]==0x21)
	 {
	    wr_xd(0x0043,0x24);    //4
	 }
	 else if(dat[i]==0x22)
	 {
	    wr_xd(0x0057,0x24);    //5
	 }
	 else if(dat[i]==0x58)
	 {
	    wr_xd(0x006b,0x24);    //6
		dat[i]=0x38;
	 }
	 else if(dat[i]==0x59)
	 {
	    wr_xd(0x007f,0x24);     //7
		dat[i]=0x39;
	 }
	 else if(dat[i]==0x5a)
	 {
	    wr_xd(0x0093,0x24);     //8
		dat[i]=0x3a;
	 }
	 else if(dat[i]==0x41)
	 {
	    wr_xd(0x00a7,0x24);     //9
		dat[i]=0x21;
	 }
	 else if(dat[i]==0x42)
	 {
	    wr_xd(0x00bb,0x24);      //10
		dat[i]=0x22;
	 }                                                                                                                                                   
	 wr_od (dat[i],0xC0);
	 Delay(500);
  }
}
/*------------------主程序--------------------*/
void main ()
{
   uchar rxch;
   uchar i;
   uchar j;
   WDTCN = 0xde;
    WDTCN = 0xad;                   //关闭看门狗

  PORT_Init();
  init_lcd ();
   SYSCLK_Init();
   UART0_Init();                             //串口初始化
   EA=1;
  
  clrram();
  Display1();
  
  while (1)
  {
	 if(RI0)
	 {
		 RI0=0;
		 rxch=SBUF0;
		 if(readCounts<MAX_LEN-1)
		 {
			 trdata[readCounts]=rxch;
			 readCounts++;
          }
		  else
		  {
		      trdata[readCounts]=rxch;
              readCounts=0;
			  readFlag=1;		  
		  }
      }
	  if(readFlag)
	  {
		 readFlag=0;
		 for(j=0;j<MAX_LEN;j++)
		 {   
			 for(i=0;i<=24;i++)
		     { 
		         if(num[i]==trdata[j])
		         {  
			         Display[j]=LCDtab[i];
					 SBUF0 = Display[j];                             //送入缓冲区
                     while(TI0 == 0);                        //等待发送完毕
                     TI0 = 0;                            //软件清零*/
			         break;
			      }
              }
          }
		  disp_dat(Display);
	   }
   }
}

//端口初始化
void PORT_Init(void)
{
   XBR0 = 0x04;                             //允许UART0,RX,TX连到2个端口引脚. XBR0=0000,0100
   XBR1 = 0x00;
   XBR2 = 0x40;                             //交叉开关使能
   P0MDOUT |= 0x03;                         //P0.0,P0.1为推挽方式输出,即TX0,RX0所在的端口 0000,0011
   P2MDOUT |= 0xFF ;                         
   P3MDOUT |=0x1F;      
}

//系统时钟初始化
#pragma OT(0,speed) 
void SYSCLK_Init(void)
{
   uchar i;
   OSCXCN = 0x67;                            //采用外部晶振22.1184MHz,不分频. 选型OSCXCN=0110,0111
   for(i=0;i<255;i++);                       //等待>1ms
   while(!(OSCXCN&0x80));                    //查询直到XTLVLD=1,晶振稳定
   OSCICN = 0x88;                            //切换到外部振荡器,允许时钟失效监测器. OSCICN=1000,1000
}

//串口初始化
void UART0_Init(void)
{
   SCON0 = 0x50;                            //UART0接收允许,选择串口方式1,波特率可变 SCON0=0101,0000
   ES0 = 1;                                 //UART0中断开启
   PCON |= PCONVAL;                         //PCON=0x00,SMOD = 0 ; PCON=0x80,SMOD=1
   CKCON |= 0x00;                               //定时器1使用系统时钟的12分频作为时基
   ET1=1;                                    //定时器1中断开启
   TCON=0x40;                                //TR1=1,定时器1允许
   TMOD = 0x20;                             //选择定时器1工作方式:方式2,自动重装载8位计数器/定时器
   TH1 = (int)TXVAL;                        //T1初值,根据波特率,时钟等计算. 0xF4, bps=4800bps
   TL1 = (int)TXVAL;
}

//
void Display1(void)
{
   wr_xd(0x0000,0x24);   //第一行首地址
   wr_od (0x34,0xC0);     //T
   Delay(500);
   wr_od (0x28,0xC0);    //H
   Delay(500);
   wr_od (0x25,0xC0);    //E
   Delay(500);
   wr_od (0x2f,0xC0);    //O
   Delay(500);
   wr_od (0x32,0xC0);    //R
   Delay(500);
   wr_od (0x39,0xC0);    //Y
   Delay(500);
   wr_od (0x1a,0xC0);    //:
   Delay(500);
   wr_od (0x38,0xC4);    //X
   Delay(500);
   wr_xd(0x0010,0x24);
   wr_od (0x4d,0xC0);    //m
   Delay(500);
   wr_od (0x4d,0xC4);    //m
   Delay(500);

   wr_xd(0x001b,0x24);   //第二行
   wr_od (0x39,0xC4);    //Y
   Delay(500);
   wr_xd(0x0024,0x24);
   wr_od (0x4d,0xC0);    //m
   Delay(500);
   wr_od (0x4d,0xC4);    //m
   Delay(500);

   wr_xd(0x002f,0x24);   //第三行
   wr_od (0x3a,0xC4);    //Z
   Delay(500);
   wr_xd(0x0038,0x24);
   wr_od (0x4d,0xC0);    //m
   Delay(500);
   wr_od (0x4d,0xC4);    //m
   Delay(500);

   wr_xd(0x0043,0x24);   //第四行
   wr_od (0x21,0xC4);    //A
   Delay(500);

   wr_xd(0x0057,0x24);   //第五行
   wr_od (0x22,0xC4);    //B
   Delay(500);

   wr_xd(0x0064,0x24);    //第6行首地址
   wr_od (0x21,0xC0);     //A
   Delay(500);
   wr_od (0x23,0xC0);    //C
   Delay(500);
   wr_od (0x34,0xC0);    //T
   Delay(500);
   wr_od (0x35,0xC0);    //U
   Delay(500);
   wr_od (0x21,0xC0);    //A
   Delay(500);
   wr_od (0x2c,0xC0);    //L
   Delay(500);
   wr_od (0x1a,0xC0);    //:
   Delay(500);
   wr_od (0x38,0xC4);    //X
   Delay(500);
   wr_xd(0x0074,0x24);
   wr_od (0x4d,0xC0);    //m
   Delay(500);
   wr_od (0x4d,0xC4);    //m
   Delay(500);

   wr_xd(0x007f,0x24);   //第七行
   wr_od (0x39,0xC4);    //Y
   Delay(500);
   wr_xd(0x0088,0x24);
   wr_od (0x4d,0xC0);    //m
   Delay(500);
   wr_od (0x4d,0xC4);    //m
   Delay(500);

   wr_xd(0x0093,0x24);   //第8行
   wr_od (0x3a,0xC4);    //Z
   Delay(500);
   wr_xd(0x009c,0x24);
   wr_od (0x4d,0xC0);    //m
   Delay(500);
   wr_od (0x4d,0xC4);    //m
   Delay(500);

   wr_xd(0x00a7,0x24);   //第9行
   wr_od (0x21,0xC4);    //A
   Delay(500);

   wr_xd(0x00bb,0x24);   //第10行
   wr_od (0x22,0xC4);    //B
   Delay(500);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -