Showing posts with label PIC. Show all posts
Showing posts with label PIC. Show all posts

PIC 16F887

Mình rất thích dòng vi điều khiển PIC , việc lập trình PIC đối với người chưa biết gì như mình rất khó, với những ai giống mình , bài viết này sẽ cung cấp cho bạn những kiến những cơ bạn , học tới đâu thì tìm hiểu thêm về nó! Hi vọng bài viết này sẽ có ích cho các bạn, mình chọn chip 16f887 để thực hành :
1,

Module I/O PORT của PIC16F887

Hình 1. Sơ đồ chân PIC16F887
Module I/O của PIC16F887  có 35I/O trong đó có 1 input. Tất cả các chân của PIC có khả năng cấp và rút dòng khoảng 25mA, đủ điều khiển 2 LED mắc song song. Tuy nhiên, giới hạn của mỗi PORT (8 chân) chỉ là 90mA mà thôi. Do đó, khi thiết kế cần tính toán tránh quá tải cho từng chân (vượt quá 25mA) và tránh quá tải cho toàn PORT (90mA).

Các PORT của PIC16F887 lần lượt được đặt tên theo chữ cái là PORTA, PORTB, PORTC, PORTD và PORTE, tương ứng với mỗi chân I/O ngoài chứng năng Input và Output logic ra còn tích hợp thêm nhiều tính năng khác, như RX, TX cho module USART, SDO, SDI, SCK, SS cho module SPI ….
Ngoài ra, trên Hình 1, những chân ANx được tô vàng là những chân có tính năng Analog, nghĩa là ngõ và của module ADC.Ứng với mỗi chân sẽ có 1 bit cấu hình chế độ Analog hay Digital trong 2 thanh ghi ANSEL và ANSELH.
Hình 2. Thanh ghi ANSEL
Hình 3. Thanh ghi ANSELH
Tương ứng với mỗi chân ANx (tô vàng trong Hình 1) mỗi bit ANSx (x = 0 – 13) sẽ quyết định chân ANx đó có tính năng Analog hay Digital, trong Hi-Tech C có thể dùng các định nghĩa của Datasheet để gán/đọc giá trị các thanh ghi này. Với giá trị được xóa về không (0) thì chân AN tương ứng sẽ là chân Digital (có thể xuất, đọc mức logic từ PORT), nếu ANSx được gán bằng Một (1) thì chân AN tương ứng sẽ là chân Analog, chỉ có tính năng Analog input cho ADC. Lưu ý cách đọc giá trị thanh ghi trong datasheet, dòng chữ trên cùng R/W-1 có nghĩa là bit này có thể Read/Write và khi Reset sẽ có giá trị là 1. Điều đó cũng có nghĩa là mặc định những chân có kỹ hiệu AN sẽ có tính năng Analog, muốn bật tắt 1 con LED trên những chân này,hãy cấu hình bit AN tương ứng trước nhé. Một ví dụ trong Hi-Tech C:
1ANSEL = 0; /* Cấu hình cho các chân AN0 -> AN7 là chân Digital */
2ANSELH = 0; /* Cấu hình cho các chân AN8 -> AN13 là chân Digital */
Hay có thể cấu hình theo từng bit (từng chân)
1ANS0 = 0; /* Cấu hình chân AN0 là chân Digital (chân RA0) */
2ANS5 = 1; /* Cấu hình chân AN5 là chân Analog (Chân RE0) */
Ứng với mỗi PORT sẽ có 2 thanh ghi chính để điều khiển là TRIS PORT, tương ứng với PORTA, PORTB, PORTC, PORTD và PORTE có các thanh ghi TRISA, TRISB, TRISC, TRISD và TRISE để điều khiển hướng xuất nhận của PORT.
Lưu ý, TRIS cấu hình cho PORT là input thì lúc này, chân được cấu hình input có trở kháng cao, có thể đọc được logic điện áp trên chân đó, và có thể coi như chân đó cách ly với mạch bên ngoài. Không phải tất cả các PORT đều có đầy đủ 8 bit. PORTB còn có thêm tính năng Interrupt On Change và Internet Pull-Up
Ví dụ PORTA, có thanh ghi TRISA và thanh ghi PORTA
Hình 4. Thanh ghi PORTA
Hình 5. Thanh ghi TRISA
Như vậy để cấu hình I/O PORT để sử dụng, cần 3 bước:
+ Xác định xem chân sử dụng có tính năng Analog hay không, nếu có, cấu hình là Analog (ADC) hay Digital (I/O) tùy thuộc vào mục  đích
+ Cần xác định xem I/O cần dùng là ngõ vào hay ngõ ra, nếu ngõ vào điều khiển TRIS tương ứng bằng 1 (số 1 giống chứ i trong input) và ngược lại là 0 (giống chư o trong output)
+ Xuất ra I/O mức cao hay mức thấp tùy thuộc vào yêu cầu mà xuất trên PORT
Ví dụ: Cấu hình RE1 là ngõ ra digital điều khiển LED và RB0 là ngõ vào đọc giá trị nút nhấn:
ANS6 = 0; //RE1 là chân Digital

ANS12 = 0; //RB0 là chân Digital

TRISE1 = 0; //RE1 là Digital Output, có thể điều khiển LED

TRISB0 = 1; //RB0 là Digital Input, có thể đọc giá trị của nút nhấn

RE1 = 1; //Xuất mức cao ra RE1

if(RB0 == 0) {

   RE1 = 0; //Đọc giá trị của RB0, kiểm tra nếu RB0 = 0 thì xuất mức 0 ra RE1

}
(tiếp theo …)
WEAK PULL-UP trên PORTB
IOC trên PORTB
Ví dụ về bật tắt LED trên chân RE1 trong mỗi 500ms
#include

//Cấu hình sử dụng dao động nội 4MHz

__CONFIG(INTOSC & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT &

BORDIS & IESODIS & FCMDIS & LVPDIS);

__CONFIG(BORV40) ;

/* Hàm delay một khoảng ms mili giây */

void delay_ms(int ms);

 

void main()

{

  ANSEL = ANSELH = 0; //Cấu hình tất cả các chân AN là chân Digital

  TRISE1 = 0;  //Cấu hình chân RE1 là chân Digital Output

  while(1){

     RE1 ^= 1;  //Đảo trạng thái của RE1 ( dấu "^" nghĩa là XOR, Nếu RE1 = 1,

              //thì 1^1 = 0, gán lại cho RE1=0, nếu RE1 = 0, 0^1=1, gán lại RE1 = 1;)

     delay_ms(500); //Chờ trong khoảng  500mili giây

  }

}

void delay_ms(int ms)

{

    int i;

    for(i=0; i

        _delay(1000);//Dao động 4MHz,

                     ///tần số Clock là 1Mhz, => delay 1000 chu kỳ máy = 1mili giây

    }

}

Đề tài : Giải phương trình bậc 2 dùng PIC16f887 (Demo)

Mình đang cần người giúp mình hoàn thiện đề tài.Mọi ý kiến gửi về namdinhcuong2702@gmail.com
sourecode Link download  (phiên bản Demo)


File Kèm Theo

#include
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);
#include
#include   
#include   
#include "lcd.h"

void spi_init();
unsigned char spi(unsigned char data);
void xeeprom_write(unsigned int addr, unsigned char data);
unsigned char xeeprom_read(unsigned int addr);
#define CS    RD0

/*
    Ghi 1 byte gia tri 0x55 vao dia chi 0x00 cua EEPROM 25LC256
    Doc 1 byte tu dia chi 0x00 cua EEPROM 25LC256 ve
    trong 1 bien va kiem tra tren MPLAB (PITKit2)
*/
char Counter;
float a, b, c, delta,x1,x2;

void main()
{
   
    //khoi tao
    spi_init();
    lcd_init();
    //Cau hinh I/O
    TRISB0 = 1;
    WPUB0 = 1;//weak-pullup
    RBPU = 0;
        TRISB1 = 1;
    WPUB1 = 1;//weak-pullup
    RBPU = 0;
        TRISB2 = 1;
    WPUB2 = 1;//weak-pullup
    RBPU = 0;
   
   
    Counter = xeeprom_read(0x0005);
    if(Counter==0xFF) Counter = 0;


while(1){
   
   


 lcd_gotoxy(0,0);
  printf("he so A  ");
while(RB2){    if(RB0 == 0) {
            Counter++;
            lcd_gotoxy(0,0);
            printf("\fA(tang) :\n%d ",Counter);
            xeeprom_write(0x0006,Counter);
            while(!RB0);
        }
            if(RB1 == 0) {
            Counter--;
            lcd_gotoxy(0,0);
            printf("\fA(giam):\n%d ",Counter);
            xeeprom_write(0x0006,Counter);
            while(!RB1);
        }
    while(!RB2);
}

lcd_gotoxy(0,0);
printf("\he so B  ");
while(RB2){    if(RB0 == 0) {
            Counter++;
            lcd_gotoxy(0,0);
            printf("\fB(tang): \n%d ",Counter);
            xeeprom_write(0x0001,Counter);
            while(!RB0);
        }
            if(RB1 == 0) {
            Counter--;
            lcd_gotoxy(0,0);
            printf("\fB(giam):\n%d ",Counter);
            xeeprom_write(0x0001,Counter);
            while(!RB1);
        }
    while(!RB2);
}

lcd_gotoxy(0,0);
printf("he so C  ");
while(RB2){    if(RB0 == 0) {
            Counter++;
            lcd_gotoxy(0,0);
            printf("\fC(tang):\n%d ",Counter);
            xeeprom_write(0x0002,Counter);
            while(!RB0);
        }
            if(RB1 == 0) {
            Counter--;
            lcd_gotoxy(0,0);
            printf("\fC(giam):\n%d ",Counter);
            xeeprom_write(0x0002,Counter);
            while(!RB1);
        }
    while(!RB2);
}



    a = xeeprom_read(0x0006);
   
    b = xeeprom_read(0x0001);
   
    c = xeeprom_read(0x0002);
   
   


  delta = b * b - 4 * a * c;
  if (delta<0){lcd_gotoxy(1,0);
    printf(" vo nghiem");
        }
  else if (delta == 0)
     {
    lcd_gotoxy(1,0);
    printf("\n x1 = x2 = %f", -b/(2*a));
                    }
  else
  {
    lcd_gotoxy(1,0);
    printf(" x1 = %f", (-b + sqrt(delta))/(2*a));
    lcd_gotoxy(1,4);
    printf("\nx2 = %f", (-b - sqrt(delta))/(2*a));
  }
while(!RB2);   
   
}   
   
}
void putch(char c)
{
    lcd_putc(c);
}

void spi_init()
{
    ANSEL = ANSELH = 0;
    // IO PORT
    TRISC3 = 0;        // SCK la output
    TRISC5 = 0;        // SDO la output
    TRISC4 = 1;        // SDI la input
    TRISD0 = 0;        // 25LC256 chip select
    CS = 1;        // deselect chip
   
    //SSPSTAT
    SMP = 1;         // lay mau o giua chu ky bus
    CKE = 1;         // du lieu ra tren SDO theo canh lenh cua SCK
    //SSPCON
    SSPCON = 0b00100000;    // CKP = 0, SPI mode baudrate = Fosc/4
}
unsigned char spi(unsigned char data)
{
    WCOL = 0;        // clear any write collision condition
    SSPIF = 0;        // clear SSP interrupt flag
    SSPBUF = data;        // load the SSP buffer with data
    while(!SSPIF);    // wait for SSPIF to be set
    return SSPBUF;
}
void xeeprom_write(unsigned int addr, unsigned char data) {
//ghi lenh WREN
    CS = 0;
    spi(0x06);
    CS = 1;
    _delay(100);
   
    //Ghi byte 0x55 vao dia chi 0x0001
    CS = 0;
    spi(0x02);    //lenh WRITE
    spi((unsigned char)(addr>>8));    //Dia chi can ghi 0x0000
    spi((unsigned char)(addr));
    spi(data);    //Du lieu can ghi
    CS = 1;
}
unsigned char xeeprom_read(unsigned int addr)
{
    unsigned char temp;
    CS = 0;
    spi(0x03); //Lenh READ
    spi((unsigned char)(addr>>8));    //Dia chi can ghi 0x0000
    spi((unsigned char)(addr));
    temp = spi(0x00); //Ghi 1 byte va nhan ve 1 byte
    CS=1;
    return temp;
}   





Thiết kế: LCD Menu Tree

 Nguồn PIC Việt Nam
Thiết kế: LCD Menu Tree
Sử dụng: PIC 16F877A, LCD, nút bấm
Mức độ thiết kế: Trình bày ý tưởng, giải thuật, lập trình firmware bằng ngôn ngữ C, mô phỏng bằng Proteus
Tác giả: Phạm Minh Tuấn

Nội dung tài liệu tham khảo nằm trong file đính kèm.







Hình Ðính Kèm
Click image for larger version



Name: LCD_Tree_Menu.png

Views: 121

Size: 85.1 KB

ID: 1111





File Kèm Theo
File Type: txt readme.txt (1.4 KB, 203 lần tải)
File Type: zip PIC_contest_2007_11_LCD_Tree_Menu.zip (284.8 KB, 1089 lần tải)
/*+-----------------------------------------------------------------------+*
 *|   Chuong trinh Dung de hien thi MENU dieu khien len LCD 16x2          |*
 *|   MENU co dang cay(TREE) 1 MENU chinh co the co nhieu MENU con        |*
 *|   DE DANG them vao MENU bat ky dau hay sua chua de su dung lai        |*
 *|***********************************************************************|*
 *| Chuong trinh duoc viet voi Pham Minh Tuan: SVDH Su Pham Ky Thuat HCMC |*
 *|      Moi thac mac xin lien he email: emailchotoi@yahoo.com            |*
 *|***********************************************************************|*
 *|   Phan cung ket noi voi 1 LCD nhu sau (Su dung LCD driver cua CCS C)  |*
 *|               PIC     |       LCD                                     |*
 *|              ----------------------                                   |*
 *|              RD4->7   |      D4->7                                    |*
 *|              RD0      |      EN                                       |*
 *|              RD1      |      RS                                       |*
 *|              RD2      |      RW                                       |*
 *|   va ket noi voi cac phim nhan nhu sau:                               |*
 *|              RB4   :  CANCEL                                          |*
 *|              RB5   :  ENTER                                           |*
 *|              RB6   :  DOWN                                            |*
 *|              RB7   :  UP                                              |*
 *+-----------------------------------------------------------------------+*/

#include "16F877A.h"
#device adc=10
#fuses NOLVP, NOWDT, HS
#use delay(clock=4000000)
#include "lcd_driver.c"

/* Dinh nghia MA PHIM se duoc dung de dieu khien Menu
 * UP - DOWN : Lua chon mot Muc trong Menu
 * ENTER: Neu co Menu co, thi hien thi Menu con, nguoc lai thi hanh lenh
 * CANCEL: Tro ve Menu cap bac truoc no
*/
#define UP     0xB0
#define DOWN   0x70
#define ENTER  0xD0
#define MENU   0xF0
#define CANCEL 0xE0

/* Dinh nghia gia tri CHI MUC cho Menu Chinh, Menu con, tien cho viec so sanh
 * O day su dung tat ca la 12 Dong MENU
 */
#define ALL_MENU     14
#define BEGIN        0x00  //Mac dinh day la Chi Muc goc
#define MICROCHIP    0x01
#define ATMEL        0x02
#define XILINX       0x03
#define PIC16        0x04
#define PIC18        0x05
#define DSPIC        0x06
#define PIC877A      0x07
#define PIC84        0x08

#define AVR          0x0A
#define MCS51        0x0B
#define COOLRUNNER   0x0C
#define VIRTEX       0x0D
#define ABOUT        0x0E
#define NAME         0x0F

/* Co the giai thich Cau truc cua Menu duoc su dung nhu sau:
 * +MenuID la ID(dinh danh) cua Dong Menu do
 * +SubMenu   la ID(dinh danh) cua Dong Menu Truoc no 1 BAC
 * +MenuName  gom 17 ky tu Chua toi da 16 ky tu in ra LCD la 1 ky tu ket thuc(Chuoi)
 */
struct TypeMenu {
   int8 MenuID;
   int8 SubMenu;
   char MenuName[16];//17
};
int8 ContainMenu, STATE = BEGIN, PAGE = 0, LEVEL[7], LevelPtr=0;
Boolean  AccessENTER = TRUE, AccessCANCEL=TRUE;

/*Cau truc cua Menu o day duoc hinh dung nhu sau:
 * BEGIN
 *   + MICROCHIP
 *   |     + 8 BIT PIC16
 *   |     |      + PIC 16F877A 
 *   |     |      + PIC 16F84   
 *   |     + 8 BIT PIC18     
 *   |     + 16 BIT dsPIC    
 *   + ATMEL
 *   |     + 8 BIT AVR       
 *   |     + 8 BIT MCS51     
 *   + XILINX
 *   |     + CoolRunner      
 *   |     + VirTex-4        
 */
const struct TypeMenu MenuOfTuan[ALL_MENU] 
            ={{MICROCHIP,   BEGIN,     "MicroChip"   },
              {ATMEL,       BEGIN,     "Atmel"       },
              {XILINX,      BEGIN,     "Xilinx"      },
              {PIC16,       MICROCHIP, "8 Bit PIC16" },
              {PIC18,       MICROCHIP, "8 Bit PIC18" },
              {DSPIC,       MICROCHIP, "16 Bit dsPIC"},
              {AVR,         ATMEL,     "8 Bit AVR"   },
              {MCS51,       ATMEL,     "8 Bit MCS51" },
              {COOLRUNNER,  XILINX,    "CoolRunner"  },
              {VIRTEX,      XILINX,    "Virtex-4"    },
              {PIC877A,     PIC16,     "PIC 16F877A" },
              {PIC84,       PIC16,     "PIC 16F84"   },
              {ABOUT,       BEGIN,     "About"       },
              {NAME,        ABOUT,     "Pham Minh Tuan"}};


/* Cau truc dung de chua Menu se hien thi trong Mang MENU da Dinh nghia */
struct typeMenu MenuPoiter[5];

//Luu Y la Ngo vao o day chinh la su thay doi co y nghia doi voi 1 HAM
/*+ ---------------------------------------------------------------------------+*
 *|  Ham QueryMenu: dung LOC ra nhung Item la Menu CON cua trang               |*
 *|  thai(STATE) hien tai                                                      |*
 *|  + Ngo vao: Trang thai hien tai (STATE)                                    |*
 *|  + Tra ve So luong MENU CON cua trang thai(STATE) hien tai                 |*
 *+----------------------------------------------------------------------------+*/
int8 QueryMenu() {
   int8 i,j=0, NumMenu = 0;               
   for(i=0; i
      if(MenuOfTuan[i].SubMenu == STATE) {
         NumMenu++;                       //Neu Menu duoc kiem tra co chi muc
      }                                   //giong voi SubMenu cua Menu hien tai
   }                                      // thi no la Menu CON cua Menu do
   if(NumMenu) {
     for(i=0; i
        if(MenuOfTuan[i].SubMenu == STATE) { //Nhieu hon 0 thi COPY no vao
         MenuPoiter[j] = MenuOfTuan[i];      //MenuPointer de hien thi
         j++;
        }
     }
   }
   return NumMenu;         //Tra ve so luong Menu da kiem tra



/*+---------------------------------------------------------------------------+*
 *|   Ham QueryLastMenu: Dung lay trang thai CAP TREN cua TRANG THAI hien tai |*
 *|   Khi An CANCEL thi phai tro ve MENU TREN CAP cua MENU hien tai           |*
 *|   Vi du: Khi dang o STATE la PIC16 thi khi an CANCEL phai tro ve MENU     |*
 *|   TREN CAP cua no 1 bac tuc la STATE MICROCHIP                            |*
 *|   +Ngo vao : Khong                                                        |*
 *|   +Tra ve: Trang thai TREN 1 CAP cua trang thai HIEN TAI                  |*
 *+---------------------------------------------------------------------------+*/
int8 QueryLastMenu() {
   int8 i;                          //Mang Menu dang duoc hien thi co SubMenu
   for(i=0; i
      if(MenuOfTuan[i].MenuID == MenuPoiter[0].SubMenu)  //mot bac
         return MenuOfTuan[i].SubMenu;
   }
   return 0x00;
}


/*+---------------------------------------------------------------------------+*
 *|   Ham HasSubMenu: Co chuc nang kiem Tra Xem 1 Item Co ton tai Menu CON ko |*
 *|   Dieu nay la can thiet, Neu mot Item co Menu CON thi Khi AN ENTER        |*
 *|   phai Hien thi TAT CA Menu CON cua Item nay, neu Ko co Menu CON thi THI  |*
 *|   HANH Chuc nang cua Item do                                              |*
 *|   + Ngo vao: Trang thai hien tai  (STATE)                                 |*
 *|   + Tra ve Gia tri TRUE neu co Menu CON, nguoc lai la FALSE               |*
 *+---------------------------------------------------------------------------+*/
BOOLEAN HasSubMenu() {
   int8 i;
   for(i=0; i
      if(STATE == MenuOfTuan[i].SubMenu)  //Neu trang thai hien tai giong voi
         return TRUE;                     //SubMenu thi no chinh la Menu con
   }                                      //cua Trang thai HIEN TAI, nghia la co
   return FALSE;                          //Menu con, nguoc lai: KHONG CO
}


/*+---------------------------------------------------------------------------+*
 *|   Ham ProcessMenu: Dung de hien thi Mang Menu MenuPoiter da duoc LOC      |*
 *|   Co Phan trang de khi Chi muc tro den  1 Item vuot qua so Item thi Reset |*
 *|   +Ngo vao: PAGE -> Chi muc (TRANG) cua mot Mang menu da loc (MenuPoiter) |*
 *|             ContainMenu -> So Menu trong Mang Menu                        |*
 *|   +Tra ve: KHONG                                                          |*
 *+---------------------------------------------------------------------------+*/
void ProcessMenu() {
   int8  PageTemp;               //LCD co 2 dong, PAGE tro dong 1, PageTemp->d2
   if(PAGE == 0xFF) {            //Khi an UP or DOWN lam cho PAGE giam tu 0->0xFF
      PAGE = ContainMenu - 1;    //hay hi PAGE > Tong so Menu hien thi ....
      PageTemp = 0;              //Thi can phai tro LAI sao cho khi nhin thay
   }                             //Menu nhu duoc cuon tron.->DAY LA 1 CACH
   else if(PAGE >= ContainMenu) {
      PAGE = 0;
      PageTemp = 1;
   } else if(PAGE == (ContainMenu - 1)) PageTemp = 0;
   else PageTemp = PAGE + 1;
  
   //In ra dong thu 1, va dong thu 2
   printf(lcd_putc,"\f>%s",MenuPoiter[PAGE].MenuName);
   if(ContainMenu > 1)
   printf(lcd_putc,"\n %s",MenuPoiter[PageTemp].MenuName);
}


/*+---------------------------------------------------------------------------+*
 *|   Ham ProcessAction: La Ham QUANG TRONG nhat trong ca chuong trinh        |*
 *|   Ham nay tuy thuoc vao gia tri PHIM NHAN dua vao ma thi hanh MENU 1 cach |*
 *|   phu hop, se giai thich ro hon trong noi dung cua HAM                    |*
 *|   +Ngo vao: gia tri PHIM NHAN, TRANG hien tai, TRANG THAI hien tai        |*
 *|   +Tra ve: KHONG                                                          |*
 *+---------------------------------------------------------------------------+*/
void ProcessAction(int16 Key) {
   if(STATE == BEGIN) AccessCANCEL = FALSE;  //Neu TRANG THAI dang o CAP cao nhat
   else  AccessCANCEL = TRUE;                // thi NUT NHAN CANCEL bi vo hieu
   switch(Key) {
      case ENTER:
      if(!AccessENTER) break;       //Neu la nut nhan ENTER va ENTER duoc cho phep
         LEVEL[LevelPtr] = PAGE;    //Luu Trang Hien hanh, va ngan xep
         LevelPtr++;                //len 1 don vi
         STATE = MenuPoiter[PAGE].MenuID; //Lay trang thai MOI, ung voi su lua chon
         PAGE = 0;                  //Khoi dau tu TRANG 0
         ContainMenu = QueryMenu(); //Kiem tra co bao nhien MENU CON
         if(ContainMenu) {
            ProcessMenu();          //Neu nhieu hon 0, thi hien thi
         }else {
            AccessENTER = FALSE;    //Nguoc lai la Item cuoi cung, ko co Menu con
            switch(STATE){          //Do do Disable nut ENTER, va Kiem tra xem
               case PIC877A:        //Neu tu Item PIC 16F877A thi thuc hien
                  lcd_putc("\fHi 16F877A");
                  break;
               case PIC84:          //Neu tu PIC 16F84 thi ...
                  lcd_putc("\fHi 16F84");
                  break;
               case AVR:            //...
                  lcd_putc("\fHi AVR");
                  break;
               case MCS51:
                  lcd_putc("\fHi MCS51");
                  break;
               case COOLRUNNER:
                  lcd_putc("\fHi Cool Runner");
                  break;
               case VIRTEX:
                  lcd_putc("\fHi VirTex");
                  break;
               case PIC18:
                  lcd_putc("\fHi PIC 18F4550");
                  break;
               case DSPIC:
                  lcd_putc("\fHi dsPIC");
                  break;
            }
           
         }
         break;
        
      case UP:                   //Neu la NUT UP va ENTER duoc cho phep
         if(!AccessENTER) break;
         PAGE --;                //Giam TRANG HIEN TAI va HIEN THI
         ProcessMenu();
         break;
      case DOWN:                 //Neu la NUT DOWN va ENTER duoc cho phep
         if(!AccessENTER) break;
         PAGE ++;                //Tang TRANG HIEN TAI va HIEN THI
         ProcessMenu();
         break;
      case CANCEL:                  //Neu la CANCEL va NUT CANCEL duoc cho phep
         if(!AccessCANCEL) break;
         if(LevelPtr) LevelPtr--;   //Lay TRANG da luu truoc do tu ngan xep
         PAGE = LEVEL[LevelPtr];    //giam con tro ngan xep
         if(!HasSubMenu()) {        //Neu Item Hien hanh khong co Menu CON
               AccessENTER = TRUE;  //Cho Phep nhu ENTER tro lai
               STATE = MenuPoiter[PAGE].SubMenu;
         } else {                   //Neu trang hien hanh co Menu CON
               STATE = QueryLastMenu();   //Lay TRANG THAI Tren no 1 CAP
            }
            ContainMenu = QueryMenu();
            ProcessMenu();          //Hien thi Menu
         break;
      case MENU:
         ContainMenu = QueryMenu();
         ProcessMenu();
         Break; 
   }
}

/*
Chuong trinh con Quet PHIM dung de TEST cho MENU nay, khong QUAN TRONG, co ban
la no se goi MA PHIM UP, DOWN, ENTER, CANCEL toi cho ham ProcessAction khi mot
trong cac PHIM duoc nhan va duoc tha (OnRelease)
*/
int8 keyscan() {
   int8 inB, varRet;
   inB = input_b()&0xF0;
   if(inB != 0xF0){
      varRet = inB;
      delay_ms(20);
      inB = input_b()&0xF0;
      if(inB == 0xF0) {
         return varRet;
      } else {
         return 0;
      }
   }
}


/*Chuong trinh CHINH
*/
void Main() {

   int8 key;
   set_tris_b(0xFF); //Khoi tao PORTB -> INPUT
   lcd_init();       //Khoi tao LCD
   processAction(MENU); //Hien thi MENU Chinh
   while(1){
      key = keyscan();  //Cho Phim NHAN
      if(key) {         //Neu PHIM nhan HOP LE, hien thi
         processAction(key);
      }
   }
}


PWM

PWM

Usart



 Đo nhiệt độ hiển thị kết quả trên màn hình máy tính
Download Hyper terminal for Win7 tại đây
Code
Soure file Usart.c
#include
#include
#include "i2c.h"

__CONFIG(HS & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS);        //1st config. word
__CONFIG(BORV21);        //2nd config. word

#define _XTAL_FREQ    4000000

//Global variables
    unsigned char cmd_byte;
    unsigned char temp;

//Interrupt Service Routine
void interrupt ISR(void)
{
}   

//Required main function
void main(void)
{
    char i,c;
    char buf[10];
   
    BRG16 = 0;
//    BAUDCTL = BAUDCTL & 0xF7;
    TXSTA = 0x24;    //Che do high-speed, cho phep phat du lieu
    RCSTA = 0x90;    //Nhan du lieu lien tuc, dung cac chan TX/RX
    //baud rate = Fosc / (16*(n+1))
    //n = Fosc/((baud rate)*16) - 1
    SPBRG = 25;    //Gia tri ung voi baud rate = 9600, xtal 4 MHz
    //SPBRGH khong can dung den
        TRISC3 = 1;            //configure PORTC<3> as input
    TRISC4 = 1;            //configure PORTC<4> as input
    TRISB = 0;            //make PORTB an output

//Set the slew rate and baud rate for 50 kHz operation
    SMP = 1;            //set for Standard speed slew rate
    SSPADD = 19;        //set the required baud rate (warning!)

//Configure as I2C master with Fosc/4 clock source
    SSPM3 = 1;            //set to I2C master mode with Fosc/4 clock source
    SSPEN = 1;            //Enable SDA and SCL pins to operate in I2C mode
    SSPCON2 = 0;        //ensure SSPCON2 is cleared

//Put '00000000' into variable cmd_byte.
//This is the read command that will be sent to the TC74
    cmd_byte = 0x00;
   
    while (1) {
    //    while(RCTF==0)
    //    C=RCREG;
    //    TXREG=c;
    //    while (TRMT==0)
            SEN = 1;            //Initiate a START condition
        while (SEN);        //
        SSPBUF = 0x90;        //send address of TC74 w/0 in the LSB (write action)
        while (RW);            //wait for write to complete
        while (ACKSTAT);    //Wait for ACK from TC74
       
        while (TRMT == 0);
        SSPBUF = cmd_byte;    //send READ command
        _delay(8);
        while (RW);
//------------------
        while (ACKSTAT);    //Get ACK from TC74
   
        while (TRMT == 0);
       
        RSEN = 1;            //send repeated start
        while (RSEN);
       
        SSPBUF = 0x91;        //send TC74 address with READ bit set
        _delay(8);
        while (RW);
//------------------
        while (ACKSTAT);
       
        while (TRMT == 0);    //Get ACK from TC74
        RCEN = 1;            //enable receive mode
        while (RCEN);        //wait until temperature data received
        temp = SSPBUF;
//------------------
        ACKDT = 1;            //NACK
        ACKEN = 1;            //send NACK condition
        while (ACKEN);
        PEN = 1;            //send STOP condition
        while (PEN);
//------------------
    //    PORTB = temp;
    //    while (GODONE);
    //    temp = ADRESH;
        //Gia su da co ket qua A/D
        //Xoa bo dem ky tu
       
        for (i = 0; i < 10; i++) buf[i] = 0;
        //Chuyen doi tu unsigned char sang ky tu ASCII
        utoa(buf, temp, 10);
       
        i = 0;
        while (buf[i] != 0) {
            TXREG = buf[i];
            i++;
            while (TRMT == 0);
        }
        TXREG = '\n';
        while (TRMT == 0);
        TXREG = '\r';
        for (i = 0; i < 10; i++) __delay_ms(100);
    }
}
Header file i2c.h

#ifndef    _I2C_H_
#define    _I2C_H_

void i2c_start();
void i2c_stop();
void i2c_init();
unsigned char i2c_read(unsigned char ack);
unsigned char i2c_write(unsigned char d);

#endif

Công nghệ mTouch

Sản phẩm demo công nghệ mTouch của công ty R&P được giới thiệu tại picvietnam và dientuvietnam ở các luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=3187
http://www.dientuvietnam.net/forums/showthread.php?p=149856
Đây là source code và báo cáo về sản phẩm này.
http://falleaf.net/download/mTouch/REP01.02.MTOUCH.NGMT.041208.SRC.zip




source file
main.c
#include
#include
#include "touch.h"
#include "lcd.h"


__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);

extern volatile unsigned char touch_pressed;
   
void main()
{
    RE1 = 0;
    TRISE1 = 0;
    ANS6 = 0;
   
    lcd_init();
    touch_init();
   
    lcd_puts("\fLab - 8\n-----mTouch-----");
   
    OPTION = 0b10000100;        // timer 0 prescaler = 1:256
    T0IF = 0;
    T0IE = 1;
    GIE = 1;
       
    while(1){
       
        if(touch_pressed){
            RE1 = 1;
        }else{
            RE1 = 0;
        }
    }
}
void putch(char c)
{
    lcd_putc(c);
}
void interrupt isr()
{
    if(T0IF && T0IE){
        touch_service();
        TMR0 = 0;
        T0IF = 0;
    }
}
lcd.c

#include
#include
#include "lcd.h"

void lcd_init(){
    unsigned char i;
    LCD_EN_TRIS = 0;
    LCD_RS_TRIS = 0;
    LCD_RW_TRIS = 0;
    LCD_DATA4_TRIS = 0;
    LCD_DATA5_TRIS = 0;
    LCD_DATA6_TRIS = 0;
    LCD_DATA7_TRIS = 0;
    LCD_EN = 0;
    LCD_RS = 0;
    LCD_RW = 0;

    __delay_ms(100);                // delay for power on
   
    // reset LCD
    lcd_put_byte(0,0x30);
    __delay_ms(50);
    lcd_put_byte(0,0x30);
    __delay_ms(50);
    lcd_put_byte(0,0x32);
    __delay_ms(100);                // delay for LCD reset
    __delay_ms(100);                // delay for LCD reset
    __delay_ms(100);                // delay for LCD reset
   
    while(lcd_busy());
    lcd_put_byte(0,FOUR_BIT & LINES_5X7);            // Set LCD type
    while(lcd_busy());
   
    lcd_put_byte(0,DOFF&CURSOR_OFF&BLINK_OFF);        // display off
    while(lcd_busy());
    lcd_put_byte(0,DON&CURSOR_OFF&BLINK_OFF);        // display on
    while(lcd_busy());
   
    lcd_put_byte(0,0x01);                            // clear display and move cursor to home
    while(lcd_busy());
    lcd_put_byte(0,SHIFT_CUR_LEFT);                // cursor shift mode
    while(lcd_busy());
    lcd_put_byte(0,0x01);                            // clear display and move cursor to home
    while(lcd_busy());
}
unsigned char lcd_busy()
{
    unsigned char busy;
   
    LCD_DATA4_TRIS = 1;
    LCD_DATA5_TRIS = 1;
    LCD_DATA6_TRIS = 1;
    LCD_DATA7_TRIS = 1;
   
    LCD_RW = 1;
    LCD_RS = 0;
    __delay_us(20);
    LCD_EN = 1;
    __delay_us(20);
   
    busy = LCD_DATA7;
   
    LCD_EN = 0;
    __delay_us(20);
    LCD_EN = 1;
    __delay_us(20);
    LCD_EN = 0;

   
    return busy;
}
unsigned char lcd_get_byte(unsigned char rs)
{
    BYTE_VAL b;
   
    LCD_DATA4_TRIS = 1;
    LCD_DATA5_TRIS = 1;
    LCD_DATA6_TRIS = 1;
    LCD_DATA7_TRIS = 1;
   
    LCD_RW = 1;
    LCD_RS = 0;
    if(rs) LCD_RS = 1;
    __delay_us(20);
    LCD_EN = 1;
    __delay_us(20);
   
    b.bits.b7 = LCD_DATA7;
    b.bits.b6 = LCD_DATA6;
    b.bits.b5 = LCD_DATA5;
    b.bits.b4 = LCD_DATA4;
   
    LCD_EN = 0;
    __delay_us(20);
    LCD_EN = 1;
    __delay_us(20);
    b.bits.b3 = LCD_DATA7;
    b.bits.b2 = LCD_DATA6;
    b.bits.b1 = LCD_DATA5;
    b.bits.b0 = LCD_DATA4;
    LCD_EN = 0;
   
    return b.Val;
}
void lcd_put_byte(unsigned char rs, unsigned char b)
{
    BYTE_VAL temp;
   
    LCD_DATA4_TRIS = 0;
    LCD_DATA5_TRIS = 0;
    LCD_DATA6_TRIS = 0;
    LCD_DATA7_TRIS = 0;
   
    LCD_RS = 0;
    if(rs) LCD_RS = 1;
   
    __delay_us(20);
    LCD_RW = 0;
    __delay_us(20);
    LCD_EN = 0;
   
    temp.Val = b;
   
    // send the high nibble
    LCD_DATA4 = temp.bits.b4;
    LCD_DATA5 = temp.bits.b5;
    LCD_DATA6 = temp.bits.b6;
    LCD_DATA7 = temp.bits.b7;
    __delay_us(20);
    LCD_EN =  1;
    __delay_us(20);
    LCD_EN = 0;
    // send the low nibble
    LCD_DATA4 = temp.bits.b0;
    LCD_DATA5 = temp.bits.b1;
    LCD_DATA6 = temp.bits.b2;
    LCD_DATA7 = temp.bits.b3;
    __delay_us(20);
    LCD_EN =  1;
    __delay_us(20);
    LCD_EN = 0;
}
void lcd_putc(char c){
    switch(c){
        case '\f':
            lcd_put_byte(0, 1);
            while(lcd_busy());
            break;
        case '\n':
            lcd_gotoxy(0, 1);
            break;
        default:
            if(isprint(c)){
                lcd_put_byte(1, c);
                while(lcd_busy());
            }
            break;
    }
}

void lcd_gotoxy(unsigned char col, unsigned char row)
{
    unsigned char address;
   
    if(row!=0)
        address=0x40;
    else
        address=0;
   
    address += col;
    lcd_put_byte(0,0x80|address);
    while(lcd_busy());
}
void lcd_puts(const char* s)
{
    while(*s){
        lcd_putc(*s++);
    }
}
touch.c
#include
#include
#include "touch.h"
volatile unsigned char touch_pressed=0;

void touch_init(void)
{
    TRISA0 = 1;        // C12IN0-
    TRISA2 = 1;        // C2IN+
    ANS2 = 1;        //
    ANS0 = 1;
   
    TRISA5 = 0;        // C2OUT
    ANS5 = 0;
   
    TRISC0 = 1;        // T1CKI
   
    // comparator 1
    C1OE = 1;
    C1POL = 1;
    C1R = 1;
    C1ON = 1;
    // comparator 2
    C2OE = 1;
    C2ON = 1;
   
    CM2CON1 = 0b00100000;
   
    // VREF = 2/3 Vdd
    //VRCON = 0b10001111;
    VRCON = 0b10001111;
    // SR latch control
    SRCON = 0xF0;
    // timer 1
    TMR1L = 0;
    TMR1H = 0;
    T1CON = 0b00000111;
}
void touch_service()
{
    static unsigned char calibrate = 64;
    static long average=0;
    long raw, percent;
   
    TMR1ON = 0;            // dung timer 1
    // 1: Doc gia tri timer 1
    raw = ((unsigned int)TMR1H<<8) + TMR1L;
   
    // 2: khi moi khoi dong can tinh toan gia tri Average ban dau de lam moc so sanh
    if(calibrate){
        average = (average * 15 + raw)/16;
        calibrate--;
        TMR1L = 0;
        TMR1H = 0;
        TMR1ON = 1;
        return;
    }
   
    if(average==0){
        TMR1L = 0;
        TMR1H = 0;
        TMR1ON = 1;
        return;
    }
   
    // 3: tinh toan % thay doi cua gia tri raw so voi gia tri trung binh Average
    percent = average - raw;
    if(percent<0)
        percent = 0;
    else{
        percent *= 1000;
        percent /= average;
    }
   
    // 4: kiem tra neu su thay doi vuot qua nguong dinh san
    if(percent > PERCENT_ON){            // pressed
        touch_pressed = 1;
       
    }else{
        touch_pressed = 0;
        average = (average * 15 + raw)/16;
        if(raw > average)
            average = (average * 15 + raw)/16;
    }
   
   
    // 5: reset timer1, dem lai tu dau
    TMR1L = 0;
    TMR1H = 0;
    TMR1ON = 1;
}
Header file
lcd.h
#ifndef _LCD_H_
#define _LCD_H_

#include

#ifndef _XTAL_FREQ
#define _XTAL_FREQ    4000000
#endif


/* Display ON/OFF Control defines */
#define DON         0b00001111  /* Display on      */
#define DOFF        0b00001011  /* Display off     */
#define CURSOR_ON   0b00001111  /* Cursor on       */
#define CURSOR_OFF  0b00001101  /* Cursor off      */
#define BLINK_ON    0b00001111  /* Cursor Blink    */
#define BLINK_OFF   0b00001110  /* Cursor No Blink */

/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT    0b00000100  /* Cursor shifts to the left   */
#define SHIFT_CUR_RIGHT   0b00000101  /* Cursor shifts to the right  */
#define SHIFT_DISP_LEFT   0b00000110  /* Display shifts to the left  */
#define SHIFT_DISP_RIGHT  0b00000111  /* Display shifts to the right */

/* Function Set defines */
#define FOUR_BIT   0b00101100  /* 4-bit Interface               */
#define EIGHT_BIT  0b00111100  /* 8-bit Interface               */
#define LINE_5X7   0b00110000  /* 5x7 characters, single line   */
#define LINE_5X10  0b00110100  /* 5x10 characters               */
#define LINES_5X7  0b00111000  /* 5x7 characters, multiple line */


/* Pins mapping */
#ifndef        LCD_RS
#define    LCD_RS        RD1
#define    LCD_EN        RD3
#define    LCD_RW        RD2
#define    LCD_DATA4    RD4
#define    LCD_DATA5    RD5
#define    LCD_DATA6    RD6
#define    LCD_DATA7    RD7

#define    LCD_RS_TRIS        TRISD1
#define    LCD_EN_TRIS        TRISD3
#define    LCD_RW_TRIS        TRISD2
#define    LCD_DATA4_TRIS    TRISD4
#define    LCD_DATA5_TRIS    TRISD5
#define    LCD_DATA6_TRIS    TRISD6
#define    LCD_DATA7_TRIS    TRISD7
#endif

//typedef unsigned char        unsigned char;                // 8-bit unsigned

typedef union _BYTE_VAL
{
    unsigned char Val;
    struct
    {
        unsigned char b0:1;
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char b5:1;
        unsigned char b6:1;
        unsigned char b7:1;
    } bits;
} BYTE_VAL;

void lcd_init();
unsigned char lcd_busy();
unsigned char lcd_get_byte(unsigned char rs);
void lcd_put_byte(unsigned char a,unsigned char b);
void lcd_gotoxy(unsigned char col, unsigned char row);
void lcd_putc(char c);
void lcd_puts(const char* s);
#endif
touch.h
#ifndef _TOUCH_H_
#define _TOUCH_H_

#define PERCENT_ON        35

void touch_init(void);
void touch_service();

#endif
 code main.c(bật tắt)
#include
#include
#include "touch.h"
#include "lcd.h"


__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);

extern volatile unsigned char touch_pressed;
void delay_ms(int ms);   
void main()
{
    RE1 = 0;
    TRISE1 = 0;
    ANS6 = 0;
   
    lcd_init();
    touch_init();
   
    lcd_puts("\fLab - 8\n-----mTouch-----");
   
    OPTION = 0b10000100;        // timer 0 prescaler = 1:256
    T0IF = 0;
    T0IE = 1;
    GIE = 1;
       
    while(1){
       
        if(touch_pressed){
            RE1 = 1;    
                while(touch_pressed){                    // cho toi khi phim bam duoc nha
                __delay_ms(1);
            }
        }
        if(touch_pressed){
            RE1 = 0;    
                while(touch_pressed){                    // cho toi khi phim bam duoc nha
                __delay_ms(1);
            }
       
        }
    }
}
void putch(char c)
{
    lcd_putc(c);
}
void interrupt isr()
{
    if(T0IF && T0IE){
        touch_service();
        TMR0 = 0;
        T0IF = 0;
    }
}
void delay_ms(int ms)
{
    int i;
    for(i=0; i
        _delay(1000);//1ms   
    }
}

I/O

Các bước điều khiển chớp tắt 1 LED
1: Cấu hình chân cần dùng là Digital, xem sơ đồ chân xem chân đó là kênh thứ mấy của bộ ADC
VD: chân bật tắt LED là RE1, là kênh AN6 của module ADC, cấu hình bit ANS6 = 0
2: Cấu hình chân cần dùng là Output
VD: TRISE1 = 0
3: Muốn xuất trạng thái nào ra I/O port thì bật, tắt bit trên thanh ghi PORT
VD: RE1 = 1; //xuất mức 1(5V)
      RE1 = 0; //xuất mức 0 (0V)
Pull-Up
1: Cấu hình Chân cần sử dụng là chân digital
VD: dùng RB0 , ANS12 = 0 -> RB0 la digital
2: Cấu hình RB0 là input
VD: TRISB0 = 1
3: Cho phép Pull-Up trên RB0
VD: WPUB0 = 1; RBPU = 0
4: Nếu ngõ vào RB0 = 0, thì ngõ ra RE1 = 1;
   Nếu ngõ vào RB0 = 1; thì ngõ ra RE1 = 0;
code I/O

Sơ đồ bộ Kit

Related Posts Plugin for WordPress, Blogger...

Cùng tôi học Điện Tử ..(http://ilovec.tk)..