我也是最近學習單片機和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)
2018-11-30 14:38 上傳
點擊文件名下載附件
|