Friday, August 8, 2014

Bài 4.(Học MSP430 qua ví dụ) Đồng hồ số - Tạo menu,viết các hàm chức năng

1.Sử dụng ADC
1.1.Khởi tạo,đọc ADC

Thông thường chúng ta sử dụng GPIO cho chức năng nút bấm,tuy nhiên trong project này chúng ta sử dụng 1 ADC để nhận nhiều nút bấm thông qua phân áp khác nhau chu từng nút.

Trước hết cần download bộ thư viện ADC.h tại đây .Các bạn nên đọc lại Tutorial ADC10 của MSP430.Bắt đầu là khởi tạo Module ADC10.Chúng ta sẽ dùng điện áp tham chiếu VCC, nên khai báo hàm ADC10_Init(VCC); .Vì trong mạch không có điện trở treo trên chân P1.4 và P1.5 nên cần cài đặt điện trở nội kéo lên trên các chân này.






Viết tiếp vào hàm Initial() để khởi tạo module ADC10.
//Khoi tao ADC
ADC10_Init(VCC);

// Chinh dien tro keo len tren chan P1.4 P1.5 (Nut bam)
P1DIR &=~(BIT3+BIT4+BIT5);                   //Chon nhap du lieu
P1OUT |= (BIT4+BIT5);      
P1REN |= (BIT4+BIT5);                   //Cho dien tro keo len
P1OUT &= ~BIT3;    //Doc ADC cua quang tro khong can dien tro keo le
P1REN &= ~BIT3;
Có thể sửa lại hàm main như sau để xem thông số các ADC khi bấm nút.Đọc 2 ADC 4 và 5 tại chân P1.4 và P1.5 .

void main(void)
{
            unsigned int abc=0;
            Initial();
            while(1)
            {
                        Hien_thi_gio();
                        abc = ADC10_Read_Channel(4);
                        //Khoi tao ngat ngoai
                        #ifdef USE_UART
                        UART_Write_Char(10);                  //Ky tu xuong dong
                        sprintf(buff,"ADC4:%d",abc);
                        UART_Write_String(buff);
                        #endif

                        abc = ADC10_Read_Channel(5);
                        //Khoi tao ngat ngoai
                        #ifdef USE_UART
                        sprintf(buff,"  ADC5:%d",abc);
                        UART_Write_String(buff);
                        UART_Write_Char(10);                  //Ky tu xuong dong
                        #endif

                        _delay_cycles(500000);
            }
}
Kết quả hiển thị trên hercules dạng như sau. Chú ý là vì dùng ADC nên nếu muốn nhận nhiều nút cùng lúc thì bạn phải viết thêm các phép if … else để bắt các giá trị ADC trung gian khi 2 nút được nhấn.

ADC4:1020  ADC5:519       //Nhấn nút trên cùng
ADC4:1019  ADC5:0           //Nhấn nút thứ 2
ADC4:520  ADC5:1021       //Nhấn nút thứ 3
ADC4:2  ADC5:1021           //Nhấn nút thứ 4
ADC4:1021  ADC5:1022     //Không có nút nào được nhấn

1.2. Đọc bàn phím

Từ dữ liệu thu được như trên chúng ta sẽ viết hàm nhận phím bấm bằng cách đọc ADC.Các bạn nên tạo một thư viện Switch.h riêng trong thư mục Library.Trong thư viện Switch chúng ta khai báo biến toàn cục và 2 macro sbi và cbi.
#define sbi(REG,BIT) REG |= (1<<BIT) // set BIT trong thanh ghi REG
#define cbi(REG,BIT) REG &= ~(1<<BIT)// clear BIT trong thanh ghi REG

unsigned char press=0;//trang thai phim bam
unsigned char press_quakhu=0;
unsigned int SW1=0,SW2=0;
Viết hàm SWITCH_CheckKey() .Đây là hàm kiểm tra tại thời điểm gọi hàm có nút nào đang được nhấn không.Đầu tiên là đọc giá trị ADC trên 2 chân P1.4 và P1.5 .Khi không có nút nhấn thì giá trị các ADC trong khoảng lớn hơn 1000.Khi nhấn nút trên cùng,giá trị SW1 giảm xuống trong khoảng 510 ->530 ( Chúng ta đo được khoảng 520).Nếu SW1 trong khoảng 510->530 thì là nút 1 được nhấn,kéo bit0 của press lên 1,nếu không thì giữ mức 0,nếu SW1<10 thì tức là nút 2 được nhấn,kéo bit 1 của press lên 1.Tương tự vậy với các nút khác.

void SWITCH_CheckKey()
{
            press=0;
            SW1=(int)ADC10_Read_Channel(5);
            SW2=(int)ADC10_Read_Channel(4);

            if(SW1<530)  // neu co bat ky nut nao o PORT duoc bam
            {          
                        if(SW1>510){sbi(press,0);cbi(press,1);}                //SW1
                        else if(SW1<10){sbi(press,1);cbi(press,0);}            //SW2
            }
            if(SW2<530)
            {
                        if(SW2>510){sbi(press,2);cbi(press,3);}                //SW3
                        else if(SW2<10) {sbi(press,3);cbi(press,2);}           //SW4
            }
}
Kết quả trên Hercules:

press:0                       //Không có nút nào được nhấn
press:1                       //Nút 1 được nhấn
press:2                       //Nút 2 được nhấn
press:4                       //Nút 3 được nhấn
press:8                       //Nút 4 được nhấn
Chúng ta viết tiếp hàm SWITCH_Key() . Đây là hàm nhận cạnh xuống của nút nhấn,tức là chỉ báo nút được nhấn đúng 1 lần khi nút từ trạng thái không nhấn -> nhấn . Khi nút đang được nhấn thì giá trị press vẫn bằng 0 . Hàm này dùng trong menu để tránh tình trạng dính nút . Cụ thể là biến press_quakhu sẽ lưu giá trị nút nhấn trong lần kiểm tra nút bấm trước đó.Khi chưa nhấn gì,cả press và press_quakhu đều bằng 0. Khi nhấn 1 nút,press kháo press_quakhu ,nên giá trị press được gán bằng sự khác nhau giữa press và press_quakhu & press ,tức là chỉ nút nào được nhấn hiện tại mới được kéo lên 1 trong press.press_quakhu = press nên trong thời gian nhấn sau đó press=0.Cuối cùng khi nhả nút ra,có sự khác nhau giữa press và press_quakhu,nhưng bit khác nhau của press =0 nên kết quả cuối cùng press=0.
//Ham quet phim chi nhan tung lan 1 nhung cpu ko chay trong vong while
void SWITCH_Key()
{
            unsigned char temp;
            SWITCH_CheckKey();
            temp=press;
            if(press == press_quakhu)press=0;
            else
            {
                        press =(press^press_quakhu)&press;
                        press_quakhu=temp;
            }
}

2.Tạo menu chương trình

Cấu trúc menu như sau:

  • Nhấn nút 2 để xem ngày
  • Nhấn nút 3 để xem nhiệt độ
  •  Giữ nút 1 để vào cài đặt.Trong cài đặt, chức năng các phím như sau .Phím 1- Enter ; Phím 2 – Lên ; Phím 3 – Xuống ; Phím 4 – Thoát.Trong setup sẽ chia ra các mục từ 1 đến 5.Enter ở mục nào thì vào cài đặt của mục đó.Muốn thoát thì nhấn phím 4 .
  • Nếu trong menu mà trong 1 phút không có nút nhấn nào thì thoát .

2.1. Tạo timer định thời gian

Bạn tưởng tượng thế này,sau khi nhấn nút 2 để hiển thị ngày,sau khi nhả ra,chúng ta muốn hiển thị thêm 2s nữa rồi hiển thị năm rồi mới thoát về hiển thị giờ.Và trong rất nhiều trường hợp khác nữa.Để giải quyết việc này,chúng ta có thể tạo timer định thời 1 khoảng thời gian (0.5s chẳng hạn).Tạo Cờ Enable_TimerA0 và biến Dem_TimerA0 .Trong ngắt TimerA0 , khi cờ Enable_TimerA0=1 thì mỗi lần ngắt Timer thì tăng biến Dem_TimerA0 lên.Khi muốn định 1 khoảng thời gian nào đó chỉ cần bật cờ Enabled_TimerA0 và chờ đến khi Dem_TimerA0 bằng thời gian định trước thì thực hiện lệnh cần làm.
//Co su dung Timer
volatile unsigned int Dem_timerA0=0;
volatile unsigned char Enable_timerA0=0;

Viết tiếp hàm định thời Timer 0.5s vào hàm Initial().Luôn để lệnh cho phép ngắt ở dưới cùng của hàm khởi tạo,nhưng phải đảm bảo nằm trên của các lệnh có dùng đến ngắt để tránh gây lỗi chương trình.
            // Khoi tao Ngat timer
            // Tao timer 0,5 s
            TACCR0 = 62499;
            TACCTL0 = CCIE;
            TACTL = TASSEL_2 + MC_1 + ID0 + ID1;             // SMCLK/8, Up mode
            __bis_SR_register(GIE);                             //Cho phep ngat hoat dong
Khai báo ngắt TimerA0.
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
            if((Dem_timerA0<65535)&&(Enable_timerA0==1))Dem_timerA0++;
}

2.2.
Tạo menu

Chúng ta sẽ viết chương trình cho 2 nút bấm 2 và 3 trước vì nó đơn giản hơn.
while(1)
            {
                        Hien_thi_gio();
                        if(counter<20)counter++;
                        else counter=0;

                        if(counter==0)
                        {
                                    SWITCH_CheckKey();
                                    if(press==0x02)
                                    {
#ifdef USE_UART
                                                UART_Write_Char(10);                 //Ki tu xuong dong
                                                UART_Write_String("Dang nhan nut 1");
#endif
                                    }
                                    if(press==0x04)
                                    {
#ifdef USE_UART
                                                UART_Write_Char(10);                  //Ki tu xuong dong
                                                UART_Write_String("Dang nhan nut 2");
#endif
                                    }

                                    // Neu nut 1 khong duoc nhan thi reset timer ,
                                    // va khong cho timer hoat dong
                                    if(press!=0x01)
                                    {
                                                Enable_timerA0=0;  // Ngung dem timer
                                                Dem_timerA0=0;                  // Reset bien Dem_timerA0
                                    }
                                    // Neu nut 1 duoc nhan,cho bien Dem_timerA0 chay
                                    else if((press==0x01)&&(Enable_timerA0==0))
                                    {
                                                Enable_timerA0=1;
                                                Dem_timerA0=0;
#ifdef USE_UART
                                                UART_Write_Char(10);                  //Ki tu xuong dong
                                                UART_Write_String("Dang nhan enter");
#endif
                                    }
// Sau 1,5s ke tu luc giu phim 1 thi nhay chuong trình vao Menu Setup
                                    if((Dem_timerA0>=3)&&(Enable_timerA0==1))
                                    {
                                                press=0;
                                                press_quakhu=1;
                                                Dem_timerA0=0;
                                                Enable_timerA0=1;
#ifdef USE_UART
                                                UART_Write_Char(10);                  //Ki tu xuong dong
                                                UART_Write_String("Vao Menu setup");
#endif
                                                PHUT_ON;

                                                //Menu setup
                                                while(1)
                                                {
//Chuong trinh trong menu se duoc viet vao day
                                                            Enable_timerA0=1;             
//Cho phep chuc nang thoat khi khong nhan nut nao sau 1 phut
                                                            Write_74HC595_8bit(soled[setup]);
                                                            _delay_us(delay_led_on);
                                                            Write_74HC595_8bit(0xFF);
_delay_us(delay_led_off);
}
#ifdef USE_UART
                                                UART_Write_Char(10);      //Ki tu xuong dong
                                                UART_Write_String("Thoat menu");
#endif
}
}
}
      
Thay hàm SWITCH_Key() bằng hàm SWITCH_CheckKey() vì bây giờ chúng ta cần tính thời gian nhấn nút của phím 1.sau này chúng ta sẽ thêm các hàm chức năng vào trong lệnh if,tạm thời bây giờ thì chỉ hiển thị kết quả qua UART.Nhấn nút 2 và 3 sẽ có thông báo qua UART.Nhấn nút 1 sẽ có thông báo ,sau 1,5s (3 lần ngắt timerA0) thì chương trình sẽ vào menu setup.Vòng while(1) dưới cùng sẽ hiển thị giá trị kênh trong menu đang được trỏ tới, ví dụ 1 là chỉnh giờ,khi nhấn enter thì sẽ nhảy vào chương trình chỉnh giờ.

Chúng ta tạo thêm 1 biến “ unsigned char setup “để giữ giá trị kênh trong menu hiện tại.Tiếp tục code trong vòng while(1).
//Menu setup
while(1)
{
            Enable_timerA0=1;             
//Cho phep chuc nang thoat khi khong nhan nut nao sau 1 phut
            Write_74HC595_8bit(soled[setup]);
            _delay_us(delay_led_on);
            Write_74HC595_8bit(0xFF);
            _delay_us(delay_led_off);
//Hien thi gia tri bien setup

            SWITCH_Key();
            if(press==2)
            {if(setup<5)setup++;Dem_timerA0=0;}
            if(press==4)
            {if(setup>1)setup--;Dem_timerA0=0;}
            if(press==8)
            {
                        Enable_timerA0=0;
                        Dem_timerA0=0;
                        break;
            }
            if(press==1)               //Nhan ENTER
{
                        if(setup==1);//Chinh_gio();
                        else if(setup==2);//Chinh_ngay();
                        else if(setup==3);//Chinh_do_tuong_phan();
                        else if(setup==4);//Hen_gio();
            else if(setup==5);//Dong_ho_dem_nguoc();
            }
            //Neu qua 1 phut ma khong co nut nao nhan thi thoat
            if(Dem_timerA0>=120)
            {
                        setup=1;
                        press=0;
                        press_quakhu=0;
                        Enable_timerA0=0;
                        Dem_timerA0=0;
                        Doc_thoi_gian();
                        break;
            }
}

Nếu nhấn nút 1 thì sẽ chuyển vào kênh thứ “setup”,trong này chúng ta gọi các hàm chức năng ứng với từng kênh trong setup ra.Đoạn hàm if cuối cùng để thoát khỏi Menu khi không nhấn nút gì trong 1 phút,vì vậy mỗi khi nhấn 1 nút gì,chúng ta phải đưa biến Dem_timerA0 về 0 để reset quá trình tự thoát.

Như vậy là các bạn đã viết xong menu của chương trình rồi.Trong hàm if(press==1) {…} các bạn có thể dùng if … else hoặc switch đều được.

2.3. Tạo hàm xem ngày

Bây giờ,khi muốn hiển thị ngày khi nhấn nút 2,ta tạo hàm Hien_thi_ngay() và gọi hàm này ở đoạn lệnh quét phím như phần menu ở trên.

Chúng ta sẽ không đọc bàn phím liên tục mà cứ quét được khoảng 20 lần quét led thì mới đọc bàn phím 1 lần.Vì thời gian đọc ADC khá lâu và nếu đọc liên tục thì sẽ ảnh hưởng đến hiển thị.Dùng biến counter để làm việc này.

Hàm Hien_thi_ngay() như sau.
void Hien_thi_ngay()
{
            Enable_timerA0=1;  // Cho phep dem timer
            Dem_timerA0=0;                  // Reset bien dem timer ve 0
            Doc_thoi_gian();
            while(press==0x02)
            {
                        if(Dem_timerA0==0)            // 2.5s mois quet ban phim 1 lan
                        {
#ifdef USE_UART
                                    UART_Write_Char(10);                  //Ky tu xuong dong
                                    sprintf(buff,"Date:%d:%d:20%d",ngay,thang,nam);
                                    UART_Write_String(buff);
#endif
                                    Dem_timerA0++;
                                    SWITCH_CheckKey();
                        }
                        if(Dem_timerA0>=5)Dem_timerA0=0;      //Sau moi 2.5s thi quet lai nut bam

                        //Doan nay hien thi ngay
                        GIO10_ON;
                        Write_74HC595_8bit(soled[ngay10BCD]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        GIO_ON;
                        Write_74HC595_8bit(soled[ngayBCD]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        PHUT10_ON;
                        Write_74HC595_8bit(soled[thang10BCD]&~BIT5);//hien thi dau cham
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        PHUT_ON;
                        Write_74HC595_8bit(soled[thangBCD]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);
            }

            //Sau 2.5s ke tu luc nha nut bam ra -> doan nay hien thi ngay
            Dem_timerA0=0;
            //Hien thi nam
            while(Dem_timerA0<4)
            {
                        GIO10_ON;
                        Write_74HC595_8bit(soled[2]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        GIO_ON;
                        Write_74HC595_8bit(soled[0]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        PHUT10_ON;
                        Write_74HC595_8bit(soled[nam/10]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        PHUT_ON;
                        Write_74HC595_8bit(soled[nam%10]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);
            }
            Enable_timerA0=0;
            Dem_timerA0=0;
}

2.4. Tạo hàm xem nhiệt độ

Tương tự chúng ta viết hàm đọc nhiệt độ khi nhấn nút 3,gọi hàm này trong menu chương trình.Chúng ta đọc cảm biến nhiệt độ trong MSP430.Thực chất cảm biến này là một trở nhiệt được mắc nối tiếp với 1 điện trở thường.Đọc giá trị cảm biến nhiệt độ ở cổng 10 của ADC.Các bạn có thể đọc lại bài ADC trong loạt bài MSP430 Tutorial để hiểu chi tiết.

Một điểm cần chú ý là cảm biến nhiệt độ trong MSP430 có sai số tĩnh khá lớn và mỗi chip vi điều khiển có sai số riêng cần phải căn chỉnh bằng tay.Vì vậy công thức tính nhiệt độ (biến Temperature ) cần chỉnh lại cho phù hợp.

Nhiệt độ sẽ được cập nhật trong ngắt nhận của BQ32000,tức là mỗi giây đo nhiệt độ 1 lần,cho qua 1 bộ lọc cửa sổ ( Temp[0] -> Temp[7]) để giảm nhiễu .Các bạn có thể làm nhiều cách khác tùy ý,miễn sao phải đo nhiệt độ thường xuyên và cách đều nhau.Đoạn code này đặt trong ngắt của chân P1.0 ,đặt ngay trước lệnh :
 P1IFG &=~BIT0;
[code]
if(giay%2==0)
                        {
                                    Temp[7]=Temp[6];
                                    Temp[6]=Temp[5];
                                    Temp[5]=Temp[4];
                                    Temp[4]=Temp[3];
                                    Temp[3]=Temp[2];
                                    Temp[2]=Temp[1];
                                    Temp[1]=Temp[0];
                                    Temp[0] = ADC10_Read_Channel(10);
                        }[/code]

Các bạn nhớ để ý xem đã khai báo ngắt cho ADC chưa.

Khi nhấn nút 3,hàm nhiệt độ sẽ được gọi,thêm đoạn code này trong timer để nhận nút 3 .
  if(counter==0)
                        {
                                    SWITCH_Key();
                                    if(press==0x02)Hien_thi_ngay();  // Nhan nut 2
                                    if(press==0x04)Doc_nhiet_do();   // Nhan nut 3
                        }

Viết hàm đọc thời gian.
void Doc_nhiet_do()
{
            // Luu y gia tri Temperature duoc tinh dua tren trung binh
            // cua 8 lan do cuoi cung,vi vay can doan code cap nhat gia tri
            // nhiet do thuong xuyen trong ngat 1s nhan tu BQ32000
            long Temperature=0;
            Enable_timerA0=1;              //Cho phep dem timer
            Dem_timerA0=0;                              //Reset timer ve 0
            while(press==0x04)             //Neu giu nut 3 thi van hien thi nhiet do
            //Nha ra thi 2.5s sau se thoat
            {
                        if(Dem_timerA0==0)            //Tuong tu tren, cu 2.5s moi quet ban phim 1 lan
                        {
                                    Temperature= (Temp[7]+Temp[6]+Temp[5]+Temp[4]+
                                                       Temp[3]+Temp[2]+Temp[1]+Temp[0])>>3;
                                    // Tao bo tre,lay trung binh gia tri 8 lan do cuoi cung , de chong nhieu
                                    Temperature = (Temperature*4437/128-10180)/25;
                                    // Tinh theo cong thuc mau trong datasheet,gia tri offset cua cam bien
                                    // Co the chinh bang TLV
#ifdef USE_UART
                                    UART_Write_Char(10);                  //Ky tu xuong dong
                                    sprintf(buff,"Temp:%d *C",Temperature);
                                    UART_Write_String(buff);
#endif
                                    SWITCH_CheckKey();
                                    Dem_timerA0++;
                        }
                        if(Dem_timerA0>=5)Dem_timerA0=0;

                        // Neu nhiet do duong thi hien nhiet do o ky tu thu 2 va 3,
                        // ky tu *C o ben phai
                        if(Temperature>0)
                        {
                                    GIO_ON;
                                    Write_74HC595_8bit(soled[Temperature/10]);
                                    _delay_us(delay_led_on);
                                    Write_74HC595_8bit(0xFF);
                                    _delay_us(delay_led_off);

                                    PHUT10_ON;
                                    Write_74HC595_8bit(soled[Temperature%10]);
                        }
                        // Neu nhiet do am thi hien dau tru o ben trai
                        else
                        {
                                    GIO10_ON;
                                    Write_74HC595_8bit(soled[11]);   // Dau -
                                    _delay_us(delay_led_on);
                                    Write_74HC595_8bit(0xFF);
                                    _delay_us(delay_led_off);

                                    GIO_ON;
                                    Write_74HC595_8bit(soled[-Temperature/10]);
                                    _delay_us(delay_led_on);
                                    Write_74HC595_8bit(0xFF);
                                    _delay_us(delay_led_off);

                                    PHUT10_ON;
                                    Write_74HC595_8bit(soled[-Temperature%10]);
                        }

                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        //Hien *C
                        PHUT_ON;
                        Write_74HC595_8bit(soled[12]); //*C
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);
            }
            Enable_timerA0=0;
            Dem_timerA0=0;
}

2.5. Viết hàm chỉnh giờ trong Menu Setup

Ở đây mình sẽ không giải thích chi tiết thuật toán nữa vì nó không khác nhiều với các hàm bên trên.
void Chinh_gio()
{
            unsigned char temp=0;     //Phan chuc nang phim 2 va 3 chinh gio va phut
            while(1)
            {
                        GIO10_ON;
                        P2OUT&=~BIT7;      //Bat dau hai cham
                        if((temp!=0)||(giay%2==0))Write_74HC595_8bit(soled[gio10BCD]);
                        _delay_us(delay_led_on);
                        P2OUT|=BIT7;          //Tat dau hai cham
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        GIO_ON;
                        if((temp!=0)||(giay%2==0))Write_74HC595_8bit(soled[gioBCD]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        PHUT10_ON;
                        if((temp!=1)||(giay%2==0))Write_74HC595_8bit(soled[phut10BCD]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        PHUT_ON;
                        if((temp!=1)||(giay%2==0))Write_74HC595_8bit(soled[phutBCD]);
                        _delay_us(delay_led_on);
                        Write_74HC595_8bit(0xFF);
                        _delay_us(delay_led_off);

                        SWITCH_Key();
                        if(press!=0)
                        {
                                    Enable_timerA0=1;
                                    Dem_timerA0=0;
                                    //__bic_SR_register(GIE);
                                    switch(press)
                                    {
                                                case 1:
                                                {
                                                            if(temp==1)temp=0;
                                                            else temp=1;
                                                            break;
                                                }
                                                case 2:           //Tang phut/gio
                                                {
                                                            if(temp==0)    //Gio
                                                            {
                                                                        if(gio==23)gio=0;
                                                                        else gio++;
                                                                        I2C_USCI_Write_Byte(0x02,((gio/10)<<4)+gio%10);
                                                            }
                                                            else    //Phut
                                                            {
                                                                        if(phut==59)phut=0;
                                                                        else phut++;
                                                                        I2C_USCI_Write_Byte(0x01,((phut/10)<<4)+phut%10);
                                                            }
                                                            break;
                                                }
                                                case 4: //Giam phut/gio
                                                {
                                                            if(temp==0)                //Gio
                                                            {
                                                                        if(gio==0)gio=23;
                                                                        else gio--;
                                                                        I2C_USCI_Write_Byte(0x02,((gio/10)<<4)+gio%10);
                                                            }
                                                            else    //Giam phut
                                                            {
                                                                        if(phut==0)phut=59;
                                                                        else phut--;
                                                                        I2C_USCI_Write_Byte(0x01,((phut/10)<<4)+phut%10);
                                                            }
                                                            break;
                                                }
                                                case 8:
                                                {
                                                            Dem_timerA0=120;
                                                            break;
                                                }
                                    }
                                    //__bis_SR_register(GIE);
                        }
                        if(Dem_timerA0>=120)break;
            }
            press=0;
            Dem_timerA0=0;
            Enable_timerA0=0;
}


Các hàm còn lại các bạn có thể tự viết hoặc tham khảo trong project mẫu.
Download toàn bộ Project tại đây

No comments:

Post a Comment

END COMMENT FACEBOOK-->