❶ 关于单片机液晶屏LCD12864的程序
/*****************************************************************
*程序名称:带汉字库的12864液晶显示模块驱动
*程序功能:显示字符 、汉字和图片
*开发工具:Kile
* MCU型号:AT89S52-24PU
*时钟频率:11.0592MHZ
*程序作者:yuan
*版权说明:yuan
*****************************************************************/
#include<reg52.h>
#include "lcd.h"
#include "util.h"
sbit E=P1^5;//脉冲使能
sbit RW=P1^6;//读写选择
sbit RS=P1^7;//数据命令选择
sbit rst=P3^6;//12864复位
// 延时ms函数:
// 12864检查状态函数:
void Check12864State(void)
{
P0=0xff;
E=0;//读状态前三控制线的状态
RS=0;
RW=1;
E=1;//拉高,读状态
while((P0&0x80)==0x80);//等待空闲
E=0;//写命令后三控制线的状态
RS=1;
RW=0;
}
// 12864写命令函数:
void Write12864Command( unsigned char com)
{
Check12864State();//检查状态
P0=com;//赋值
E=0;//写命令前三控制线的状态
RS=0;
RW=0;
E=1;//拉高,写命令
E=0;//写命令后三控制线的状态
RS=1;
RW=1;
}
//12864写数据函数:
void Write12864Data( unsigned char dat)
{
Check12864State();//检查状态
P0=dat;//赋值
E=0;//写数据前三控制线的状态
RS=1;
RW=0;
E=1;//拉高,写数据
E=0;//写数据后三控制线的状态
RS=0;
RW=1;
}
//在指定的位置显示字符串(汉字和ASCII码字符)函数:
void LCD12864DisplayString( unsigned char y,unsigned char x, unsigned char *pstr)
//y-行数值0-3,x-列数值0-7,pstr-字符串指针
//12864可以显示32个汉字(四行每行8个),一个地址对应一个汉字
//可以显示64个ASCII码字符(四行每行16个),一个地址对应两个字符
//为了实现自动换行功能,这个函数比较繁琐
{
unsigned char row,n=0;
Write12864Command(0x30);//基本指令
Write12864Command(0x06);//地址计数器自动加以,光标右移
switch(y)//根据行号选择行地址
{
case 0:row=0x80;break;//第一行首地址
case 1:row=0x90;break;//第二行首地址
case 2:row=0x88;break;//第三行首地址
case 3:row=0x98;break;//第四行首地址
default:;
}
Write12864Command(row+x);//写地址
while(*pstr!='\0')
{
Write12864Data(*pstr);//写字符
pstr++;
n++;//计数
if((n+x*2)==16)//如果一行写完 ,继续写第二行
{
if(y==0) Write12864Command(0x90);//写下一行地址
else if(y==1) Write12864Command(0x88);//写下一行地址
else if(y==2) Write12864Command(0x98);//写下一行地址
else ;
}
else if((n+x*2)==32)//如果第二行写完 ,继续写第三行
{
if(y==0) Write12864Command(0x88);//写下一行地址
else if(y==1) Write12864Command(0x98);//写下一行地址
else ;
}
else if((n+x*2)==48)//如果第三行写完 ,继续写第四行
{
if(y==0) Write12864Command(0x98);//写下一行地址
else ;
}
else ;
}
}
//图片模式清屏函数:
void Clear12864Screen()
{
unsigned char i,j;
Write12864Command(0x34);//功能设定:8位控制方式,使用扩充指令
Write12864Command(0x36);//使用扩充指令,绘图显示控制
for(i=0;i<32;i++)
//ST7920可控制256*32点阵(32行256列),而12864液晶实际的行地址只有0-31行,
//12864液晶的32-63行的行是0-31行地址从第128列划分一半出来的,所以分为上下两半屏,
//也就是说第0行和第32行同属一行,行地址相同;第1行和第33行同属一行,以此类推
{
Write12864Command(0x80|i);//写行地址(垂直地址)
Write12864Command(0x80);//写列地址(水平地址)
for(j=0;j<32;j++)
Write12864Data(0x00);//清屏
}
}
//在任意位置显示任意大小的图片函数:
void LCD12864DisplayPictrue(unsigned char y,unsigned char x,
unsigned char px,unsigned char py, unsigned char *pp)
//y-起始行(数值0-63),x-起始列(16位宽,数值0-7),
//px-图片宽度,py-图片高度,pp-指针指向图片数组
//因为上下屏的地址不连续,要在任意位置显示完整的图像,处理起来比较繁琐
{
unsigned char i,j,k;
Clear12864Screen();//清屏
if(y<32)//如果起始行在上半屏
{
k=32-y;//算出上半屏的行数
for(i=0;i<k;i++,y++)//上半屏行数
{
Write12864Command(0x80|y);//写行地址(垂直地址)
Write12864Command(0x80|x);//写列地址(水平地址)
for(j=0;j<px/8;j++)
Write12864Data(pp[i*px/8+j]);//写图片数据
}
y=0;//下半屏起始行,接上半屏继续写数据
for(;i<py;i++,y++)//下半屏剩下的行数
{
Write12864Command(0x80|y);//写行地址(垂直地址)
Write12864Command(0x80|(8+x));//写列地址(水平地址)
for(j=0;j<px/8;j++)
Write12864Data(pp[i*px/8+j]);//写图片数据
}
}
else //如果起始行在下半屏
{
for(i=0;i<py;i++,y++)//行数
{
Write12864Command(0x80|(y-32));//写行地址(垂直地址)
Write12864Command(0x80|(8+x));//写列地址(水平地址)
for(j=0;j<px/8;j++)
Write12864Data(pp[i*px/8+j]);//写图片数据
}
}
}
void Clear12864Text()
{
Write12864Command(0x34);//清屏
DelayMs(5);
Write12864Command(0x30);//清屏
DelayMs(5);
Write12864Command(0x01);//清屏
DelayMs(5);
}
//12864初始化函数:
void Initialize12864()
{
rst=0;//复位12864
DelayMs(30);
rst=1;
DelayMs(20);
Write12864Command(0x30);//功能设定:8位控制方式,使用基本指令
Write12864Command(0x08);//显示关
Write12864Command(0x01);//清屏
Write12864Command(0x06);//地址计数器加一、光标右移
Write12864Command(0x0c);//显示开
}
带字库的驱动
❷ 51单片机双机串口通信 一个单片机控制12864显示程序模板
我这里只有RS-485在单片机多机通信中的应用的,不过读懂程序就可以控制12864,不是很难,我同学都有做成功。
1、RS-485在单片机多机通信中的应用
主机程序
#include"reg52.h"
#define uint unsigned int
#define uchar unsigned char
sbit p10=P1^0;
sbit p11=P1^1;
void main(void)
{
uchar i=0;
TMOD=0X20;//设置定时器1工作模式2
TH1=0XFF;
TL1=0XFF; //这里是假设晶振是11。0592的 波特率设置57600
SCON=0X40; //设置方式1 只能发送 不能接受
PCON=0X80;
TR1=1; // 启动T1
while(1)
{
if(p10==0)
{
SBUF=0x11; //次LED单片机的针头
while(TI==0);
TI=0;
while(p10==0);
}
if(p11==0)
{
SBUF=0x12; //次闪单片机的针头
while(TI==0);
TI=0;
while(p11==0);
}
}
}
从机2
#include"reg51.h"
#define uint unsigned int
#define uchar unsigned char
bit flag=0;
sbit p20=P2^0;
void main(void)
{ uchar i=0;
TMOD=0X20;
TH1=0XFF;
TL1=0XFF; //这里晶振频率同主机是11。0592的波特率设置57600
SCON=0X50; //设置方式1 只能发送 不能接受
PCON=0X80;
TR1=1; // 启动T1
while(1)
{
while(RI==0);//采用查询的方法判断时候接受到数据
RI=0;
i=SBUF;
if(i==0x12)
p20=~p20;
i=0x00;
}
}
从机1
RS BIT P1.7
RW BIT P1.6
E BIT P1.5
KOU EQU P2
ORG 0030H
LOP: MOV SP,#5fH
MOV TMOD,#20H
MOV 40H,#00H
MOV TH1,#0FFH
MOV TL1,#0FFH
MOV SCON,#50H
MOV PCON,#80H
SETB TR1
ACALL LCD_MODEL ;初始化的模块
MOV KOU,#81H
ACALL READY
MOV DPTR,#TAB
ACALL WRITE ;显示的模块
MOV P2,#0C1H
ACALL READY
MOV DPTR,#TAB1
ACALL WRITE
xt: jnb RI,$
CLR RI
x: MOV A,SBUF
CJNE A,#11H,rel
INC 40H
MOV A,40H
CJNE A,#10,XTG
MOV 40H,#0
XTG: MOV P2,#0C9H
ACALL READY
MOV DPTR,#TAB2
ACALL WRITEx
AJMP xt
rel: ajmp xt
WRITEx:MOV A,40H
MOVC A,@A+DPTR
MOV KOU,A
ACALL WRITE1
RET
WRITE: MOV A,#00H
MOVC A,@A+DPTR
CJNE A,#0FFH,s
AJMP EXIT
S: MOV KOU,A
ACALL WRITE1
INC DPTR
AJMP WRITE
EXIT: RET
WRITE1:SETB RS
CLR RW
CLR E
ACALL DELAY
SETB E
RET
LCD_MODEL: MOV KOU,#01H
ACALL READY
MOV KOU,#03H
ACALL READY
MOV KOU,#00000110B
ACALL READY
MOV KOU,#00001100B
ACALL READY
MOV KOU,#38H
ACALL READY
RET
READY: CLR RS
CLR RW
CLR E
ACALL DELAY
SETB E
RET
DELAY: MOV KOU,#0FFH
CLR RS
SETB RW
CLR E
NOP
SETB E
JB KOU.7,DELAY
RET
TAB: DB "Proteus 7.1" ,0FFH ;显示字库
TAB1: DB "Count:" ,0FFH
TAB2: DB "0123456789"
END
仿真图
❸ c51单片机控制12864程序(c语言),显示几个字,或一些简单的图片就行!先谢谢了!
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS=P2^5; //片选信号
sbit SID=P2^6; //数据信号
sbit SCLK=P2^7; //时钟信号
sbit RST=P2^2; //复位信号
sbit CH = P2^4; //并行、串行选择信号
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间为 100us * t。这是通过软件延时,有一定误差。
* 输入 : t
* 输出 : 无
***********************************************************************/
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0; i<t; i++)
for(j=0; j<10; j++);
}
/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(unsigned char zdata)
{
unsigned int i;
for(i=0; i<8; i++)
{
if((zdata << i) & 0x80)
{
SID = 1;
}
else
{
SID = 0;
}
SCLK = 0;
SCLK = 1;
}
}
/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode)
{
CS = 1;
sendbyte(0xf8);
sendbyte(cmdcode & 0xf0);
sendbyte((cmdcode << 4) & 0xf0);
delay(2);
}
/********************************************************************
* 名称 : write_data()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_data(unsigned char Dispdata)
{
CS = 1;
sendbyte(0xfa);
sendbyte(Dispdata & 0xf0);
sendbyte((Dispdata << 4) & 0xf0);
delay(2);
}
/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit()
{
RST = 0;
delay(100);
RST = 1;
delay(20000);
write_com(0x30);
delay(50);
write_com(0x0c);
delay(50);
}
/********************************************************************
* 名称 : hzkdis()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void hzkdis(unsigned char code *s)
{
while(*s > 0)
{
write_data(*s);
s++;
delay(50);
}
}
/********************************************************************
* 名称 : Test()
* 功能 : 显示子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Test()
{
write_com(0x03);
delay(50);
write_com(0x81);
hzkdis(" HOT-51");
write_com(0x91);
hzkdis("单片机开发板");
write_com(0x89);
hzkdis(" ");
write_com(0x98);
hzkdis(" 东流电子");
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
CH = 0;
delay(1);
lcdinit();
delay(10);
while(1)
{
Test();
delay(5000);
}
}
❹ 有个51单片机关于12864串口显示读写程序求助(c语言)
if(a&(1<<(i-1))) RW_SID=1;
表示1左移i-1位再于a进行与运算,i=8的情况下i-1=7,1左移7位就是0x80。再跟a与运算(全1出1有0出0)即可获得a的最高位。以此类推可以取出a的所有位。
if(RW_SID==1) dat|=(1<<(i-1));
当RW_SID端口为1时把1左移i-1位跟dat或运算。i=8的情况下1左移i-1位正好是0x80,再经过与运算保存最高位,循环移位再或运算就能读取到全部位保存在dat里面
可以写成
//写部分
if(a&0x80)//取出a的最高位
RW_SID=1;//如果是1则输出1
else
RW_SID=0;//否则输出0
a<<=1;//a整体左移,让第7位补到最高位的位置,循环取出
E_CLK=1;
delay(100);
E_CLK=0;
delay(100);
//读部分
E_CLK=1;
delay(100);
dat<<=1;//接收1次数据后左移。第一次为0的情况影响数据
if(RW_SID)//当端口为高的时候
dat++;//dat+1相当于dat|=1 当端口为0的时候默认左移最低位是补零的,所以不用管
E_CLK=0;//循环8次后第一次接受到的数据就在最高位了
delay(100);
效果是一样的相对来说比较好理解
❺ 谁有用51单片机控制12864显示数字时钟的程序!急求!不用ds1302;简单一点就好。有好的答案加分!
里面有128564显示汉字的程序,自己研究下,不过是用msp430控制的,你改改端口i就可以了。
#include "msp430x26x.h"
#define uchar unsigned char
#define uint unsigned int
#define iDat 1 //数据标志
#define iCmd 0 //指令标志
#define LCDb_RS 0x20 //定义四个控制引脚
#define LCDb_RW 0x40
#define LCDb_E 0x80
#define LCDb_RST 0x04
#define LCDb_L1 0x80 //第一行的地址
#define LCDb_L2 0x90 //第二行的地址
#define LCDb_L3 0x88 //第三行的地址
#define LCDb_L4 0x98 //第四行的地址
#define LCDb_SET_RS P1OUT|=LCDb_RS //四个控制管脚的控制操作
#define LCDb_SET_RW P1OUT|=LCDb_RW
#define LCDb_SET_E P1OUT|=LCDb_E
#define LCDb_SET_RST P8OUT|=LCDb_RST
#define LCDb_CLR_RS P1OUT&=~LCDb_RS
#define LCDb_CLR_RW P1OUT&=~LCDb_RW
#define LCDb_CLR_E P1OUT&=~LCDb_E
#define LCDb_CLR_RST P8OUT&=~LCDb_RST
#define LCDb_DO P4OUT //输出数据总线端口定义
#define LCDb_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符
#define LCDb_BASCMD 0x30 // 基本指令集
#define LCDb_CLS 0x01 // 清屏
#define LCDb_HOME 0x02 // 地址返回原点,不改变DDRAM内容
#define LCDb_ENTRY 0x06 // 设定输入模式,光标加,屏幕不移动
#define LCDb_C2L 0x10 // 光标左移
#define LCDb_C2R 0x14 // 光标右移
#define LCDb_D2L 0x18 // 屏幕左移
#define LCDb_D2R 0x1C // 屏幕又移
#define LCDb_ON 0x0C // 打开显示
#define LCDb_OFF 0x08 // 关闭显示
unsigned char RXData;
unsigned char Seg_Data[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //数码管编码
unsigned char Result[5]; //整数转化成字符串,给LCD显示
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++);
}
void Delayus(uint US)
{
uint i;
US=US*5/4;
for( i=0;i<US;i++);
}
void LCD12864_portini()
{
P1DIR=0xFF;
P4DIR=0xFF;
P5DIR=0xFF;
P8DIR=0xFF;
P8OUT |=LCDb_RST;
// P1OUT=0xFF;
}
/*函数名称: LCD12864_sendbyte
功 能: 向12864液晶写入一个字节数据或者指令
*/
void LCD12864_sendbyte(uchar DatCmd, uchar dByte)
{
if (DatCmd == iCmd) //指令操作
LCDb_CLR_RS;
else
LCDb_SET_RS;
LCDb_CLR_RW; //写操作
LCDb_SET_E;
LCDb_DO = dByte; //写入数据
//Delayus(500);
Delayms(1);
LCDb_CLR_E;
}
/*函数名称: LCD12864_sendstr
功 能: 向12864液晶写入一个字符串
参 数: ptString--字符串指针
返回值 : 无
*/
void LCD12864_sendstr(uchar *ptString)
{
while((*ptString)!='\0') //字符串未结束一直写
{
LCD12864_sendbyte(iDat, *ptString++);
}
}
/*函数名称: LCD12864_clear
功 能: 12864液晶清屏
参 数: 无
返回值 : 无
*/
void LCD12864_clear(void)
{
LCD12864_sendbyte(iCmd,LCDb_CLS);
Delayms(2);// 清屏指令写入后,2ms 的延时是很必要的!!!
}
/*
函数名称: LCD12864_gotoXY
功 能: 移动到指定位置
参 数: Row--指定的行
Col--指定的列
返回值 : 无
*/
void LCD12864_gotoXY(uchar Row, uchar Col)
{
switch (Row) //选择行
{
case 2:
LCD12864_sendbyte(iCmd, LCDb_L2 + Col); break; //写入第2行的指定列
case 3:
LCD12864_sendbyte(iCmd, LCDb_L3 + Col); break; //写入第3行的指定列
case 4:
LCD12864_sendbyte(iCmd, LCDb_L4 + Col); break; //写入第4行的指定列
default:
LCD12864_sendbyte(iCmd, LCDb_L1 + Col); break; //写入第1行的指定列
}
}
/*
函数名称: LCD12864_initial
功 能: 12864液晶初始化
*/
void LCD12864_initial(void)
{
Delayms(100); // 等待内部复位
LCD12864_portini(); //端口初始化
LCD12864_sendbyte(iCmd, LCDb_FUNCTION); //功能、模式设定
LCD12864_sendbyte(iCmd, LCDb_ON); //打开显示
LCD12864_clear(); //清屏
LCD12864_sendbyte(iCmd, LCDb_ENTRY); // 输入模式设定
}
void Int_char(int data)
{
if(data/1000)
{
Result[0]=data/1000+'0';
Result[1]=data/100%10+'0';
Result[2]=data/10%10+'0';
Result[3]=data%10+'0';
Result[4]=0;
}
else if(data/100)
{
Result[0]=data/100+'0';
Result[1]=data/10%10+'0';
Result[2]=data%10+'0';
Result[3]=0;
}
else if(data/10)
{
Result[0]=data/10%10+'0';
Result[1]=data%10+'0';
Result[2]=0;
}
else
{
Result[0]=data%10+'0';
Result[1]=0;
}
}
unsigned char Key_Press(void)
{
P7OUT=0xF0;
if((P7IN&0x10)&&(P7IN&0x20)&&(P7IN&0x40)&&(P7IN&0x80)) return 0x00;
else return 0xFF;
}
unsigned char Get_Keycode(void)
{
while(1)
{
P7OUT=0xFE; //扫描第一列
if((P7IN&0x10)==0) return 0;
else if((P7IN&0x20)==0) return 4;
else if((P7IN&0x40)==0) return 8;
else if((P7IN&0x80)==0) return 12;
P7OUT=0xFD; //扫描第二列
if((P7IN&0x10)==0) return 1;
else if((P7IN&0x20)==0) return 5;
else if((P7IN&0x40)==0) return 9;
else if((P7IN&0x80)==0) return 13;
P7OUT=0xFB; //扫描第三列
if((P7IN&0x10)==0) return 2;
else if((P7IN&0x20)==0) return 6;
else if((P7IN&0x40)==0) return 10;
else if((P7IN&0x80)==0) return 14;
P7OUT=0xF7; //扫描第四列
if((P7IN&0x10)==0) return 3;
else if((P7IN&0x20)==0) return 7;
else if((P7IN&0x40)==0) return 11;
else if((P7IN&0x80)==0) return 15;
}
}
void Init_compa()
{
CACTL1 = CAON+CAREF_2+CARSEL; // Enable Comp, ref = 0.5*Vcc = Vin-
CACTL2 = P2CA0; // Pin to CA0
P1DIR |= 0x01; // P1.0 = o/p direction(CAOUT - LED)
P1SEL |= 0x01; // P1.0 - CAOUT, option select
}
/*
** 函数名称:初始化函数
*/
void Init_IIC(void)
{
P3SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x50; // Slave Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0RXIE; // Enable RX interrupt
_BIS_SR(GIE);
// RXCompare = 0x0; // Used to check incoming data
}
/** 函数名称:字节写函数
*/
void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word)
{
while (UCB0CTL1 & UCTXSTP); // 确定总线空闲
UCB0CTL1 |= UCTXSTT + UCTR; // 发送起始位,确定为发送模式
UCB0TXBUF = high_Address; // 发送高位地址
while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕
UCB0TXBUF = low_Address; // 发送低位地址
while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕
UCB0TXBUF = Word; // 发送数据
while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕
UCB0CTL1 |= UCTXSTP; // 发送停止位
while((UCB0CTL1 & UCTXSTP)==1); // 判断停止位是否发送完毕
}
/**
** 函数名称:字节读函数
*/
void EEPROM_readmore()
{
UCB0CTL1 &= ~UCTR; // 确定为读
while (UCB0CTL1 & UCTXSTP); // 总线是否空闲
UCB0CTL1 |= UCTXSTT; // 发送开始位
}
/*
** 函数名称:字节写函数
**/
void EEPROM_read(unsigned char high_Address,unsigned char low_Address)
{
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT + UCTR; // 发送起始位,确定为写
UCB0TXBUF = high_Address; // 发送地址位高位
while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕
UCB0TXBUF = low_Address; // 发送地址位低位
while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕
UCB0CTL1 &= ~UCTR; // 确定为接收
while (UCB0CTL1 & UCTXSTP); //
UCB0CTL1 |=UCTXSTT ;
while((UCB0CTL1 & UCTXSTT)==1);
for(unsigned char i=0x0;i<0x2f;i++); // 延时确定数据已经被发送出去
UCB0CTL1 |=UCTXSTP + UCTXNACK; // 发送停止位和NACK位
}
/*
** 函数名称:接收中断函数
**/
// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
RXData = UCB0RXBUF; // Get RX data
Int_char(RXData);
LCD12864_gotoXY(2,0); //第2行,第1列显示
LCD12864_sendstr(Result);
/*
key_code[0]=RXData%10+'0';
key_code[1]=0;
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr(key_code);
*/
// __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
void Init_UART()
{
P3OUT &= ~(BIT4+BIT5+BIT6+BIT7);
P3SEL = 0xF0; // P3.4,5,6,7 = USCI_A0 TXD/RXD USCI_A1 TXD/RXD
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600 = 3.41
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS1 + UCBRS0; // Molation UCBRSx = 3
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK
UCA1BR0 = 0x03; // 32kHz/9600 = 3.41
UCA1BR1 = 0x00; //
UCA1MCTL = UCBRS1 + UCBRS0; // Molation UCBRSx = 3
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UC1IE |= UCA1RXIE; // Enable USCI_A0 RX interrupt
_BIS_SR(GIE); //使能中断
}
void Init_ADC()
{
ADC12CTL0 = SHT0_2 + ADC12ON; // Set sampling time, turn on ADC12
ADC12CTL1 = SHP; // Use sampling timer
ADC12IE = 0x01; // Enable interrupt
ADC12CTL0 |= ENC; // Conversion enabled
P6DIR &= 0x01; // P6.0, i/p
P6SEL |= 0x01; // P6.0-ADC option select
_BIS_SR(GIE); //使能中断
}
void Start_ADC()
{
ADC12CTL0 |= ADC12SC; // Start convn, software controlled
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF; // TX -> RXed character
LCD12864_sendbyte(iDat,UCA0RXBUF);
}
#pragma vector=USCIAB1RX_VECTOR
__interrupt void USCI1RX_ISR(void)
{
while (!(UC1IFG&UCA1TXIFG)); // USCI_A0 TX buffer ready?
UCA1TXBUF = UCA1RXBUF; // TX -> RXed character
LCD12864_sendbyte(iDat,UCA0RXBUF);
//UCA1TXBUF = 'z';
}
// ADC12 interrupt service routine
#pragma vector=ADC12_VECTOR
__interrupt void ADC12_ISR (void)
{
int i=ADC12MEM0;
Int_char(i);
LCD12864_gotoXY(2,0); //第1行,第1列显示
LCD12864_sendstr(Result);
/*
key_code[0] =i/1000+'0';
key_code[1] =i/100%10+'0';
key_code[2] =i/10%10+'0';
key_code[3] =i%10+'0';
key_code[4] =0;
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr(key_code);
*/
}
void Init_all()
{
LCD12864_initial(); //LCD初始化,包含了数码管和LED灯初始化
P7DIR=0x0F; //键盘扫描初始化
P7REN=0xF0; //输入上下拉电阻使能,输出上下拉不使能
P7OUT=0xF0; //输入上拉
Init_UART(); //串口初始化
Init_compa(); //比较器初始化
Init_ADC(); //ADC初始化
Init_IIC(); //IIC初始化
}
void Test_Led()
{
unsigned char i=0;
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("1.Test_LED");
for(;i<16;i++)
{
P8OUT=0xF0|i;
Delayms(50);
}
}
void Test_Seg()
{
int i;
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("2.Test_SEG");
for(i=0;i<500;i++)
{
//4,3,2,1
P1OUT&=~0x02;
P1OUT|=0x10|0x08|0x04;
P5OUT=Seg_Data[9]; //清楚数码管显示
Delayms(1);
P1OUT&=~0x04;
P1OUT|=0x10|0x08|0x02;
P5OUT=Seg_Data[8]; //清楚数码管显示
Delayms(1);
P1OUT&=~0x08;
P1OUT|=0x10|0x04|0x02;
P5OUT=Seg_Data[7]; //清楚数码管显示
Delayms(1);
P1OUT&=~0x10;
P1OUT|=0x08|0x04|0x02;
P5OUT=Seg_Data[6]; //清楚数码管显示
Delayms(1);
}
P5OUT=0x00; //熄灭所有数码管
}
void Test_Key()
{
unsigned char i=0;
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("3.Test_KEY");
LCD12864_gotoXY(2,0); //第2行,第1列显示
LCD12864_sendstr("按键:");
for(;i<16;i++)
{
Int_char(Get_Keycode());
LCD12864_gotoXY(2,3);
LCD12864_sendstr(" ");
LCD12864_gotoXY(2,3);
LCD12864_sendstr(Result);
Delayms(100); //防抖
}
}
void Test_Uart()
{
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("4.Test_UART");
LCD12864_gotoXY(2,0); //第2行,第1列显示
}
void Test_Compa()
{
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("5.Test_COMPA");
}
void Test_ADC()
{
int i=0;
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("6.Test_ADC");
for(;i<200;i++)
{
Start_ADC();
Delayms(10);
}
}
void Test_IIC()
{
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("7.Test_IIC");
EEPROM_Write(0x00,0x40,7); // 字节写
Delayms(10);
EEPROM_read(0x00,0x40);
}
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;//关闭看门狗
Init_all();
while(1){
Test_Led(); //1.测试LED
LCD12864_gotoXY(2,0); //第1行,第1列显示
LCD12864_sendstr("请按16键!");
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
Test_Seg(); //2.测试数码管
LCD12864_gotoXY(2,0); //第1行,第1列显示
LCD12864_sendstr("请按16键!");
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
Test_Key(); //3.测试按键扫描
LCD12864_gotoXY(2,0); //第1行,第1列显示
LCD12864_sendstr("请按16键!");
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
LCD12864_gotoXY(3,0); //第3行,第1列显示
LCD12864_sendstr("请按16键!");
Test_Uart(); //4.测试串口
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
Test_Compa(); //5.测试比较器
LCD12864_gotoXY(2,0); //第2行,第1列显示
LCD12864_sendstr("请按16键!");
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
Test_ADC(); //6.测试ADC
LCD12864_gotoXY(3,0); //第3行,第1列显示
LCD12864_sendstr("请按16键!");
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
Test_IIC(); //7.测试IIC
Delayms(100);
LCD12864_gotoXY(3,0); //第3行,第1列显示
LCD12864_sendstr("测试完成");
while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子
LCD12864_clear();
}
}
❻ 求个51单片机控制KNY12864M液晶屏的简单程序
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define Nop() _nop_()
/*引脚端口定义*/
sbit LCD12864_RS_PORT = P1^7; /*LCD12864引脚定义*/
sbit LCD12864_RW_PORT = P1^6;
sbit LCD12864_E_PORT = P2^3;
#define LCD12864_DA_PORT P0
sbit led_en_port = P2^5; /*发光二极管寄存器LE引脚*/
sbit sled_en_port = P3^6; /*数码管寄存器LE引脚*/
uchar hanzi_buff1[]={" 液晶显示 "};
//////////////////以下是LCD12864驱动程序////////////////
void LCD12864_WaitIdle()
//LCD12864 忙 信号检测
{
LCD12864_DA_PORT = 0xff;
LCD12864_RS_PORT = 0;
LCD12864_RW_PORT = 1;
LCD12864_E_PORT = 1;
while((LCD12864_DA_PORT&0x80)==1); /*等待BF 不为1*/
LCD12864_E_PORT = 0;
}
void LCD12864_COM_Write( uchar com_da)
/* 检测忙信号写入命令字
com_da 为待写入的命令字*/
{
LCD12864_WaitIdle();
LCD12864_RS_PORT = 0;
LCD12864_RW_PORT = 0;
LCD12864_DA_PORT = com_da;
LCD12864_E_PORT = 1;
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
LCD12864_E_PORT = 0;
}
void LCD12864_NoWaitIdle_COM_Write(uchar com_da)
/* 不检测忙信号写入命令字
com_da 为待写入的命令字*/
{
LCD12864_RS_PORT = 0;
LCD12864_RW_PORT = 0;
LCD12864_DA_PORT = com_da;
LCD12864_E_PORT = 1;
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
LCD12864_E_PORT = 0;
}
void LCD12864_Data_Write(uchar da)
/* 数据写入
da 为待写入的8位数据*/
{
LCD12864_WaitIdle(); /*检测忙信号*/
LCD12864_RS_PORT = 1;
LCD12864_RW_PORT = 0;
LCD12864_DA_PORT = da;
LCD12864_E_PORT = 1;
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
LCD12864_E_PORT = 0;
}
void lcd_delay_ms(uchar x)
{
uchar j;
while(x--){
for(j=0;j<125;j++)
{;}
}
}
void LCD12864_Reset()
/*LCD12864初始化*/
{
lcd_delay_ms(100); /*适当延时待LCD自动复位完成*/
LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/
lcd_delay_ms(10);
LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/
lcd_delay_ms(10);
LCD12864_NoWaitIdle_COM_Write(0x0c); /*显示开及光标设置*/
lcd_delay_ms(10);
LCD12864_NoWaitIdle_COM_Write(0x01); /*显示清屏*/
lcd_delay_ms(30);
LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址计数器(AC)加1*/
lcd_delay_ms(30);
}
void LCD12864_HANZI_WRITE(uchar xpos,uchar ypos,uchar daH,uchar daL)
//ST7920 汉字字符写入
//参数说明: xpos 待写入的X位置
//ypos 待写入的Y位置
//daH 待写入的汉字的高八位 daL待写入的汉字的低八位
{
uchar xy_pos;
if((xpos>=8)||(ypos>=4) ) return; /*X位置超出显示范围退出*/
if(ypos==0) xy_pos = 0x80 + xpos;
else if(ypos==1) xy_pos = 0x90 + xpos; /*计算转换地址*/
else if(ypos==2) xy_pos = 0x88 + xpos;
else if(ypos==3) xy_pos = 0x98 + xpos;
LCD12864_COM_Write(xy_pos); /*写地址*/
lcd_delay_ms(1);
LCD12864_Data_Write(daH); /*写高八位数据*/
lcd_delay_ms(1);
LCD12864_Data_Write(daL); /*写低八位数据*/
lcd_delay_ms(1);
}
//////////////////以上是LCD12864驱动程序////////////////
void main()
{
uchar i;
LCD12864_Reset(); /*LCD初始化*/
LCD12864_DA_PORT = 0xff; /*释放P0端口*/
led_en_port = 0;/*关闭发光二极管显示*/
sled_en_port = 0;/*关闭数码管显示*/
while(1)
{
for (i=0;i<6;i++)
LCD12864_HANZI_WRITE(i,0,hanzi_buff1[i*2],hanzi_buff1[i*2+1]);
}
}
❼ 如何在12864(带子库)编写显示变化数字的子程序中文显示程序已会。
#define uchar unsigned char
#define uint unsigned int
#define iDat 1 //数据标志
#define iCmd 0 //指令标志
#define LCDb_RS 0x20 //定义四个控制引脚
#define LCDb_RW 0x40
#define LCDb_E 0x80
#define LCDb_RST 0x04
#define LCDb_L1 0x80 //第一行的地址
#define LCDb_L2 0x90 //第二行的地址
#define LCDb_L3 0x88 //第三行的地址
#define LCDb_L4 0x98 //第四行的地址
#define LCDb_SET_RS P1OUT|=LCDb_RS //四个控制管脚的控制操作
#define LCDb_SET_RW P1OUT|=LCDb_RW
#define LCDb_SET_E P1OUT|=LCDb_E
#define LCDb_SET_RST P8OUT|=LCDb_RST
#define LCDb_CLR_RS P1OUT&=~LCDb_RS
#define LCDb_CLR_RW P1OUT&=~LCDb_RW
#define LCDb_CLR_E P1OUT&=~LCDb_E
#define LCDb_CLR_RST P8OUT&=~LCDb_RST
#define LCDb_DO P4OUT //输出数据总线端口定义
#define LCDb_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符
#define LCDb_BASCMD 0x30 // 基本指令集
#define LCDb_CLS 0x01 // 清屏
#define LCDb_HOME 0x02 // 地址返回原点,不改变DDRAM内容
#define LCDb_ENTRY 0x06 // 设定输入模式,光标加,屏幕不移动
#define LCDb_C2L 0x10 // 光标左移
#define LCDb_C2R 0x14 // 光标右移
#define LCDb_D2L 0x18 // 屏幕左移
#define LCDb_D2R 0x1C // 屏幕又移
#define LCDb_ON 0x0C // 打开显示
#define LCDb_OFF 0x08 // 关闭显示
unsigned char RXData;
unsigned char Result[5]; //整数转化成字符串,给LCD显示
/*******************************************
函数名称: Delayms
功 能: 延时指定毫秒(8M晶振)
参 数: MS--延时的毫秒数
返回值 : 无
********************************************/
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++);
}
/*******************************************
函数名称: Delayus
功 能: 延时指定微秒(8M晶振)
参 数: US--延时的微秒数(大约,不是很精确,MS越大越准确)
返回值 : 无
********************************************/
void Delayus(uint US)
{
uint i;
US=US*5/4;
for( i=0;i<US;i++);
}
void LCD12864_portini()
{
P1DIR=0xFF;
P4DIR=0xFF;
P8DIR=0xFF; //Trig =P8^3输出;
P8OUT |=LCDb_RST;
// P1OUT=0xFF;
}
/******************************************
函数名称: LCD12864_sendbyte
功 能: 向12864液晶写入一个字节数据或者指令
参 数: DatCmd--为iDat时是数据,为iCmd时是指令
dByte--为写入12864的数据或者指令
返回值 : 无
********************************************/
void LCD12864_sendbyte(uchar DatCmd, uchar dByte)
{
if (DatCmd == iCmd) //指令操作
LCDb_CLR_RS;
else
LCDb_SET_RS;
LCDb_CLR_RW; //写操作
LCDb_SET_E;
LCDb_DO = dByte; //写入数据
//Delayus(500);
Delayms(1);
LCDb_CLR_E;
}
/*******************************************
函数名称: LCD12864_sendstr
功 能: 向12864液晶写入一个字符串
参 数: ptString--字符串指针
返回值 : 无
********************************************/
void LCD12864_sendstr(uchar *ptString)
{
while((*ptString)!='\0') //字符串未结束一直写
{
LCD12864_sendbyte(iDat, *ptString++);
}
}
/*******************************************
函数名称: LCD12864_clear
功 能: 12864液晶清屏
参 数: 无
返回值 : 无
********************************************/
void LCD12864_clear(void)
{
LCD12864_sendbyte(iCmd,LCDb_CLS);
Delayms(2);// 清屏指令写入后,2ms 的延时是很必要的!!!
}
/*******************************************
函数名称: LCD12864_gotoXY
功 能: 移动到指定位置
参 数: Row--指定的行
Col--指定的列
返回值 : 无
********************************************/
void LCD12864_gotoXY(uchar Row, uchar Col)
{
switch (Row) //选择行
{
case 2:
LCD12864_sendbyte(iCmd, LCDb_L2 + Col); break; //写入第2行的指定列
case 3:
LCD12864_sendbyte(iCmd, LCDb_L3 + Col); break; //写入第3行的指定列
case 4:
LCD12864_sendbyte(iCmd, LCDb_L4 + Col); break; //写入第4行的指定列
default:
LCD12864_sendbyte(iCmd, LCDb_L1 + Col); break; //写入第1行的指定列
}
}
/*******************************************
函数名称: LCD12864_initial
功 能: 12864液晶初始化
参 数: 无
返回值 : 无
********************************************/
void LCD12864_initial(void)
{
Delayms(100); // 等待内部复位
LCD12864_portini(); //端口初始化
LCD12864_sendbyte(iCmd, LCDb_FUNCTION); //功能、模式设定
LCD12864_sendbyte(iCmd, LCDb_ON); //打开显示
LCD12864_clear(); //清屏
LCD12864_sendbyte(iCmd, LCDb_ENTRY); // 输入模式设定
}
void Int_char(int data)
{
if(data/1000)
{
Result[0]=data/1000+'0';
Result[1]=data/100%10+'0';
Result[2]=data/10%10+'0';
Result[3]=data%10+'0';
Result[4]=0;
}
else if(data/100)
{
Result[0]=data/100+'0';
Result[1]=data/10%10+'0';
Result[2]=data%10+'0';
Result[3]=0;
Result[4]=0;
}
else if(data/10)
{
Result[0]=data/10%10+'0';
Result[1]=data%10+'0';
Result[2]=0;
Result[3]=0;
Result[4]=0;
}
else
{
Result[0]=data%10+'0';
Result[1]=0;
Result[2]=0;
Result[3]=0;
Result[4]=0;
}
}
这使msp430单片机的程序,只要在主函数中调用函数,就是调用这个函数Int_char(tmp);每一次循环调用一次,这样可以实时显示这个变化温度数值
LCD12864_gotoXY(2,4);
LCD12864_sendstr(" ");
LCD12864_gotoXY(1,0); //第1行,第1列显示
LCD12864_sendstr("正在检测");
LCD12864_gotoXY(2,0); //第2行,第1列显示
LCD12864_sendstr("距离是:");
Int_char(tmp);