我也是最近學(xué)習(xí)單片機(jī)和MATLAB的小白平時(shí)在看學(xué)習(xí)的時(shí)候 下載了一些有價(jià)值的參考文獻(xiàn)
概述 - 采用51單片機(jī),atmel的STC89C52RC芯片,主要用到的是七段數(shù)碼管用來做一個(gè)時(shí)鐘,程序編寫軟件為keil,燒錄軟件為STC-ISP 4.88,串口調(diào)試軟件用的是sscom42。
- 運(yùn)用Matlab的GUI工具編輯一個(gè)可視化界面,用以跟單片機(jī)進(jìn)行串口通信
實(shí)現(xiàn)功能- 運(yùn)用keil編寫時(shí)鐘程序,燒錄到單片機(jī)中,時(shí)鐘程序?qū)崿F(xiàn)的功能是實(shí)現(xiàn)時(shí)鐘的顯示,并且能用開發(fā)板上的三個(gè)按鈕進(jìn)行時(shí)鐘的修改,一個(gè)按鈕進(jìn)入修改模式,另兩個(gè)實(shí)現(xiàn)時(shí)間的增減。
- 編輯GUI界面,實(shí)現(xiàn)對(duì)單片機(jī)的控制,其中,GUI界面通過串口能不斷的采樣開發(fā)板上時(shí)鐘的數(shù)值,并在GUI界面上進(jìn)行顯示。同樣的,可以通過GUI界面實(shí)現(xiàn)對(duì)開發(fā)板上時(shí)鐘的修改。
具體實(shí)現(xiàn)
B) Matlab GUI界面的編輯 效果圖如下,操作說明:START點(diǎn)擊開始,采集單片機(jī)時(shí)鐘時(shí)間,ADJUST點(diǎn)擊進(jìn)入修改模式,同時(shí)單片機(jī)開發(fā)板亦會(huì)進(jìn)入修改模式,EXIT點(diǎn)擊關(guān)串口,退出界面,GET點(diǎn)擊獲取當(dāng)前值,另外一些輔助按鈕,滑塊按鈕都有各自功能,易于理解。 其中: 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)); - 調(diào)整時(shí)鐘 調(diào)整分鐘 調(diào)整秒鐘 都添加callback:
global s a=str2num(get(handles.edit1,'String')); fwrite(s,a); a=get(handles.slider1,'value'); set(handles.edit1,'String',a);
C)操作說明 1. 開發(fā)板上的按鈕修改時(shí)鐘顯示
2. 開發(fā)板上時(shí)鐘顯示
3. START前的開發(fā)板以及GUI界面,此時(shí)GUI界面的時(shí)鐘無顯示 4. START點(diǎn)擊后GUI有了顯示,與開發(fā)板顯示一致
5. ADJUST點(diǎn)擊后進(jìn)入修改模式,開發(fā)板同步進(jìn)入修改模式,同時(shí)GUI保留當(dāng)前時(shí)間quondam time,隨后分別調(diào)整秒鐘 時(shí)鐘 分鐘,可以用編輯框,也可以用滑塊. 6. 點(diǎn)擊調(diào)整時(shí)鐘后,顯示調(diào)整結(jié)束。 7. 同時(shí),也可以用單片機(jī)上的按鈕調(diào)整時(shí)鐘,同時(shí)GUI會(huì)實(shí)時(shí)返回設(shè)置值
時(shí)鐘顯示程序如下(并且加入了串口接收部分)
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]; //顯示緩沖區(qū)
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char count;
bit Timer1sFlg;
//函數(shù)聲明
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); //動(dòng)態(tài)顯示
unsigned char GetKey(void);
/*——————————————————————————————主函數(shù)————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
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);
}
}
/*——————————————————————————————配置函數(shù)————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void AT89S51Config(void)
{ TMOD|=0x20; //串口配置————————————————————————————————————————
PCON&=0x7f;
TH1=TL1=0xfd;
TR1=1;
SCON=0x50; //串口配置————————————————————————————————————————
RCAP2H=0x0F;//T2定時(shí)器初值
RCAP2L=0x00;
ET2=1;//允許T2定時(shí)器中斷
TR2=1;//啟動(dòng)T2定時(shí)器
EA=1;//開總中斷
}
/*——————————————————————————————變量初始化————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void VariableInitial(void)
{
ShowState = 0;
Second = 0;
Minute = 0;
Hour = 0;
Timer1sFlg = 0;
count=0;
}
/*——————————————————————————————延時(shí)函數(shù)————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
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) //——————————給串口送數(shù)據(jù), 既給 matlab 送數(shù)據(jù)———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作對(duì)象是TI
TI=0 ;
}
}
}
LEDBuffer[0] = Second % 10; //秒個(gè)位送顯示緩沖區(qū)
LEDBuffer[1] = Second / 10; //秒十位送顯示緩沖區(qū)
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;
}
}
/*——————————————————————————————秒鐘調(diào)整————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void ShowSecondAdj(void)
{ unsigned char i;
TYPEDEF_KEY key;
LEDBuffer[0] = Second % 10; //秒個(gè)位送顯示緩沖區(qū)
LEDBuffer[1] = Second / 10; //秒十位送顯示緩沖區(qū)
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) //——————————給串口送數(shù)據(jù), 既給 matlab 送數(shù)據(jù)———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作對(duì)象是TI
TI=0 ;
}
}
if(RI==1)
{ RI=0;
Second=SBUF;
TI=0;
LEDBuffer[0] = Second % 10; //秒個(gè)位送顯示緩沖區(qū)
LEDBuffer[1] = Second / 10; //秒十位送顯示緩沖區(qū)
ShowState = SHOW_MIN_ADJ;
for(i=0;i<100;i++)
{Display(LEDBuffer,6);}
}
}
/*——————————————————————————————分鐘調(diào)整————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void ShowMinuteAdj(void)
{
unsigned char i;
TYPEDEF_KEY key;
LEDBuffer[0] = LED_GOOUT; //熄滅
LEDBuffer[1] = LED_GOOUT; //熄滅
LEDBuffer[2] = Minute % 10; //分個(gè)位送顯示緩沖區(qū)
LEDBuffer[3] = Minute / 10; //分十位送顯示緩沖區(qū)
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; //秒個(gè)位送顯示緩沖區(qū)
LEDBuffer[1] = Second / 10; //秒十位送顯示緩沖區(qū)
LEDBuffer[4]=0;
LEDBuffer[5]=0;
if(TI==0) //——————————給串口送數(shù)據(jù), 既給 matlab 送數(shù)據(jù)———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作對(duì)象是TI
TI=0 ;
}
}
if(RI==1)
{ RI=0;
Minute=SBUF;
LEDBuffer[2] = Minute % 10; //分個(gè)位送顯示緩沖區(qū)
LEDBuffer[3] = Minute / 10; //分十位送顯示緩沖區(qū)
TI=0;
Display(LEDBuffer,6);
ShowState = SHOW_HOUR_ADJ;
for(i=0;i<100;i++)
{Display(LEDBuffer,6);
}
}
}
/*——————————————————————————————時(shí)鐘調(diào)整————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
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; //小時(shí)個(gè)位送顯示緩沖區(qū)
LEDBuffer[5] = Hour / 10; //小時(shí)十位送顯示緩沖區(qū)
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; //秒個(gè)位送顯示緩沖區(qū)
LEDBuffer[1] = Second / 10; //秒十位送顯示緩沖區(qū)
LEDBuffer[2] = Minute % 10;
LEDBuffer[3] = Minute / 10;
if(TI==0) //——————————給串口送數(shù)據(jù), 既給 matlab 送數(shù)據(jù)———————————————————————————
{ //———————————————————————————————————————————————————————
SBUF=LEDBuffer[5-i];
while (!TI ); //操作對(duì)象是TI
TI=0 ;
}
}
if(RI==1)
{ RI=0;
Hour=SBUF;
TI=0;
LEDBuffer[4] = Hour % 10; //小時(shí)個(gè)位送顯示緩沖區(qū)
LEDBuffer[5] = Hour / 10; //小時(shí)十位送顯示緩沖區(qū)
ShowState = SHOW_NORMAL;
for(i=0;i<100;i++)
{Display(LEDBuffer,6);;}
}
}
/*——————————————————————————————顯示函數(shù)————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
void Display(unsigned char * buf, unsigned char number)
{
unsigned char i;
for (i = 0; i < number; i++)
{
LED_SELECT = 0x00; //關(guān)所有LED (防止出現(xiàn)閃爍現(xiàn)象)
LED_DATA = LEDMAP[*(buf + i)]; //送數(shù)據(jù)
LED_SELECT = ~(1<<light[ i]); //顯示某1位數(shù)碼管,其余關(guān)閉
Delay(90); // 延時(shí)約1ms,參數(shù)與晶振大小有關(guān)
}
}
/*——————————————————————————————定時(shí)器五————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————*/
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); //去抖動(dòng)
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單片機(jī)串口PC的通信.doc
(5.82 MB, 下載次數(shù): 65)
2018-11-30 14:38 上傳
點(diǎn)擊文件名下載附件
|