#include <xc.h>
// __CONFIG (0x3F39); //调试用
//常数定义
#define COM 0
#define DAT 1
#define HZ 16 //16X16,全角字符
#define SZ 8 //8X16,半角字符
//HGD12864F-1的命令定义
#define RESET 0b11100010 //复位指令
#define DISP_ON 0b10101111 //显示开
#define DISP_NOR 0b10100110 //正常显示,+1为反相
#define DISP_ALL 0b10100100 //显示所有的点,+1为显示
#define LINE0 0b01000000 //行0,加上0-63,共64行,由此可实现?动
#define PAGE0 0b10110000 //页0,加上0-7,共7页
#define COLHI 0b00010000 //列的高4位
#define COLLO 0b00000000 //列的低4位,共有16列
#define ADC 0b10100000 //横向方向,+1为向右
#define COM_DIR 0b11000000 //纵向方向,+8为方向向?
//引脚定义
#define A0 RC0
#define CS RC1
#define SCK RC2
#define SDO RC3
void WRITE_ONE(char,char);
void DISP_ONE(char,char,const char *,char);
void CSH(void);
void DELAY(unsigned int);
//分别定义汉字“单”、“片”、“机”、“福”的16×16点阵字模信息
const char DAN[32]={
0x00,0x00,0xF8,0x28,0x29,0x2E,0x2A,0xF8,0x28,0x2C,0x2B,0x2A,0xF8,0x00,0x00,0x00,
0x08,0x08,0x0B,0x09,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x09,0x0B,0x08,0x08,0x00
};
const char PIAN[32]={
0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x18,0x10,0x00,
0x80,0x40,0x30,0x0F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x00,0x00,0x00,0x00,
};
const char JI[32]={
0x08,0x08,0xC8,0xFF,0x48,0x88,0x08,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,
0x04,0x03,0x00,0xFF,0x00,0x41,0x30,0x0C,0x03,0x00,0x00,0x00,0x3F,0x40,0x78,0x00,
};
const char FU[32]={
0x08,0x08,0x89,0xCE,0x28,0x18,0x02,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x02,0x00,
0x02,0x01,0x00,0xFF,0x01,0x02,0xFF,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0xFF,0x00,
};
//半角字符,下标0-9分别为0-9的16×8点阵字模信息
const char AA[10][16]={
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00}
};
main(void)
{ char i;
CSH();
DELAY(10);
DISP_ONE(2,0,DAN,HZ); //在行0列2的位置显示“单”
DISP_ONE(3,1,PIAN,HZ); //在行1列3的位置显示“片”
DISP_ONE(4,2,JI,HZ); //在行2列4的位置显示“机”
DISP_ONE(7,3,FU,HZ); //在行3列7的位置显示“福”
i=0;
for (;;i++)
{ if (i>=10)
i=0;
DISP_ONE(6,2,AA[i],SZ); //在行2列6的位置显示半角数字0~9
DELAY(200);
}
}
//在指定的行Y,列X显示1个16×16汉字或16×8字符,数据存放在一维数组A[]中
//当HZ_SZ=16时显示汉字,HZ_SZ=8时显示半角字符数字
//X=0~15,程序将其转换为实际的列0~112。Y=0~3
void DISP_ONE(char X,char Y,const char * A,char HZ_SZ)
{ char i,j,a,b;
b=X<<4; //乘以16,将X=0~15转换为实际的列0~112
a=b>>4;
a=COLHI+a; //得到列的高4位命令字
b=b & 0x0F;
b=COLLO+b; //得到列的低4位命令字
WRITE_ONE(a,COM); //写列高4位位置命令
WRITE_ONE(b,COM); //写列低4位位置命令
Y=PAGE0+Y*2; //将=0~3转换为0~7
WRITE_ONE(Y,COM); //写页(行)位置命令
j=0;
for (i=0;i<HZ_SZ;i++) //全角汉字HZ_SZ=16,半角字符HZ_SZ=8
WRITE_ONE(A[j++],DAT); //输出1列8个点的数据,显示
WRITE_ONE(Y+1,COM); //换下行
WRITE_ONE(a,COM); //写列高4位命令
WRITE_ONE(b,COM); //写列低4位命令
for (i=0;i<HZ_SZ;i++)
WRITE_ONE(A[j++],DAT); //输出1列8个点的数据,显示
}
//写一字节命令或数据A,A0=AA,即AA=COM(0)时为命令,AA=DAT(1)时为数据
void WRITE_ONE(char A,char AA)
{ char i;
CS=0;NOP(); //片选为低电平,选中
SDO=0;NOP(); //数据线为低电平
A0=AA; //根据AA确定A0的电平,AA=COM(0)为命令,AA=DAT(1)为数据(显示)
for (i=0;i<8;i++)
{ SCK=0; //时钟为低电平
if ((A & 0x80)==0x80)
SDO=1; //A的最高位为1,输出1
else
SDO=0; //A的最高位为0,输出0
A=A<<1; //A左移1位
SCK=1; //时钟上升沿,数据有效
}
SDO=0;NOP();
A0=0;NOP();
SCK=0;
CS=1;
DELAY(2);
}
void CSH(void)
{ PORTC=0;
DELAY(50);
TRISC=0;
TRISD=0; //此句在串行接口中无用!
WRITE_ONE(RESET,COM); //复位
WRITE_ONE(DISP_ON,COM); //显示开
WRITE_ONE(ADC+1,COM); //+1为自动向右
WRITE_ONE(DISP_ALL,COM);
WRITE_ONE(DISP_NOR,COM); //正常显示
WRITE_ONE(COM_DIR,COM);
}
//======延时(n)ms
void DELAY(unsigned int n)
{
unsigned int j;
char k;
for (j=0;j<n;j++)
for (k=246;k>0;k--) NOP();
}
这个程序有什么问题吗
最新发布