浦江一水 发表于 2024-7-14 21:47:43

初试 8051U, 做个小实验...

初试 8051U, 做个小实验...

首先感谢国芯论坛官方赠送寄来 8051U 新芯片,
使本单片机爱好者有机会接触和得到学习实验的机会。

STC8051U其中封装之一的PDIP40芯片,
其引脚分布对比传统的8031以及89C51,除了几个特殊引脚以外,
全部对应相同。

这就使人立即想到是否可以利用传统51单片机实验板来做实验了。
手头正好有一块QX-MCS51_V3.0实验板, 换上STC8051U以后, 果然, 无需做任何硬件改动, 就能上手实验了。
或许这可称是STC8051U的亮点和特别用心了,老项目可以很方便地直接升级提高性能了。

本人做了一个最基本的、简单的实验,内容涵盖:
1,对LED灯驱动;
2,对LCD1602点阵字符显示屏的驱动;
3,实验四个独立按键功能,能分别辨识长按和短按;
   (当按下底部四个键之一时,LCD屏幕和LED灯显示键值)
4,串口通讯实验,与上位PC机对话,实现串口屏功能。
   (PC机发送串口屏指令时,LCD执行显示,发送非串口屏指令时,原字符串返回PC机)
由于QX-MCS51_V3.0实验板,有USB转TTL接口,并具有自动断电上电功能,
因此,在使用STC-ISP软件时,顺利对接,检测MCU类型,制作串口仿真芯片等等,都顺利通过。
( 有关ADC、DMA、SPI、I2C、PWM...等外设功能, 有待逐步学习实验.... )

主程序贴一下:
/******************************************************************
* 工程: Test STC8051U(DIP40) + LCD1602A
* 基于: QX-MCS51_V3.0(STC89C52)单片机实验板
* 实验: LCD1602串口显示屏,8位数据控制,USART1_串口通讯,4键8值..
* 四键: P30/P31/P32/P33 8LED:P10...P17
* 说明: 测试STC8051U在传统51实验板上,不做任何硬件改动的实验...
* 编程: 浦晓明(浦江一水) 2024-07-12 ...
*******************************************************************/
#include "STC8051U.h"
#include <stdio.h>
#include <string.h>
#include "KEY4_IO.H"    //4键盘相关函数
#include "LCD1602.H"    //LCD1602A显示屏相关函数

//波特率计算...      
#define FOSC            11059200UL                      //晶振频率
#define BRT             (256 - FOSC / 9600 / 32)      //按照波特率9600计算
//#define BRT         (256 - FOSC / 115200 / 32)//按照波特率115200计算

sbit LED0= P1^7;            //运行状态指示

char RxBuf,k;                //串口接收缓存
unsigned short RxCount=0;//接收计数器
char S;                         //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工作模式28位自动重装
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==0x0D)){ RxBuf=0;RxBuf=0; }
    }
    else if(RxCount<19)RxBuf=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亮
LED0 = 1; delay(1000); //测试IO口控制 LED0灭
//显示屏初始界面
LCD_STR(0,0,"STC8051U_U1_9600");
LCD_STR(1,0,"LCD1602A+4KEY=00");
//测试通讯口发送字符串
SendString("STC8051U_UART1_OK\r\n");
delay(1000);
//大循环
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...
       P1 = ~k;                   //显示键值   
    }
    //运行指示灯...
    if(wait==0){LED0 = 0; }                               // LED亮
    if(wait==200){LED0 = 1; RxOK=0;RxCount=0;RxBuf=0; }// LED灭
    wait=wait<2250?wait+1:0;//计数器循环
    //串口屏通讯处理....
    if(RxOK)//接收到指令串
    { //解析串口接收指令字符串,显示之
      switch(RxBuf)
      { case 'P'://显示指令
                   X=RxBuf-0x30;
                   Y=RxBuf-0x30; if(Y>9)Y=Y-7;
                   for(i=0;i<RxCount-3;i++){ S=RxBuf; S=0; }
                   LCD_STR(X,Y,S);//显示接收字符串
                   break;
      case '@':X=RxBuf-0x30;
                   Y=RxBuf-0x30; if(Y>9)Y=Y-7;
                   LCD_SetXY(X,Y);//光标定位
                   break;
      case '_':mode=RxBuf-0x30;if(mode>0)mode=1;
                   LCD_Cursor(mode);//光标显示      
                   break;
      case '*':mode=RxBuf-0x30;if(mode>0)mode=1;
                   LCD_Blink(mode); //光标闪动
                   break;
      case 'C':mode=RxBuf-0x30;
                   if(mode==0)LCD_STR(0,0,"                ");//清屏第一行
                   if(mode==1)LCD_STR(1,0,"                ");//清屏第二行
                   if(mode>=2)LCD_CLS();                      //清全屏
                   break;
      default:   RxBuf=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 在先前指定的坐标位置显示底画线; (底画线显示后,光标闪烁取消)
//*******************************************************************************

其余见工程文件所包含, 供有兴趣的初学爱好者们参考:



嵌入式之路 发表于 2024-7-15 01:46:01

这是串口屏吗?

jwd 发表于 2024-7-15 06:29:34

{:4_250:}

xxkj2010 发表于 2024-7-15 08:22:40

老瓶换新酒,{:4_250:}

神农鼎 发表于 2024-7-15 08:38:53

LCD12864, LCD1602如不是用的 SPI, 而是 M6800并行/TFT接口
可以使用 STC8051U的 i8080/M6800-TFT彩屏接口
控制慢速的 LCD12864/LCD1602,
新增加 i8080/M6800-TFT彩屏接口 降速机制

神农鼎 发表于 2024-7-15 08:38:53

LCD12864, LCD1602如不是用的 SPI,
而是 M6800并行/TFT接口,
可以使用 STC8051U的 i8080/M6800-TFT彩屏接口
控制速度不能超过1M的 慢速 LCD12864/LCD1602,
新增加 i8080/M6800-TFT彩屏接口 降速机制









STC8051U-大学计划实验箱 V1.1 原理图,参考PCB, 2024/7/12 - 单片机创意设计大赛 @【STC & 嘉立创EDA】 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)





springvirus 发表于 2024-7-15 08:48:07

感谢楼主分享!!

神农鼎 发表于 2024-7-15 08:52:30





Snapdragon 发表于 2024-7-15 18:13:17

{:5_332:}
我的也到了,今晚就试试。
TFPU@108MHz 太强了简直

浦江一水 发表于 2024-7-15 21:35:22

非常感谢神农鼎管理员的鲜花鼓励。

关于可采用 8051U的i8080/M6800-TFT彩屏接口模式,看了手册资料,对接口引脚相对有固定选择。
现有实验板难以调整了,准备改日再做一块实验板,专门用来做LCM模式驱动LCD1602或LCD12864显示屏实验。
页: [1] 2 3 4 5 6
查看完整版本: 初试 8051U, 做个小实验...