| 
				打卡等级:以坛为家III打卡总天数:657最近打卡:2025-10-31 08:27:32   荣誉版主 
 
	积分4469 
 | 
 
| 初试 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[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亮
 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]=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 在先前指定的坐标位置显示底画线; (底画线显示后,光标闪烁取消)
 //*******************************************************************************
 
 其余见工程文件所包含, 供有兴趣的初学爱好者们参考:
 
  03 TestSTC8051U.rar
(38.44 KB, 下载次数: 317) 
 
 
 | 
2
喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
 
 +2楼主威武~
 +1楼主威武~
 |