我也是最近学习单片机和MATLAB的小白平时在看学习的时候 下载了一些有价值的参考文献
概述 - 采用51单片机,atmel的STC89C52RC芯片,主要用到的是七段数码管用来做一个时钟,程序编写软件为keil,烧录软件为STC-ISP 4.88,串口调试软件用的是sscom42。
- 运用Matlab的GUI工具编辑一个可视化界面,用以跟单片机进行串口通信
实现功能- 运用keil编写时钟程序,烧录到单片机中,时钟程序实现的功能是实现时钟的显示,并且能用开发板上的三个按钮进行时钟的修改,一个按钮进入修改模式,另两个实现时间的增减。
- 编辑GUI界面,实现对单片机的控制,其中,GUI界面通过串口能不断的采样开发板上时钟的数值,并在GUI界面上进行显示。同样的,可以通过GUI界面实现对开发板上时钟的修改。
具体实现
B) Matlab GUI界面的编辑 效果图如下,操作说明:START点击开始,采集单片机时钟时间,ADJUST点击进入修改模式,同时单片机开发板亦会进入修改模式,EXIT点击关串口,退出界面,GET点击获取当前值,另外一些辅助按钮,滑块按钮都有各自功能,易于理解。 其中: global s s=serial('COM10'); fopen(s); handles.timer = timer('TimerFcn',{@mycallback,handles}, 'Period',0.01,'ExecutionMode','FixedRate'); start(handles.timer);
a=get(handles.text8,'String'); set(handles.text28,'String',a); a=get(handles.text10,'String'); set(handles.text27,'String',a); a=get(handles.text13,'String'); set(handles.text25,'String',a); a=get(handles.text14,'String'); set(handles.text24,'String',a); a=get(handles.text15,'String'); set(handles.text22,'String',a); a=get(handles.text16,'String'); set(handles.text21,'String',a); global s fwrite(s,0); global s fclose(s); close; global s a=fread(s,6); set(handles.text8,'String',a(6)); set(handles.text10,'String',a(5)); set(handles.text13,'String',a(4)); set(handles.text14,'String',a(3)); set(handles.text15,'String',a(2)); set(handles.text16,'String',a(1)); - 调整时钟 调整分钟 调整秒钟 都添加callback:
global s a=str2num(get(handles.edit1,'String')); fwrite(s,a); a=get(handles.slider1,'value'); set(handles.edit1,'String',a);
C)操作说明 1. 开发板上的按钮修改时钟显示
2. 开发板上时钟显示
3. START前的开发板以及GUI界面,此时GUI界面的时钟无显示 4. START点击后GUI有了显示,与开发板显示一致
5. ADJUST点击后进入修改模式,开发板同步进入修改模式,同时GUI保留当前时间quondam time,随后分别调整秒钟 时钟 分钟,可以用编辑框,也可以用滑块. 6. 点击调整时钟后,显示调整结束。 7. 同时,也可以用单片机上的按钮调整时钟,同时GUI会实时返回设置值
时钟显示程序如下(并且加入了串口接收部分)
Main.c
#include <REGX52.H>
#define LED_SELECT P2
#define LED_DATA P0
#define KEY_PIN P3
//变量定义
unsigned char light[]={3,2,0,7,5,4,1,6};
static unsigned char count_1s=0 ;
typedef enum
{
NULL, KEY_ENTER, KEY_UP, KEY_DOWN
}TYPEDEF_KEY;
enum SHOW_STATE
{
SHOW_NORMAL, SHOW_SEC_ADJ, SHOW_MIN_ADJ,SHOW_HOUR_ADJ,
}ShowState;
unsigned char code LEDMAP[] = //共阴极显示代码
{
0xc0, 0xf9, 0xa4, 0xb0, 0x99,
0x92, 0x82, 0xf8, 0x80, 0x90,
0xff, //熄灭
};
enum
{
LED_GOOUT = 10,
};
unsigned char LEDBuffer[6]; //显示缓冲区
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char count;
bit Timer1sFlg;
//函数声明
void AT89S51Config(void);
void VariableInitial(void);
void ShowNormal(void);
void ShowSecondAdj(void);
void ShowMinuteAdj(void);
void ShowHourAdj(void);
void Delay(unsigned int t);
void Display(unsigned char * buf, unsigned char number); //动态显示
unsigned char GetKey(void);
/*——————————————————————————————主函数————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
main(void)
{
AT89S51Config(); //AT89S51配置
VariableInitial(); //变量初始化
while(1)
{
switch(ShowState)
{
case SHOW_NORMAL:
ShowNormal();
break;
case SHOW_SEC_ADJ:
ShowSecondAdj();
break;
case SHOW_MIN_ADJ:
ShowMinuteAdj();
break;
case SHOW_HOUR_ADJ:
ShowHourAdj();
break;
default:
break;
}
Display(LEDBuffer,6);
}
}
/*——————————————————————————————配置函数————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void AT89S51Config(void)
{ TMOD|=0x20; //串口配置————————————————————————————————————————
PCON&=0x7f;
TH1=TL1=0xfd;
TR1=1;
SCON=0x50; //串口配置————————————————————————————————————————
RCAP2H=0x0F;//T2定时器初值
RCAP2L=0x00;
ET2=1;//允许T2定时器中断
TR2=1;//启动T2定时器
EA=1;//开总中断
}
/*——————————————————————————————变量初始化————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void VariableInitial(void)
{
ShowState = 0;
Second = 0;
Minute = 0;
Hour = 0;
Timer1sFlg = 0;
count=0;
}
/*——————————————————————————————延时函数————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void Delay(unsigned int t)
{
for (t; t>0; t--) ;
}
/*——————————————————————————————正常显示界面————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void ShowNormal(void)
{ unsigned char i;
TYPEDEF_KEY key;
//1秒钟到,显示值更新
if(Timer1sFlg)
{
Timer1sFlg = 0;
Second++;
if(Second >= 60)
{
Second = 0;
Minute ++;
if(Minute >= 60)
{
Minute = 0;
Hour ++;
if(Hour >= 24)
{
Hour = 0;
}
}
}
for(i=0;i<6;i++)
{
if(TI==0) //——————————给串口送数据, 既给 matlab 送数据———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作对象是TI
TI=0 ;
}
}
}
LEDBuffer[0] = Second % 10; //秒个位送显示缓冲区
LEDBuffer[1] = Second / 10; //秒十位送显示缓冲区
LEDBuffer[2] = Minute % 10;
LEDBuffer[3] = Minute / 10;
LEDBuffer[4] = Hour % 10;
LEDBuffer[5] = Hour / 10;
key = GetKey();
if(key == KEY_ENTER)
{
ShowState = SHOW_SEC_ADJ;
}
if(RI==1)
{
RI=0;
TI=0;
ShowState = SHOW_SEC_ADJ;
}
}
/*——————————————————————————————秒钟调整————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void ShowSecondAdj(void)
{ unsigned char i;
TYPEDEF_KEY key;
LEDBuffer[0] = Second % 10; //秒个位送显示缓冲区
LEDBuffer[1] = Second / 10; //秒十位送显示缓冲区
LEDBuffer[2] = LED_GOOUT; //熄灭
LEDBuffer[3] = LED_GOOUT; //熄灭
LEDBuffer[4] = LED_GOOUT; //熄灭
LEDBuffer[5] = LED_GOOUT; //熄灭
Display(LEDBuffer,6);
key = GetKey();
switch(key)
{
case KEY_ENTER:
ShowState = SHOW_MIN_ADJ;
break;
case KEY_UP:
Second++;
if(60 == Second)
{
Second = 0;
}
break;
case KEY_DOWN:
if(0 == Second)
{
Second = 59;
}
else
{
Second--;
}
break;
}
for(i=0;i<6;i++)
{
LEDBuffer[2]=0;
LEDBuffer[3]=0;
LEDBuffer[4]=0;
LEDBuffer[5]=0;
if(TI==0) //——————————给串口送数据, 既给 matlab 送数据———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作对象是TI
TI=0 ;
}
}
if(RI==1)
{ RI=0;
Second=SBUF;
TI=0;
LEDBuffer[0] = Second % 10; //秒个位送显示缓冲区
LEDBuffer[1] = Second / 10; //秒十位送显示缓冲区
ShowState = SHOW_MIN_ADJ;
for(i=0;i<100;i++)
{Display(LEDBuffer,6);}
}
}
/*——————————————————————————————分钟调整————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void ShowMinuteAdj(void)
{
unsigned char i;
TYPEDEF_KEY key;
LEDBuffer[0] = LED_GOOUT; //熄灭
LEDBuffer[1] = LED_GOOUT; //熄灭
LEDBuffer[2] = Minute % 10; //分个位送显示缓冲区
LEDBuffer[3] = Minute / 10; //分十位送显示缓冲区
LEDBuffer[4] = LED_GOOUT; //熄灭
LEDBuffer[5] = LED_GOOUT; //熄灭
Display(LEDBuffer,6);
key = GetKey();
switch(key)
{
case KEY_ENTER:
ShowState = SHOW_HOUR_ADJ;
break;
case KEY_UP:
Minute++;
if(60 == Minute)
{
Minute = 0;
}
break;
case KEY_DOWN:
if(0 == Minute)
{
Minute = 59;
}
else
{
Minute--;
}
break;
}
for(i=0;i<6;i++)
{
LEDBuffer[0] = Second % 10; //秒个位送显示缓冲区
LEDBuffer[1] = Second / 10; //秒十位送显示缓冲区
LEDBuffer[4]=0;
LEDBuffer[5]=0;
if(TI==0) //——————————给串口送数据, 既给 matlab 送数据———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作对象是TI
TI=0 ;
}
}
if(RI==1)
{ RI=0;
Minute=SBUF;
LEDBuffer[2] = Minute % 10; //分个位送显示缓冲区
LEDBuffer[3] = Minute / 10; //分十位送显示缓冲区
TI=0;
Display(LEDBuffer,6);
ShowState = SHOW_HOUR_ADJ;
for(i=0;i<100;i++)
{Display(LEDBuffer,6);
}
}
}
/*——————————————————————————————时钟调整————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void ShowHourAdj(void)
{ unsigned char i;
TYPEDEF_KEY key;
LEDBuffer[0] = LED_GOOUT; //熄灭
LEDBuffer[1] = LED_GOOUT; //熄灭
LEDBuffer[2] = LED_GOOUT; //熄灭
LEDBuffer[3] = LED_GOOUT; //熄灭
LEDBuffer[4] = Hour % 10; //小时个位送显示缓冲区
LEDBuffer[5] = Hour / 10; //小时十位送显示缓冲区
Display(LEDBuffer,6);
key = GetKey();
switch(key)
{
case KEY_ENTER:
ShowState = SHOW_NORMAL;
break;
case KEY_UP:
Hour++;
if(24 == Hour)
{
Hour = 0;
}
break;
case KEY_DOWN:
if(0 == Hour)
{
Hour = 23;
}
else
{
Hour--;
}
break;
}
for(i=0;i<6;i++)
{
LEDBuffer[0] = Second % 10; //秒个位送显示缓冲区
LEDBuffer[1] = Second / 10; //秒十位送显示缓冲区
LEDBuffer[2] = Minute % 10;
LEDBuffer[3] = Minute / 10;
if(TI==0) //——————————给串口送数据, 既给 matlab 送数据———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作对象是TI
TI=0 ;
}
}
if(RI==1)
{ RI=0;
Hour=SBUF;
TI=0;
LEDBuffer[4] = Hour % 10; //小时个位送显示缓冲区
LEDBuffer[5] = Hour / 10; //小时十位送显示缓冲区
ShowState = SHOW_NORMAL;
for(i=0;i<100;i++)
{Display(LEDBuffer,6);;}
}
}
/*——————————————————————————————显示函数————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void Display(unsigned char * buf, unsigned char number)
{
unsigned char i;
for (i = 0; i < number; i++)
{
LED_SELECT = 0x00; //关所有LED (防止出现闪烁现象)
LED_DATA = LEDMAP[*(buf + i)]; //送数据
LED_SELECT = ~(1<<light[ i]); //显示某1位数码管,其余关闭
Delay(90); // 延时约1ms,参数与晶振大小有关
}
}
/*——————————————————————————————定时器五————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
Timer2_server(void) interrupt 5 //*
{
TF2=0;
count_1s++;
if(20 == count_1s)
{
Timer1sFlg = 1;
count_1s =0;
}
}
/*——————————————————————————————得到按键值————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
TYPEDEF_KEY GetKey(void)
{
TYPEDEF_KEY key = NULL;
if( ~KEY_PIN & 0x1c) //有键按下
{
Delay(1000); //去抖动
if(~KEY_PIN & 0X04)
{
key = KEY_ENTER;
}
else if(~KEY_PIN & 0X08)
{
key = KEY_UP;
}
else if(~KEY_PIN & 0X10)
{
key = KEY_DOWN;
}
else
{
return(NULL);
}
while(KEY_PIN != 0XFF) //等待键抬起
{
Delay(2);
}
return(key);
}
return(NULL);
}
完整的Word格式文档51黑下载地址:
Matlab的GUI单片机串口PC的通信.doc
(5.82 MB, 下载次数: 65)
|