msp430單片機(jī)課程設(shè)計(jì)-實(shí)時(shí)時(shí)鐘與鍵盤控制_第1頁(yè)
已閱讀1頁(yè),還剩7頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p>  MSP430單片機(jī)課程設(shè)計(jì)</p><p><b>  實(shí)時(shí)時(shí)鐘與鍵盤控制</b></p><p><b>  設(shè)計(jì)思路</b></p><p>  該算法的流程簡(jiǎn)圖如下:</p><p>  由于LCD無(wú)法完全顯示時(shí)間日期,故采用page翻頁(yè)的方式設(shè)計(jì),每頁(yè)6位顯示。設(shè)定pa

2、ge為奇數(shù)時(shí)表示當(dāng)前在時(shí)間頁(yè)面,page為偶數(shù)時(shí)表示當(dāng)前在日期頁(yè)面。在修改時(shí)間時(shí),采用的是輸入字符串進(jìn)行修改的方式。</p><p>  顯示當(dāng)前時(shí)間time=hour*10000+min*100+sec。</p><p>  在page為偶數(shù)時(shí),前兩位顯示小時(shí),中間兩位顯示分鐘,最低兩位顯示秒。</p><p>  2、顯示當(dāng)前日期date=year*10000+

3、mon*100+day,并能與時(shí)間切換。</p><p>  在page為奇數(shù)時(shí),前兩位顯示年份,中間兩位顯示月份,最低兩位顯示天。</p><p>  鍵盤上的up、down修改page的值,實(shí)現(xiàn)兩頁(yè)顯示的切換。</p><p>  能夠讀取鍵盤值進(jìn)行修改</p><p>  鍵盤通過(guò)中斷的方式讀取鍵值,每個(gè)鍵都有相應(yīng)的操作。具體的方案如下

4、:</p><p>  鍵值在0~F之間為對(duì)應(yīng)的十六進(jìn)制數(shù)。</p><p>  按下UP鍵,page加1。</p><p>  按下DOWN鍵,page加1,以上兩鍵能使page奇偶變化。</p><p>  按下L鍵,p加1,用于修改數(shù)據(jù)時(shí)修改位置的更改。</p><p>  按下R鍵,p減1,用于修改數(shù)據(jù)時(shí)修改位

5、置的更改。</p><p>  按下ESC鍵,使set置1,進(jìn)入修改模式,并在首位顯示E。</p><p>  按下START鍵,修改的數(shù)據(jù)生效,set置0。</p><p>  按下STOP鍵,取消修改,set置0,清除首位顯示。</p><p>  按下ENTER鍵,確認(rèn)當(dāng)前位的修改,注意是單個(gè)位的修改。</p><p

6、>  體現(xiàn)430系列單片機(jī)的超低功耗的特性。</p><p>  在中斷處理結(jié)束,以及循環(huán)結(jié)束,或者等待鍵盤按鍵時(shí),會(huì)進(jìn)入低功耗工作模式,同時(shí)編程時(shí)也盡量減少函數(shù)的調(diào)用,并將一些變量定義為寄存器變量,提高運(yùn)行效率。</p><p><b>  二、參數(shù)計(jì)算</b></p><p>  設(shè)計(jì)時(shí)鐘時(shí),應(yīng)能做到分秒的60進(jìn)1,時(shí)的24進(jìn)1 ,年

7、以兩位數(shù)表示滿100進(jìn)1 ,月滿12進(jìn)1;關(guān)于天的計(jì)數(shù)較為復(fù)雜:先根據(jù)年月判斷該月的最大天數(shù),實(shí)現(xiàn)進(jìn)位。</p><p><b>  三、編程步驟</b></p><p>  1、編寫時(shí)間顯示函數(shù),測(cè)試以確認(rèn)函數(shù)功能正常。</p><p>  2、設(shè)置初始值為04年2月28日。利用定時(shí)器A控制秒信號(hào)的自加,并用LCD顯示判斷算法是否正確。<

8、;/p><p>  3、已經(jīng)得到正確的秒信號(hào),根據(jù)算法實(shí)現(xiàn)時(shí)間的進(jìn)位。</p><p>  4、設(shè)計(jì)鍵盤,使鍵盤能正確輸入,讀取鍵值。</p><p>  5、設(shè)計(jì)翻頁(yè)功能,實(shí)現(xiàn)時(shí)間和日期的切換。</p><p>  6、設(shè)計(jì)時(shí)間的修改功能,以串輸入修改數(shù)據(jù)的形式進(jìn)行修改。</p><p>  7、程序存檔,測(cè)試檢驗(yàn)基本功

9、能。</p><p>  8、優(yōu)化程序算法,精簡(jiǎn)變量與函數(shù)調(diào)用,實(shí)現(xiàn)超低功耗,測(cè)試檢驗(yàn),提交最后成果。</p><p><b>  四、實(shí)踐感受</b></p><p><b>  五、源程序 </b></p><p>  //實(shí)時(shí)時(shí)鐘+鍵盤控制(串輸入修改方式)</p><p&

10、gt;  #include <msp430x44x.h></p><p>  #include <stdio.h></p><p>  //定義液晶顯示筆畫</p><p>  #define a (0x01)</p><p>  #define b (0x02)</p><p>  

11、#define c (0x10)</p><p>  #define d (0x08)</p><p>  #define e (0x40)</p><p>  #define f (0x20)</p><p>  #define g (0x04)</p><p>  //#define h (

12、0x80)</p><p><b>  //顯示字符的指針</b></p><p>  const unsigned char LCD_Tab[] = {</p><p>  a+b+c+d+e+f ,//顯示 "0",LCD_Tab[00]</p><p>  b+c

13、 ,//顯示 "1",LCD_Tab[01]</p><p>  a+b+d+e+g ,//顯示 "2",LCD_Tab[02]</p><p>  a+b+c+d+g ,//顯示 "3",LCD_Tab[03]</p><p>  b+c+f+g ,//顯示

14、 "4",LCD_Tab[04]</p><p>  a+c+d+f+g ,//顯示 "5",LCD_Tab[05]</p><p>  a+c+d+e+f+g ,//顯示 "6",LCD_Tab[06]</p><p>  a+b+c ,//顯示 "

15、7",LCD_Tab[07]</p><p>  a+b+c+d+e+f+g ,//顯示 "8",LCD_Tab[08]</p><p>  a+b+c+d+f+g ,//顯示 "9",LCD_Tab[09]</p><p>  a+b+c+e+f+g ,//顯示 "A"

16、,LCD_Tab[0A]</p><p>  c+d+e+f+g ,//顯示 "b",LCD_Tab[0B]</p><p>  a+d+e+f ,//顯示 "C",LCD_Tab[0C]</p><p>  b+c+d+e+g ,//顯示 "d",LCD_

17、Tab[0D]</p><p>  a+d+e+f+g ,//顯示 "E",LCD_Tab[0E]</p><p>  a+e+f+g ,//顯示 "F",LCD_Tab[0F]</p><p>  0 ,//顯示 " ",LCD_Tab[10]

18、</p><p><b>  };</b></p><p>  //定義時(shí)鐘 2004-02-28 23:59:53</p><p>  unsigned short int year=04, mon=2,day=28,hour=23,min=59,sec=53;</p><p>  unsigned short

19、int x,num,page=0;</p><p>  unsigned char p3; </p><p>  double dx; </p><p>  unsigned int set=0,p=0; //p表示當(dāng)前修改哪個(gè)位 </p><p>  unsigned int key=0,temp=10;</p>

20、<p>  long int div_val=1,div=1,data=0,dat=0; </p><p>  void mInitSTDIO()// 系統(tǒng)初始化</p><p><b>  {</b></p><p>  unsigned char i;</p><p><b> 

21、 // 主時(shí)鐘初始化</b></p><p>  WDTCTL = WDTPW + WDTHOLD;// stop watchdog timer</p><p>  FLL_CTL0 |= XCAP14PF;// Configure load caps</p><p>  // 定時(shí)器A初始化</p><p>  TAC

22、TL = TASSEL0 + TACLR;// ACLK, clear TAR</p><p>  TACCTL0 = CCIE;// CCR0 interrupt enabled</p><p>  TACCR0 = 32768;// 定時(shí)器常數(shù)(1秒)</p><p>  TACTL |= MC0;// Start Timer_a in

23、upmode</p><p>  // 定時(shí)器B初始化</p><p>  TBCTL = TASSEL0 + TACLR;// ACLK, clear TAR</p><p>  TBCCTL0 = CCIE;// CCR0 interrupt enabled</p><p>  TBCCR0 = 328;// 定時(shí)器常數(shù)

24、(1/100秒)</p><p>  TBCTL |= MC0;</p><p><b>  // P口初始化</b></p><p>  P1DIR = 0;// 設(shè)置P1.0~P1.7為輸入方式</p><p>  P1IFG = 0;// 清除P1的中斷標(biāo)志</p><p>

25、;  P1IE = 0xFF;// 設(shè)置 P1.0~P1.7 中斷</p><p>  P1IES = 0xFF;// 設(shè)置 P1.0~P1.7 下降沿中斷</p><p>  P2DIR |= 0xCF;// 設(shè)置P2.0~P2.3,P2.6,P2.7為輸出方式</p><p>  P3DIR = 0xFF;// 設(shè)置P3.0~

26、P3.7為輸出方式</p><p>  P4DIR |= 0xFC;// 設(shè)置P4.2~P4.7為輸出方式</p><p>  P5SEL = 0xFF;// P5用于LCD顯示</p><p>  P6SEL = 1;// P6.0用于ADC</p><p>  P3DIR |= 0xFE;// 設(shè)置P6.1

27、~P6.7為輸出方式(臨時(shí))</p><p>  // 初始化 LCD</p><p>  LCDCTL = LCDON + LCD4MUX + LCDP0;// 4-Mux LCD, segments S0-S15</p><p>  BTCTL = BTFRFQ1;</p><p>  for(i = 0; i < 8; i++)

28、 LCDMEM[i] = 0;// 清除顯示</p><p><b>  } </b></p><p>  //========================主程序====================================</p><p>  void main(void)</p><p><

29、;b>  {</b></p><p><b>  char x=0;</b></p><p>  mInitSTDIO();// 系統(tǒng)初始化</p><p>  _EINT();// 開啟中斷</p><p>  for(dx = 0;dx < 1000;dx++);</p&g

30、t;<p>  printf("Start\n");</p><p><b>  while(1)</b></p><p><b>  {</b></p><p>  while(page%2==0&&set==0) //判斷條件為偶數(shù)頁(yè),顯示時(shí)分秒<

31、;/p><p><b>  { </b></p><p>  LCDMEM[0] = LCD_Tab[sec % 10];</p><p>  LCDMEM[1] = LCD_Tab[sec / 10];</p><p>  LCDMEM[2] = LCD_Tab[min % 10];</p><p&

32、gt;  LCDMEM[3] = LCD_Tab[min / 10];</p><p>  LCDMEM[4] = LCD_Tab[hour % 10];</p><p>  LCDMEM[5] = LCD_Tab[hour / 10]; </p><p>  // _BIS_SR(LPM3_bits);// Enter LPM3&l

33、t;/p><p>  _BIS_SR(LPM0_bits);// Enter LPM0</p><p><b>  } </b></p><p>  while(page%2==1&&set==0) //判斷條件為奇數(shù)頁(yè),顯示年月日</p><p><b>  { &

34、lt;/b></p><p>  LCDMEM[0] = LCD_Tab[day % 10];</p><p>  LCDMEM[1] = LCD_Tab[day / 10];</p><p>  LCDMEM[2] = LCD_Tab[mon % 10];</p><p>  LCDMEM[3] = LCD_Tab[mon / 10]

35、;</p><p>  LCDMEM[4] = LCD_Tab[year % 10];</p><p>  LCDMEM[5] = LCD_Tab[year / 10];</p><p>  _BIS_SR(LPM3_bits);// Enter LPM3</p><p>  _BIS_SR(LPM0_bits);// Enter

36、LPM0</p><p>  } </p><p>  while(set==1) //set=1時(shí),設(shè)置模式</p><p><b>  { </b></p><p>  LCDMEM[0] = LCD_Tab[temp]; //最低位閃爍<

37、/p><p>  for(dx = 0;dx < 1000;dx++); </p><p>  LCDMEM[0] = LCD_Tab[16]; //空白,不顯示</p><p>  for(dx = 0;dx < 2000;dx++);</p><p>  //--------------------------

38、-----字符串輸入------------------------------------------ </p><p>  while(key<0x0a) //按鍵為0~9,可進(jìn)行修改</p><p>  { </p><p>  data=data*10+key; dat=data;</

39、p><p><b>  x=p;</b></p><p><b>  do</b></p><p>  { LCDMEM[x--] = LCD_Tab[dat / div];</p><p>  dat %= div;</p><p>  div /= 10;</p&g

40、t;<p>  } while(div);</p><p>  div_val=div_val*10; div=div_val; </p><p>  p++; p %=6; temp=key; key=0x0a; </p><p>  } //data為輸入的6位數(shù), start 鍵確認(rèn)修改</p

41、><p>  } // 設(shè)置模式 end~~~ </p><p>  // 修改建議:嘗試按位修改時(shí)間</p><p>  } //while(1) </p><p>  } //=======main結(jié)束=========</p><p>  // -----------------------------

42、-Timer A0 中斷服務(wù)程序--------------------------------------------</p><p>  #pragma vector=TIMERA0_VECTOR</p><p>  __interrupt void Timer_A0(void)</p><p><b>  { </b></p&g

43、t;<p><b>  p3 <<= 1;</b></p><p>  if(p3 == 0) p3 = 1;</p><p>  P3OUT = p3; // LED流水燈</p><p>  switch(mon) //判斷每個(gè)月的天數(shù),保存為num</p&

44、gt;<p><b>  {</b></p><p>  case 1: num=31;break;</p><p>  case 2: if(year%4==0)num=29;</p><p>  else num=28;break;</p><p>  case 3:num=31;break;</

45、p><p>  case 4:num=30;break;</p><p>  case 5:num=31;break;</p><p>  case 6:num=30;break;</p><p>  case 7:num=31;break;</p><p>  case 8:num=31;break;</p>

46、<p>  case 9:num=30;break;</p><p>  case 10:num=31;break;</p><p>  case 11:num=30;break;</p><p>  case 12:num=31;break;</p><p><b>  }</b></p>

47、<p>  if(sec>=59) //實(shí)現(xiàn)時(shí)間的進(jìn)位 </p><p><b>  {sec=0;</b></p><p>  if(min>=59)</p><p><b>  {min=0;</b></p><p>  if(hour

48、>=23)</p><p><b>  {hour=0;</b></p><p>  if(day>=num)</p><p><b>  {day=1;</b></p><p>  if(mon>=112) </p><p>  {mon=1;year

49、++;year%=100;}</p><p>  else mon++; </p><p><b>  }</b></p><p>  else day++;</p><p><b>  }</b></p><p>  else hour++; </p>&

50、lt;p><b>  } </b></p><p>  else min++;</p><p><b>  }</b></p><p>  else sec++; </p><p>  // _BIC_SR_IRQ(LPM3_bits);// Clear LPM3 bits fro

51、m 0(SR)</p><p>  _BIC_SR_IRQ(LPM0_bits);// Clear LPM0, SET BREAKPOINT HERE</p><p>  //修改建議:判斷部分移入main函數(shù)</p><p><b>  }</b></p><p>  // Timer B0 中斷服務(wù)程序</

52、p><p>  #pragma vector=TIMERB0_VECTOR</p><p>  __interrupt void Timer_B0(void)</p><p><b>  {</b></p><p>  x <<= 1;// 鍵盤掃描</p><p>  if((x

53、 & 0x07) == 0) x = 1;</p><p>  P2OUT = (~x) & 0x07;</p><p>  // _BIC_SR_IRQ(LPM3_bits);// Clear LPM3 bits from 0(SR)</p><p>  _BIC_SR_IRQ(LPM0_bits);// Clear LPM0, SET B

54、REAKPOINT HERE</p><p><b>  }</b></p><p>  // ~~~~~~~~~~~~~~~~~~ P1 中斷服務(wù)程序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p><p>  #pragma vector=PORT1_VECTOR</p><p>

55、  __interrupt void P1INT(void)</p><p>  { register int scan=0,pressed;//寄存器變量存儲(chǔ)按鍵中間值 </p><p><b>  do</b></p><p>  { scan = ~P2IN;</p><p>  scan &am

56、p;= 0x0007;</p><p>  scan <<= 8;</p><p>  scan |= P1IFG; //掃描得到scan</p><p>  for(dx = 0;dx < 800;dx++); //延時(shí)數(shù)值自己調(diào)整</p><p>  pressed = ~P2IN;</p>

57、<p>  pressed &= 0x0007;</p><p>  pressed <<= 8;</p><p>  pressed |= P1IFG; //延時(shí)后得到pressed </p><p>  }while(scan!=pressed) ; //可以確定鍵值,下一步操作</p>&l

58、t;p>  switch(scan)</p><p><b>  {</b></p><p>  case 0x0101: key = 0; break;// "0"鍵鍵值</p><p>  case 0x0102: key = 1; break;// "1"鍵鍵值</p>

59、<p>  case 0x0104: key = 2; break;// "2"鍵鍵值</p><p>  case 0x0108: key = 3; break;// "3"鍵鍵值</p><p>  case 0x0110: key = 4; break;// "4"鍵鍵值</p><

60、p>  case 0x0120: key = 5; break;// "5"鍵鍵值</p><p>  case 0x0140: key = 6; break;// "6"鍵鍵值</p><p>  case 0x0180: key = 7; break;// "7"鍵鍵值</p><p>

61、;  case 0x0201: key = 8; break;// "8"鍵鍵值</p><p>  case 0x0202: key = 9; break;// "9"鍵鍵值</p><p>  case 0x0204: key = 0x0a; break;// "A"鍵鍵值</p><p> 

62、 case 0x0208: key = 0x0b; break;// "B"鍵鍵值</p><p>  case 0x0210: key = 0x0c; break;// "C"鍵鍵值</p><p>  case 0x0220: key = 0x0d; break;// "D"鍵鍵值</p><p>

63、;  case 0x0240: key = 0x0e; break;// "E"鍵鍵值</p><p>  case 0x0280: key = 0x0f; break;// "F"鍵鍵值</p><p>  case 0x0401: key = 0x10; page++; break;// "UP"鍵鍵值</p>

64、;<p>  case 0x0402: key = 0x11; page++; break;// "DN"鍵鍵值</p><p>  case 0x0404: key = 0x12; p++;break; // "L"鍵鍵值</p><p>  case 0x0408: key = 0x13; p--;break; /

65、/ "R"鍵鍵值</p><p>  case 0x0410: key = 0x14; // "STRAT"鍵鍵值</p><p>  if(page%2==0)</p><p>  { hour=data/10000;</p><p>  min=(data%10000)

66、/100;</p><p>  sec=data%100;}</p><p>  if(page%2==1)</p><p>  { year=data/10000;</p><p>  mon=(data%10000)/100;</p><p>  day=data%100;}</p><p&g

67、t;  set=0; //start確認(rèn)修改</p><p>  LCDMEM[6] = LCD_Tab[16];</p><p>  break; </p><p>  case 0x0420: key = 0x15; // "STOP"鍵鍵值</p>&

68、lt;p>  set=0; // 按stop取消修改</p><p>  LCDMEM[6] = LCD_Tab[16];</p><p><b>  break;</b></p><p>  case 0x0440: key = 0x16; // "ESC"鍵鍵值<

69、;/p><p>  set=1;p=0;data=0;dat=0;div=0;div_val=0; //記得初始化</p><p>  LCDMEM[6] = LCD_Tab[14]; //首位顯示E表示進(jìn)入手動(dòng)設(shè)置</p><p>  LCDMEM[p] = LCD_Tab[10]; //修改處顯示A </p><p><b

70、>  break;</b></p><p>  case 0x0480: key = 0x17; break; // "ENTER"鍵鍵值</p><p>  default: LCDMEM[6] = 0; break; // 其它情況</p><p>  } </p&g

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論