📄 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 + -