TA的每日心情 | 开心 3 小时前 |
---|
签到天数: 148 天 [LV.7]常住居民III
高级会员
- 积分
- 672
|
楼主 |
发表于 2023-10-30 10:35:46
|
显示全部楼层
本帖最后由 浦江一水 于 2023-11-6 10:51 编辑
主程序源码:
/******************************************************************
* 工程: PxmTest STC32G12K128 + LCD1602
* 实验: 基本系统: LCD1602串口显示屏 8位数据控制 USART1_串口通讯..4键8值..
* 四键: P32/P33/P34/P35 四LED:P20/P21/P22/P23
* 功能说明: 测试LCD1602和4键操作,练习串口通信, 制作成LCD1602串口显示屏
* 编程: 浦晓明(浦江一水) 2023-10 ...
*******************************************************************/
#include "STC32G.H" //此文件中定义了单片机的一些特殊功能寄存器
#include <stdio.h>
#include <string.h>
#include "KEY4_IO.H" //4键盘相关函数
#include "LCD1602.H" //LCD1602显示屏相关函数
//波特率计算...
#define FOSC 11059200UL //晶振频率
#define BRT (256 - FOSC / 9600 / 32) //按照波特率9600计算
//#define BRT (256 - FOSC / 115200 / 32) //按照波特率115200计算
sbit LED0 = P2^0; //运行指示
sbit LED1 = P2^1; //运行指示
sbit LED2 = P2^2; //运行指示
sbit LED3 = P2^3; //运行指示
char RxBuf[24],k; //串口接收缓存
unsigned short RxCount=0; //接收计数器
char S[20]; //LCD显示缓存
unsigned char X,Y; //坐标
unsigned char RxOK=0; //串口通信接收到标志
//毫秒级延时
void delay(unsigned int ms)
{ unsigned int x,y;
for(x = ms; x > 0; x--)
for(y =114; y > 0; y--);
}
//串口初始化:
void UART_init()
{
SCON= 0x50;
TMOD= 0x20; //T1工作模式2 8位自动重装
TH1 = BRT; //0xFD;
TL1 = BRT; //0xFD; //比特率115200
TR1 = 1; //启动T1定时器
AUXR= 0x40;
SM0 = 0;
SM1 = 1; //串口工作方式1 10位异步
REN = 1; //串口允许接收
ES = 1; //串口中断打开
EA = 1; //开总中断
}
/*----------------------------
通过串口1发送单字节数据
----------------------------*/
void SendData(unsigned char ch)
{
SBUF = ch; //写数据到UART数据寄存器
while(TI == 0);
TI = 0;
}
/*----------------------------
通过串口1发送字符串
----------------------------*/
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{ SendData(*s++); } //发送当前字符
}
//--------------------------------------------------------------
// 串口1接收中断服务...
//--------------------------------------------------------------
void UART() interrupt 4
{ unsigned char ch=0;
if(RI) //检测是否接收完成
{ ch=SBUF; //接收单字节
RI = 0; //清除标志位
if(ch==0x0A) //结尾标志
{ RxOK=1; //接收到指令串置接收到标志
if((RxCount>0)&&(RxBuf[RxCount-1]==0x0D)){ RxBuf[RxCount-1]=0;RxBuf[RxCount]=0; }
}
else if(RxCount<19)RxBuf[RxCount++]=ch;
}
}
//--------------------------------------------------------------
// 主程序入口
//--------------------------------------------------------------
void main(void)
{ unsigned char i,mode;
unsigned int wait=0;
//IO端口初始化
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
//IO端口初始化//全部为准双向口
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
//外设初始化
UART_init();
LCD_Init(); //初始化LCD1602
LCD_CLS(); //测试清屏函数
LCD_Blink(0); //测试函数
LCD_Cursor(0); //测试函数
LCD_SetXY(0,0);//测试函数
delay(5);
LED0 = 0; delay(1000); //测试IO口控制 LED0亮
LED1 = 0; delay(1000);
LED2 = 0; delay(1000);
LED3 = 0; delay(1000);
LED0 = 1; delay(1000); //测试IO口控制 LED0灭
LED1 = 1; delay(1000);
LED2 = 1; delay(1000);
LED3 = 1; delay(1000);
//显示屏初始界面
LCD_STR(0,0,"PXM_STC32G12K128");
LCD_STR(1,0,"LCD1602+4KEY4LED");
//测试通讯口发送字符串
SendString("STC32G12K128_UART1_OK\r\n");
delay(1000);
//GETCH();
//大循环
while(1)
{ k=0;
k=RDKEY(); //扫描按键
if(k!=0)
{ sprintf(S,"KEY=%02X ",(unsigned int)k); //当有键按下时, 显示键值,(<1秒为短按 >=1秒为长按)
LCD_STR(1,10,S); //比如短按Key1,显示=10, 长按显示=11
}
//运行指示
if(wait==0) { LED0 = 0; } // LED亮
if(wait==200){ LED0 = 1; RxOK=0;RxCount=0;RxBuf[0]=0; } // LED灭
wait=wait<2250?wait+1:0; //计数器循环
//串口屏通讯处理....
if(RxOK) //接收到指令串
{ //解析串口接收指令字符串,显示之
switch(RxBuf[0])
{ case 'P': //显示指令
X=RxBuf[1]-0x30;
Y=RxBuf[2]-0x30; if(Y>9)Y=Y-7;
for(i=0;i<RxCount-3;i++){ S=RxBuf[3+i]; S[i+1]=0; }
LCD_STR(X,Y,S); //显示接收字符串
break;
case '@': X=RxBuf[1]-0x30;
Y=RxBuf[2]-0x30; if(Y>9)Y=Y-7;
LCD_SetXY(X,Y); //光标定位
break;
case '_': mode=RxBuf[1]-0x30;if(mode>0)mode=1;
LCD_Cursor(mode);//光标显示
break;
case '*': mode=RxBuf[1]-0x30;if(mode>0)mode=1;
LCD_Blink(mode); //光标闪动
break;
case 'C': mode=RxBuf[1]-0x30;
if(mode==0)LCD_STR(0,0," ");//清屏第一行
if(mode==1)LCD_STR(1,0," ");//清屏第二行
if(mode>=2)LCD_CLS(); //清全屏
break;
default: RxBuf[RxCount]=0; SendString(RxBuf); SendData(0x0D); SendData(0x0A); break; //默认返回原串...
}
for(i=0;i<24;i++)RxBuf=0;RxOK=0; RxCount=0;
} //清除接收缓存
delay(10);
}
}
//******************************************************************************
// 附件: LCD1602串口屏通信控制指令协议,9600,8,1,N
//----------------------------------------------------------------------
// 共五条指令, 说明如下...
//----------------------------------------------------------------------
// 1, 格式: PXYsss...\r\n +0D+0A
// 其中: P -- 命令字 指定坐标显示字符串;
// X -- 显示行坐标, X=0或1,表示第一行或第二行
// Y -- 显示列坐标, Y=0...F(超过9用ABCDEF的16进制表示)
// sss... 需要显示的字符串 (长度限于16字符)(LCD1602每行最多显示16字符)
// \r\n 发送串结尾标志,回车换行符 即+0x0D+0x0A,(以下同)
// 实例: P00ABCDEFG+0.1234(\r\n) 在显示屏第一行首显示"ABCDEFG+0.1234"
//----------------------------------------------------------------------
// 2, 格式: Cm\r\n
// 其中: C -- 命令字 清屏
// m -- 参数 0:清第一行 1:清第二行 2:清全屏
// 实例: C0\r\n 显示屏第一行被清空;
//----------------------------------------------------------------------
// 3, 格式: @XY\r\n
// 其中: @ -- 命令字 指定当前光标坐标
// X,Y -- 参数 X:行 Y:列
// 实例: @01\r\n 当前光标在第一行第1列 (光标是否显示取决于以下指令)
//----------------------------------------------------------------------
// 4, 格式: *m\r\n
// 其中: * -- 命令字 光标闪烁显示
// m -- 参数 0:不闪烁 1:闪烁
// 实例: *1 在先前指定的坐标位置闪烁光标;
//----------------------------------------------------------------------
// 5, 格式: _m\r\n
// 其中: _ -- 命令字 底画线显示
// m -- 参数 0:不显示底画线 1:显示底画线
// 实例: _1 在先前指定的坐标位置显示底画线; (底画线显示后,光标闪烁取消)
//*******************************************************************************
01-LCD1602 4KEY USART1.rar
(26.3 KB, 下载次数: 28)
|
|