Articles by "code mẫu pic"

10 4.104 8051 9 Acquy adc pic All datasheet ALTIUM Altium Designer AM-FM Arduino ARM ARM là gì Ấn Tượng Bản tin công nghệ Bản tin Thiết Bị Số Barobo bất động sản biến Binary Bit board lpc2378 Bộ chuyển đổi ADC Bộ Đếm Bộ điều khiển cửa cuốn Bộ Định Thời Buy Khóa Số Điện Tử Buy Mạch đếm sản phẩm Buy Mạch giao thông Buy Mạch nạp Buy Matrix Byte C cho AVR các hàm vào ra các loại lõi arm các mạch DAC cơ bản các ngắt trong pic Cách đọc điện trở Cách Đọc Giá Trị Điện Trở Cách đọc giá trị tụ điện Cách hàn linh kiện dán cách làm mạch khóa số cách tạo linh kiện dán cad/cam Cài Đặt cài đặt proteus 8 cảm biến Cấu Kiện Logic Khả Trình cấu tạo cấu trúc arm cấu trúc lệnh CCS Chân chân Transistor Chip Khả Trình chuyển đổi Chuyển đổi số tương tự Chuyển Đổi Tương Tự/Số - ADC Chuyển động số chương trình City Clip Điện Tử Code 8051 - ASM Code 8051 - C Code 8051-C code ASM code ASM mẫu 8086 Code AVR - C code C Code Lập Trình Code led sao băng code maupic code mẫu 8051 Code Mẫu 8086 Code Mẫu cho ARM - LPC1343 code mẫu pic Code PIC - C codemaupic Counter Cổng Vào Ra Cơ Bản Cuộn Cảm Cửa cuốn DA DAC Debug Decimal Delay8051 Dev-C++ Diode DIY Dò đường Do It Yourself doanh nghiệp Download DTMF Mobile đảo chiều động cơ Điện Trở Điện Tử Điện Tử Cơ Bản điều chế độ rộng xung điều chế xung PWM điều khiển bằng điện thoại Điều khiển cửa cuốn Điều khiển cửa cuốn bằng điện thoại điều khiển động cơ đo điện áp đo nhiệt độ đo nhiệt độ hiển thị lên lcd trên 8051 Đo Nhiệt Độ LM35 + LCD Đo Nhiệt Độ LM35 + Led 7 thanh đọc màu điện trở đồ chơi động cơ chân không Động cơ nhiên liệu Động cơ robo đồng hồ thời gian thực Ebook Đại Học ebook điện tử Ebook đồ án Ebook Tin Học Encoder Encoder là gì Full Giải Thuật Giải thuật PID Giáo Dục giao tiếp i2c pic 16f877a giao tiếp i2c pic16f877a với ic ds1307 giao tiếp máy tính qua rs232 Giao Tiếp Máy Tính VB6 giao tiếp rs232 giao tiếp spi giữa 2 pic giao tiếp spi trong pic Giáo Trình Điện Tử Giới thiệu 8051 Giới thiệu cơ bản GPIO Graphic Design hàm Hàn linh kiện dán Hexadecimal Hệ Hexa Hệ Nhị Phân Hệ Thập Lục Phân Hệ Thập Phân hiển thị lên lcd 16x2 Hoạt Động Học Học 8051 qua các ví dụ đơn giản Học ALtium Designer học AVR Học Corel Draw X3 Học Eagle HỌC LẬP TRÌNH 16F877A Học Lập Trình 8051 Học Lập Trình C Học Orcad Học Protues hoc-lam-robot-do-duong-qua-video Hồng ngoại hướng dẫn hướng dẫn Altium Designer hướng dẫn đo đồng hồ VOM hướng dẫn keil - C lập trình 8051 hướng dẫn làm led sao băng hướng dẫn làm led trái tim hướng dẫn lập trình ARM Hướng Dẫn Lập Trình ARM - LPC1343 hướng dẫn lập trình ARM-LPC2378 hướng dẫn lập trình CCS hướng dẫn lập trình PIC Hướng Dẫn Led Trái Tim hướng dẫn module sim548c hướng dẫn sử dụng keil hướng dẫn sử dụng proteus 8 Hyper Terminal hercules 3.2.4 I/O IC 555 IC 7447 IC 74HC151 IC 74HC154 IC 74HC245 IC 74HC595 IC 74LS138 IC DS1307 IC đồng hồ thời gian thực IC LM324 IC LM342 IC LM7805 IC số IC số opamp LM324 IC Thông Dụng IC555 Interrupt Keil 4 Full keil arm Keil C Keil uVision3 kế toán kiểm toán khái niệm Khái Niệm Cơ Bản Kho Vật Liệu khóa điện tử khóa số dùng 8051 khóa số dùng 89s52 Khóa Số Điện Tử khuếch đại kiểm tra Kinh doanh maketing kinh tế quản lí Kỹ Thuật Kỹ Thuật Vi Xử Lý làm mạch điện lý thú Làm quen AVR Lap Trinh Dieu Khien Robot Lập Trình lập trình 8051 Lập Trình AVR Lập Trình C lập trình c++ Lập Trình Led Quảng Cáo Lập Trình Nhúng Lập trình pic Lập trình Robot Lập Trình Vi Điều Khiển Lập Trình Với AVR Studio LCD 16x2 Lcd16x2 Led Clock Led Quay led sao băng led trai tim Led Trái Tim Lịch sử ra đời Linh Kiện Cơ Bản linh kiện điện tử Loa LPC 2378 LSB lý thú Mã AVR - C Mạch 7seg Mạch Amply.Mạch Loa Mạch Autorobo Mạch bảo vệ Mạch Cảm Biến mạch cảm ứng sờ tay Mạch Cầu H Mạch cube Mạch Đếm Sản Phẩm Mạch điện cơ bản Mạch điện hay Mạch Điện Ứng Dụng Mạch Điều khiển động cơ Mạch Động Cơ Mạch đồng hồ Mạch đồng hồ 4 led Mạch giao thông Mạch IC số Mạch in mạch khóa số mạch khuếch đại thuật toán mạch led chúc mừng năm mới mạch led đẹp Mạch Led đơn Mạch Led Quảng Cáo mach led trai tim mạch led trái tim Mạch Led Vumeter mạch lý thú Mạch Ma trận Phím Mạch Matrix Mạch nạp Mạch nguồn Mạch Nút Bấm mạch sóng rf mạch tăng áp Mạch thu phát Mạch tổ hợp MSI Mạch trái tim Mạch Vi điều khiển Microbicho module module GSM/GPS Module Sim548 Module Sim548 giao tiếp với vi điều khiển PIC Module Sim548C Mosfet Motor Mô Phỏng Phần Cứng Mô Tả Phần Cứng MSB mua led sao băng News Ngắt Ngắt Trong LPC23xx ngân hàng Ngôn Ngữ Ngôn Ngữ C Ngôn Ngữ Tự Học Lập Trình C Ngôn Ngữ VHDL Nguyên Lý nguyên lý ic 555 Nguyên Tắc nháy led Nhập môn C Nhỏ Gọn Nibble opamp People Phần Mềm phần mềm altium Designer Phần mềm điện tử Phần Mềm Điện Tử Phần Mềm Điện Tử Hay Phần Mềm Hay Phần Mềm Led Quảng Cáo phần mềm proteus 8 Phần mềm vi tính Phần Mền Phương pháp hàn linh kiện dán PIC pic16f877a Print Design Proteus Proteus 7.8 SP2 FULL PWM quà tặng bạn gái quà tặng độc đáo quản trị doanh nghiệp quản trị kinh doanh quét led 7 đoạn Relay robocon Robot ROBOT DÒ ĐƯỜNG rút gọn mạch logic tổ hợp Sach Dien Tu Sản Phẩm Thú Vị Sản Phẩm Thương Mại Sáng tạo Short Smart Home SMD sơ đồ nguyên lý spi Sports Sử Dụng Sử Dụng Đồng Hồ sử dụng đồng hồ VOM sử dụng ngắt trong pic sự khác nhau Sức mạnh số Tải tài chính tài chính doanh nghiệp tài chính ngân hàng Tài Khoản Chia Sẻ Tài Liệu Tài Liệu 8051 tài liệu avr Tài liệu Điện Tử Tài Liệu Pic Tài liệu robocon tài liệu về ngân hàng Tài Liệu Vi Điều Khiển tailieuvn Tạo cổng Com ảo Tạo cổng nối tiếp ảo tạo dự án trong keil arm Tạo Project trong Vi Xử Lý ARM tạo thư viện altium designer tạo xung vuông Tạp chí Tạp Chí Hay tăng áp Tập lệnh AT Team Support TEAMPLATE PROTEUS Test thị trường tài chính Thiết Bị Thú Vị Thiết kế robot Thiết lập Fuse Bits Thiết Lập Pin Thuật Toán Thuật Toán Điều Khiển PID Thuật Toán Quine MCCluskey Thư viện Protues Thực Hành Thyristor Timer Timer/Counter Tin Học Chia Sẻ Tổ Chức Bộ Nhớ tổng quan về proteus 8 Transistor Tranzito Tranzitor Trao đổi học tập Travel Trình Biên Dịch Trình Dịch Trong Suốt Truyền Thông Nối Tiếp Không Đồng Bộ- UART truyền thông nối tiếp RS232 Tụ điện TUT - 8051 - ASM TUT - 8051 - KeilC tự hành Tự Học C Tự Học Lập Trình C Tý hon UART Update USB Ứng Dụng Led Quảng Cáo ứng dụng mạch khuếch đại thuật toán vẽ mạch in vẽ mạch nguyên lý VHDL Vi Điều Khiển Vi điều khiển - Ứng dụng vi điều khiển PIC Vi mạch số Vi Xử Lý Vi Xử Lý 8051 Vi Xử Lý 8086 Vi Xử Lý ARM Vi Xử Lý PIC Video Video Mach Điện Virtual Serial Port Driver VOM vxl Web Design xác định góc quay động cơ xử lý chuỗi
Hiển thị các bài đăng có nhãn code mẫu pic. Hiển thị tất cả bài đăng

Nhấp nháy LED có thể coi là một chương trình “Kinh điển”. Mỗi người khi bắt tay vào
học VĐK thì bài học đầu tiên là làm nhấp nháy một hay vài con LED trên chân VĐK. Trong
tài liệu này tôi cũng chọn bài tập đó để bắt đầu.
Mục đích của bài như trên đã nói: Làm nhấp nháy 8 LED tại PORTB của PIC 16F877A,
thời gian trễ do người lập trình định trước.
Những điều thu được qua bài học:
‐  Vẽ một mạch điện tử hoàn chỉnh dùng OrCad 9.2
‐  Tạo một Dự án trong CCS (cái này đã nói trong phần 2)
‐  Tệp định nghĩa các thanh ghi của PIC do người dùng tạo ra
‐  Thiết lập chế độ vào ra cho một cổng của PIC
‐  Sử dụng hàm tạo trễ thời gian

Dưới đây là sơ đồ phần cứng. Trong sơ đồ các LED được mắc chung lên dương nguồn
thông qua điện trở. Gia trị điện trở thay đổi trong khoảng 100Ω cho đến 560Ω tùy theo độ
sáng của LED mà ta muốn và cũng để đảm bảo dòng qua mỗi LED không quá 20mA khi
nguồn cấp là 5V. Như vậy để làm sáng LED ta chỉ việc đưa mức 0 ra các chân PIC và ngược
lại để tắt ta đưa mức 1.
 Sơ đồ mạch nháy 8 LED tại PORTB


 Sơ đồ mạch nguồn cho PIC

Mã nguồn chương trình nạp vào PIC 

//=================================================  ======= 
// Ten chuong trinh : Mach nhay den LED 
// Mo ta phan cung  : Dung PIC16F877A ‐ thach anh 20MHz 
//   : LED giao tiep voi PORTB 
//   : Cuc am cua LED noi voi PORTB 
//   : RB0 ‐ RB7 la cac chan output 
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
// Chu thich  : dung che do Power On Reset, PORTB = 00000000 
//   : chuong trinh viet cho PIC Tutorial 
//   :  chuong trinh nay hoan toan mien phi va co the dung cho 
//   : moi muc dich khac nhau 
//=================================================  ======= 

#include <16f877a.h> 
#include <def_877a.h> 
#device *=16 ADC=8 
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, 
NOLVP, NOCPD, NOWRT 
#use delay(clock=20000000) 

void main()
// Thiet lap che do cho PORTB 
TRISB = 0x00;   // Tat ca PORTB deu la cong xuat du lieu 
PORTB = 0xFF;   // Tat het cac LED 
While(1)  
  PORTB = 0;  // Cho các LED sáng 
  delay_ms(250);  // Tạo thời gian trễ 250ms 
  PORTB = 0xFF; 
  delay_ms(250); 

Qua ví dụ đơn giản trên bạn hiểu cách xuất dữ liệu ra một cổng của PIC và dùng các 
hàm tạo trễ. 
Thủ tục thiết lập vào ra cho một cổng hay một chân của PIC 
‐  Ghi giá trị vào thanh ghi điều khiển chế độ của cổng tương ứng là TRISx 
o  Bit 0 ứng với chân xuất dữ liệu 
o  Bit 1 ứng với nhận dữ liệu 
o  Thanh ghi TRISx có thể câu hình theo từng bit 
‐  Khi muốn xuất dữ liệu, ví dụ ra PORTB, câu lệnh là: PORTB = gia_tri; 
‐  Khi muôn nhận dữ liệu từ PORTB, câu lệnh là: data_in = PORTB; 
Về các hàm tạo trễ, trong CCS hỗ trọ sẵn 3 loại hàm tạo trễ là:  
‐  delay_cycles(gia_tri): gia_tri là thời gian trễ tính theo số chu kỳ máy 
‐  delay_us(gia_tri): Tạo trễ Micro giây 
‐  delay_ms(gia_trị): Tạo trễ Mili giây 
Bản chất của các hàm tạo trễ là đưa Vi điều khiển vào một vòng lặp chẳng làm gì cả cho 
đủ số thời gian mà ta cần. Ngoài việc dùng hàm tạo trễ có sẵn ta có thể tự viết hàm tạo trễ 
dùng bộ Timer.
Phạm Văn Ngọc Anh- 01644326695

Bộ chuyển đổi từ tương tự sang số là một khối mạch điện tử quan trọng, có mặt trong rất nhiều thiết kế điện tử. Các bộ ADC thực tế được đóng gói trong những IC chuyên dụng, do nhiều hãng sản xuất. Điểm quan trong cần lưu ý ở các bộ ADC này là độ phân giải và tốc độ lấy mẫu tìn hiệu. Độ phân giải của bộ ADC có thể là 8‐bít, 10‐bít, 12‐bít, 16‐bít, 24‐bít… Tốc độ lấy mẫu của ADC có thể nhanh hay chậm, tùy từng ứng dụng mà ta chọn tốc độ thích hợp.
Vi điều khiển PIC là một trong những dòng Vi điều khiển có phần giao tiếp ngoại vi mạnh và đa dạng. Bên trong PIC đã được tích hợp sẵn một bộ ADC có độ phân giải tối đa là 10‐bít (tùy chon là 8‐bit hay 10‐bit). Với bộ ADC trong PIC ta có thể làm được khá nhiều công việc, dưới đây tôi trình bày một ứng dụng của bộ ADC trong việc thiết kế mạch đo nhiệt độ sử dụng sensor nhiệt LM335.

Dưới đây là phần code mạch đo nhiệt dộ, hiển thị trên LCD.


//=================================================  =======
// Ten chuong trinh  : Mach do nhiet do
// Mo ta phan cung  : Dung PIC16F877A ‐ thach anh 20MHz
//   : LCD giao tiep voi PORTD
//   : Dau ra LM335 dua vao chan AN0
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
// Chu thich : hoac cac chu thich khac
//   : dung che do Power On Reset
//   : chuong trinh viet cho PIC Tutorial
//=================================================  =======
#include "16F877A.h"
#include "def_877a.h"
#device *=16 adc=10
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
#include <lcd_lib_4bit.c>  // Thu vien ham cho LCD
int8 low,high,key,mode,min,max,mode1,i;
int1 do_F;
void convert_bcd(int8 x);
void bao_dong();
void test();
//‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
void main()
{

 float value;
  on_off =1;
  min    =15;   //nhiet do min default
  max    =35;   //nhiet do max default
  do_F   =0 ;
  i = 50 ;
  mode   =0 ;
  mode1 = 0 ;
   trisa = 0xFF;
   trisb = 0x01;
   trisd = 0x00;
      LCD_init();
      Printf(LCD_putchar,ʺLop DT8 ‐ BKHNʺ);
      LCD_putcmd(0xC0);
      Printf(LCD_putchar,ʺKhoi tao...ʺ);
// Khoi tao cho ngat ngoai
      enable_interrupts (INT_EXT);
      ext_int_edge(H_TO_L);
      enable_interrupts (GLOBAL);
// Khoi tao che do cho bo ADC
      setup_adc_ports(AN0);
      setup_adc(ADC_CLOCK_INTERNAL);
      delay_us(10);
// Lay mau nhiet do lan dau tien
      value=(float)read_adc();
      value = (value ‐ 558.5)/2.048;        // For 5V supply
      //    value = (value ‐ 754.8)/2.048;  // For 3.7V Supply
      //    value = (value ‐ 698.2)/2.048;  // For 4V supply
      convert_bcd((int8)value);  // Tach so tram, chuc, donvi de hien thi len LED 7
      delay_ms(1000);
      LCD_putcmd(0xC0);
      Printf(LCD_putchar,ʺKhoi tao xongʺ);
      while(1)
      {
       if (i==50)
          {
            value = read_adc();

 value=(value‐558.5)/2.048;
            if (do_F==1) value=1.8*value+32;
            convert_bcd((int8)value);
            printf(ʺ\n\rNhiet do phong: %uʺ,value);// Gui gia tri len may tinh
            LCD_putcmd(0xC0);
            printf(LCD_putchar,ʺ  Temp = ʺ);
            LCD_putchar(high); LCD_putchar(low);
            if (do_F==0) printf(LCD_putchar,ʺ Cʺ);
            else printf(LCD_putchar,ʺ Fʺ);
            i=0;
          }
       i++;
       if(((int8)value > 40) || ((int8)value < 15)) on_off=1;
       else
        {
         on_off = 0;
         LCD_Putcmd(0xCF);
         LCD_putchar(ʺ ʺ);
         blink=0;
        }
       if (on_off==1)
       {
       if (blink==0) {
LCD_Putcmd(0xCF);LCD_putchar(ʺ!ʺ);blink=1;delay_ms(250);}
       else          {LCD_Putcmd(0xCF);LCD_putchar(ʺ ʺ);blink=0;delay_ms(250);}
       }
     }
   }//end main‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
#INT_EXT
void test()
{
   if (do_F == 1) do_F=0;
   else          do_F=1;
}
void convert_bcd(int8 x)
  {
   low=x%10;  //chia lay phan du, so hang don vi

 high=x/10;   //tach hang tram va hang chuc
   low = low + 0x30;
   high = high + 0x30;
  }
void bao_dong(){
int8 i;
if (blink == 0) blink = 1;
else            blink=0;
     for(i=0;i<50;i++)
     {
      LCD_Putcmd(0xCF);
      if (blink==0) LCD_putchar(ʺ!ʺ);
      else         LCD_putchar(ʺ ʺ);
     }
}

Dưới đây là một sơ đồ dùng PIC và LM335 để đo nhiệt độ, hiển thị trên LCD. Trong chương trình bạn thấy có hàm chuyển đổi nhiệt độ từ ía trị độ K về độ C. Nguyên nhân có hàm đó là do con LM335 thay đổi 10mV/K, ta cần hiển thị là độ C. Nhận thấy 0oC = 273K, như vậy tại 0oC con LM335 sẽ xuất ra một điện áp là 2.73V và với điện áp này, ADC trong PIC sẽ cho giá trị số là:  (2.73*1023)/5 = 558 . 5585 . Như vậy khi tính toán giá trị nhiệt độ ta cần trừ đi giá trị 558.558 này. Công thức đầy đủ là:
 Do_C= [(adc_value)- 558.558] / 2.048
Giá trị 2.048 có là do ta dùng ADC 10‐bit, điện áp lấy mẫu là 5V, như vậy mỗi mức lượng tử sẽ tương ứng với  5V/1024 = 4.883mV.
LM335 thay dổi 10mV/K do đó ứng với sụ thay đổi 1 độ C sẽ thay đổi 2.048 mức lượng tử (10mV/4.883mV = 2.048). Công thức trên là cho ADC 10‐bit, với các bộ ADC 8‐bit hay 12‐bit việc tính toán chuyển đổi giá trị cũng tương tự.
 Mạch đo nhiệt độ LM335 hiển thị trên LCD 16x2


Việc giao tiếp giữa Vi điều khiển và máy tính là bài lập trình khá quan trọng khi ta làm việc với các dòng Vi điều khiển khác nhau. Với Vi điều khiển PIC cũng vậy, trong mỗi IC PIC đều có tích hợp một khối giao tiếp máy tính USART. Ta sử dụng khối giao tiếp này để truyền dữ liệu lên máy tính và xử lý dữ liệu đó tùy vào mục đích của người lập trình. Để nhận dữ liệu do Vi điều khiển truyền lên máy tính ta có thể sử dụng các phần mềm giao tiếp COM có sẵn hay viết một chương trình mới, sử dụng các ngôn ngữ lập trình như C++, VB hay Delphi… Trong chương trình ví dụ dưới đây tôi sử dụng công cụ sẵn có của CCS là Serial Port Monitor để truyền và nhận dữ liệu từ PIC.
Sơ đồ mạch điện ORCAD. Mạch sử dụng IC MAX232 để kết nối đến cổng COM của
máy tính. Mạch đơn giản chỉ nhằm mục đích giới thiệu khối giao tiếp máy tính của PIC và
cách lập trình cho nó trong CCS.
Trong chương trình ta có sử dụng hàm xử lý ngắt nối tiếp để xử lý ký tự nhân được từ máy
tính. Khi có ngắt xảy ra, ta gọi hàm getc() sẽ trả về ký tự vừa nhận được. Trên màn hình LCD
sẽ hiển thị ký tự mà ta gõ từ bàn phím máy tính.


Code mẫu cho PIC - Truyền thông nối tiếp RS232
 Mạch giao tiếp máy tính, hiển thị LCD
[success title="MÃ NGUỒN CHƯƠNG TRÌNH" icon="check-circle"]

Mã nguồn chương trình: 

#include <16f877a.h> 
#include <def_877a.h> 
#use delay(clock=20000000) 
#FUSES  NOWDT,  HS,  NOPUT,  NOPROTECT,  NODEBUG,  NOBROWNOUT, 
NOLVP, NOCPD, NOWRT 
// Khai báo sử dụng giao tiếp nối tiếp RS232 
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9) 

#include <lcd_lib_4bit.c> 

int8 count=0; 
char string_in[16]; 

#INT_RDA  // Hàm xử lý ngắt nối tiếp 
Receive_isr() { 
char c; 
int8 i; 
count++; 
c = getc(); 
putc(c); 
if (c==ʹcʹ | c==ʹCʹ) 
   { 
      LCD_putcmd(0x01);    //Clear Screen 
      c=ʹcʹ; 
      count=0; 
   } 
if ((count<=16) && (c!=ʹcʹ))  LCD_putchar(c); 
if (count > 16) 
   { 
      count=0; 
      LCD_putcmd(0xC0); 
   } 
void main() 
{
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
lcd_init(); // Khởi tạo cho LCD
lcd_putcmd(0x01);
lcd_putcmd(line_1);
printf(ʺEnter a String.ʺ);
printf(ʺOr anything you want!ʺ);
while (1) {}
} [/success]
Mô tả chương trình: Trên đây là chương trình giao tiếp với máy tính, ta thấy trong CCS để sử dụng giao tiếp nối tiếp ta chỉ cần khai báo #use rs232(). Các hàm giao tiếp với máy tính mà CCS hỗ trợ là:
‐  putc(char ky_tu) : Gửi một ký tự ASCII lên máy tính
‐  getc() : Hàm trả về một ký tự nhận được từ máy tính
‐  printf(string): hàm gửi một chuỗi ký tự lên máy tính

Trong Vi điều khiển PIC có nhiều nguồn ngắt. Để biết cụ thể ta có thể vào mục View >> Valid Interrupts . Khi đó một của sổ sẽ hiện ra liệt kê đầy đủ các nguồn ngắt của từng con PIC.

 Các nguồn ngắt trong PIC


Để viết một hàm phục vụ ngắt ta chỉ việc thêm khai báo #INT_tên_ngắt vào 
trước hàm phục vụ cho ngắt đó. Khi đó trình dich sẽ hiểu đó là địa chỉ hàm cho 
ngắt, khi có ngắt tương ứng xảy ra thì nó sẽ nhảy đến vị trí đó . Lấy ví dụ khi ta muốn xử lý ngắt ngoài, hàm sẽ được viết như sau:

#INT_EXT 
Ext_isr() 
// Nhập mã tại đây 
}




Dưới đây là chương trình nháy led theo nhiều kiểu khác nhau, sử dụng 1 phím bấm nối với chân ngắt ngoài RB0 để chọn kiểu nháy. Có 8 kiểu nháy LED khác nhau, Khi đến kiểu nháy thứ 8, nếu ta nhấn thì sẽ trở về chế độ ban đẩu. Ban đầu biến mode = 0 và tất cả các LED đều tắt Mỗi khi nhấn phím bấm, biến mode sẽ tăng lên 1 đơn vị. Giá trị biến mode tương ứng với chương trình nháy được thực hiện. Khi mode = 9 thì sẽ được gán về mode = 0. Các kiểu nháy khác nhau là do ta bật tắt các LED trên cổng D theo các cách khác nhau. Lấy ví dụ khi ta muôn các LED nháy xen kẽ nhau ta chỉ việc gửi ra cổng D giá trị AAh (10101010) và 55h (01010101).
 Nháy LED nhiều chế độ dùng Ngắt

Mã nguồn chương trình: 

#include <16F877A.h> 
#include <def_877a.h> 
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, 
NOLVP, NOCPD, NOWRT 
#use delay(clock=20000000) 

int8 mode,i; 
byte temp; 



#INT_EXT
EXT_ISR() {

mode++;
if (mode==9) mode = 0;
}
// End of INT

void program1();
void program2();
void program3();
void program4();
void program5();
void program6();
void program7();
void program8();

void main() {

   trisd = 0x00;
   trisb = 0xFF;
   portd=0xff;
   enable_interrupts(int_EXT);
   ext_int_edge(H_TO_L);  // Chọn ngắt theo sườn âm
   enable_interrupts(GLOBAL);
   mode = 0;
while (1) {
   switch(mode) {
      case 1: program1(); break;
      case 2: program2(); break;
      case 3: program3(); break;
      case 4: program4(); break;
      case 5: program5(); break;
      case 6: program6(); break;
      case 7: program7(); break;
      case 8: program8(); break;
   }
}
}

void program1() {

 PortD = 0x00;
   delay_ms(250);
   Portd = 0xFF;
   delay_ms(250);
}
void program2() { // LED sáng chạy từ trái qua phải
   temp = 0xFF;
   for (i=0;i<=8;i++) {
      portd = temp;
      delay_ms(250);
      temp >>= 1;
   }
}
void program3() { // LED sáng chạy từ phải qua trái
    temp = 0xFF;
   for (i=0;i<=8;i++) {
      portd = temp;
      delay_ms(250);
      temp <<= 1;
   }
}
void program4() {
   portd = 0xAA;
   delay_ms(500);
   portd = 0x55;
   delay_ms(500);
}
void program5() {
   Portd = 0x7E;   delay_ms(150);
   Portd = 0xBD;   delay_ms(250);
   Portd = 0xDB;   delay_ms(150);
   Portd = 0xE7;   delay_ms(150);
   Portd = 0xDB;   delay_ms(150);
   Portd = 0xBD;   delay_ms(150);
   Portd = 0x7E;   delay_ms(150);
}
void program6() {
  temp = 0xFF;
   for (i=0;i<=8;i++) {
      portd = temp;
      delay_ms(250);

 temp = temp >> 1;
   }
}
void program7() {

   Portd = 0xFE;   delay_ms(150);
   Portd = 0xFD;   delay_ms(150);
   Portd = 0xFB;   delay_ms(150);
   Portd = 0xF7;   delay_ms(150);
   Portd = 0xEF;   delay_ms(150);
   PortD = 0xDF;   delay_ms(150);
   Portd = 0xBF;   delay_ms(150);
   Portd = 0x7F;   delay_ms(150);
}

void program8() {
   Portd = 0x7F;   delay_ms(150);
   Portd = 0xBF;   delay_ms(150);
   PortD = 0xDF;   delay_ms(150);
   Portd = 0xEF;   delay_ms(150);
   Portd = 0xF7;   delay_ms(150);
   Portd = 0xFB;   delay_ms(150);
   Portd = 0xFD;   delay_ms(150);
   Portd = 0xFE;   delay_ms(150);
}
Phạm Văn Ngọc Anh- 01644326695

Chương trình thực hiện đo nhiệt độ, điện áp, hiển thị kết quả lên màn hình LCD 16x2, và truyền giá trị lên máy tính.
Mô phỏng trên Proteus:


Code mẫu cho PIC - Kết hợp: ADC đo nhiệt độ, điện áp, hiển thị LCD và giao tiếp với máy tính
mô phỏng trên Proteus

Sơ đồ nguyên lý:


Sơ đồ nguyên lý


[success title="Mã nguồn" icon="check-circle"]
#include "16f877a.h"
#include "def_877a.h"
#device *=16 ADC=10
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include "lcd_lib_4bit.c"
//=======================================================================
void send(int8 a);
void HIENTHI_LCD(int8 t);
void HIENTHI_LCD_float(int8 t);
int8 count=0;
int8 i,value,vl[10];
//=======================================================================
#INT_RDA //ngat khi nhan du lieu.
Receive_isr()
{
   char c;
   c=getc();
   switch(c)
   {
      case '0':   //xoa man hinh LCD
      {
               LCD_putcmd(0x01);
      }
      break;
          //o day co the su dung ma thap phan! (ngoai tru cac ky tu dieu khien)
      case '-':   //lui con tro hien thi LCD 1 don vi.
      {
               LCD_putcmd(0x10);
      }
      break;
      case '1':   //truyen len may tinh: gia tri do duoc.
      {
         Set_ADC_channel(0);  //kenh 0 chan so2
         delay_us(10);
         for(i=0;i<10;i++)
         {
               vl[i]=read_adc();
               delay_us(10);
         }
         value=(vl[0]+vl[1]+vl[2]+vl[3]+vl[4]+vl[5]+vl[6]+vl[7]+vl[8]+vl[9])/20.48;
         send(value);
      }
      break;
      case '2':   //truyen len may tinh: gia tri do duoc.
      {
         Set_ADC_channel(1);  //kenh 1 chan so3
         delay_us(10);
         if(read_adc()==0)
         {
               for(i=0;i<10;i++)
               {
                     vl[i]=read_adc();
                     delay_us(10);
               }
               value=(vl[0]+vl[1]+vl[2]+vl[3]+vl[4]+vl[5]+vl[6]+vl[7]+vl[8]+vl[9])/10;
         }
         else
         {
               value=read_adc()+6;
               for(i=0;i<10;i++)
               {
                     vl[i]=read_adc()+6;
                     delay_us(10);
               }
               value=(vl[0]+vl[1]+vl[2]+vl[3]+vl[4]+vl[5]+vl[6]+vl[7]+vl[8]+vl[9])/10;
         }
         send(value);
      }
      break;
      case '9':   //thoat khoi ham ngat, cho ADC làm viec.
      {
            count=0;   //ket thuc viec truyen ky tu len LCD
            LCD_putcmd(0x01);
      }
      break;
      default : //truyen ky tu xuong LCD ^^.
      {
               count++;
               if(count==1) LCD_putcmd(0x01);
               if(count==16) LCD_putcmd(0xC0);
               if(count==32)
               {
                  LCD_putcmd(0x01);
                  count=0;
               }
               LCD_putchar(c);
      }  
    }
}
//=======================================================================
void main()
{
   //trisD=0x0C; //D0,D1 LA CONG VAO, D2-D7 LA CONG RA.

   enable_interrupts(int_rda); //cho phep ngat noi tiep nhan.
   enable_interrupts(GLOBAL);


   LCD_init(); //Khoi tao LCD.
   LCD_putcmd(0xC0);
   Printf(LCD_putchar,"Khoi tao...");
   delay_ms(250);

   setup_adc_ports(AN0_AN1_AN3);   //Khoi tao che do cho bo ADC.
   setup_adc(ADC_CLOCK_INTERNAL);
   delay_us(10);

   while(1)
   {
      //do nhiet do
      {
         Set_ADC_channel(0);  //kenh 0 chan so2
         delay_us(10);
         value=read_adc();
         value=value/2.048;
     
         LCD_putcmd(0x80);
         LCD_putchar("Nhiet do: ");
         LCD_putcmd(0x89);
         HIENTHI_LCD(value);
         LCD_putcmd(0x8C);
         LCD_putchar("oC");
         delay_ms(0.1);
      }
      //do diep ap
      {
         Set_ADC_channel(1);  //kenh 1 chan so3
         delay_us(10);
         if(read_adc()==0)
         {
               for(i=0;i<10;i++)
               {
                     vl[i]=read_adc();
                     delay_us(10);
               }
               value=(vl[0]+vl[1]+vl[2]+vl[3]+vl[4]+vl[5]+vl[6]+vl[7]+vl[8]+vl[9])/10;
         }
         else
         {
               value=read_adc()+6;
               for(i=0;i<10;i++)
               {
                     vl[i]=read_adc()+6;
                     delay_us(10);
               }
               value=(vl[0]+vl[1]+vl[2]+vl[3]+vl[4]+vl[5]+vl[6]+vl[7]+vl[8]+vl[9])/10;
         }

         LCD_PutCmd(0xC0);
         LCD_putchar("DIEN AP : ");
         LCD_putcmd(0xC9);
         //HIENTHI_LCD(value);
         HIENTHI_LCD_float(value);
         LCD_putcmd(0xCD);
         LCD_putchar("V ");
      }
   }
}
//=======================================================================
void HIENTHI_LCD(int8 t)
{
     unsigned char v;
     if(t<10)
          LCD_putchar(t+48);
     else
     if(t<100)
     {
          LCD_putchar(t/10+48);
          LCD_putchar(t%10+48);
     }
     else
     {
         v=t/10;
         LCD_putchar(v/10+48);
         LCD_putchar(v%10+48);
         LCD_putchar(t%10+48);
     }
}
void send(int8 a)
{
    if(a<10)
     {
         putc(a+48);    
     }
     if(a>9&&a<100)
     {
          unsigned char c=a/10;
          unsigned char d=a%10;
          putc(c+48);
          putc(d+48);  
     }
     if(a>99)
     {
          unsigned char t=a/100;
          unsigned char c=a/10-10*t;
          unsigned char d=a%10;
          putc(t+48);
          putc(c+48);
          putc(d+48);
     }
}
void HIENTHI_LCD_float(int8 t)
{
     int8 v;
     if(t<10)
     {
          LCD_putchar(48);
          LCD_putchar(46);
          LCD_putchar(t+48);
          LCD_putchar(32);
     }
     else
     if(t<100)
     {
          LCD_putchar(t/10+48);
          LCD_putchar(46);
          LCD_putchar(t%10+48);
          LCD_putchar(32);
     }
     else
     {
         v=t/10;
         LCD_putchar(v/10+48);
         LCD_putchar(v%10+48);
         LCD_putchar(46);
         LCD_putchar(t%10+48);
     }
}
/*
void send_float(float a)
{
    if(a<10)
     {
         putc(a+48);    
     }
     if(a>9&&a<100)
     {
          unsigned char c=a/10;
          unsigned char d=a%10;
          putc(c+48);
          putc(d+48);  
     }
     if(a>99)
     {
          unsigned char t=a/100;
          unsigned char c=a/10-10*t;
          unsigned char d=a%10;
          putc(t+48);
          putc(c+48);
          putc(d+48);
     }
}*/
//=======================================================================[/success]

Giao tiếp SPI song công giữa 2 PIC: PIC Master ở trên truyền dữ liệu từ PortB (công tắc trên) qua PIC Slave ở dưới để hiển thị ra PortD (LED dưới) , PIC Slave cũng lấy dữ liệu từ PortB (công tắc dưới) của mình, truyền qua PIC Master để hiển thị ra PortD (LED trên).

Chương trình chạy mô phỏng trên ISIS - Proteus:

mô phỏng SPI trên Proteus


Mã nguồn:

Code Master:


#include "16f877a.h"
#include "def_877a.h"
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=38400,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#use fast_io(B)
#use fast_io(D)
#use fast_io(A)
#define REG_Write 0x80

#INT_SSP
void spi()
{
      PORTD=spi_read(PORTB);
      delay_ms(10);
}
void main()
{
   port_b_pullups(TRUE);
   setup_spi(spi_master|spi_l_to_h|spi_clk_div_16);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   SET_TRIS_B(0xff);
   SET_TRIS_D(0x00);
   SET_TRIS_A(0x00);
   while(1)
   {
   delay_ms(100);
      output_low(PIN_A5);//Chân C2 dùng Select chip.
      delay_ms(10);//Tao tre de Slave chuan bi.
      spi_write(PORTB);
      output_high(PIN_A5);
   }
}


Code Slave:



#include "16f877a.h"
#include "def_877a.h"
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use rs232(baud=38400,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#use fast_io(B)
#use fast_io(D)

#INT_SSP
void spi()
{
      PORTD=spi_read(PORTB);//Vua nhan vua truyen.
      delay_ms(10);
}

void main()
{
   port_b_pullups(TRUE);
   setup_spi(spi_slave|spi_l_to_h|spi_clk_div_16);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   TRISB=0xff;
   TRISD=0x00;
   while(1)
   {
   }
}

Phạm Văn Ngọc Anh- 01644326695

.
Tham khảo thêm: Hướng dẫn - IC thời gian thực DS1307

Chương trình thực hiện giao tiếp I2C giữa PIC 16F877A và IC DS1307 để cài đặt thời gian, đọc thời gian từ DS1307, hiển thị lên LCD, truyền qua RS232.
Với LCD, chương trình sẽ đọc dữ liệu DS1307 và cập nhật LCD liên tục, còn khi truyền lên máy tính sẽ dựa vào ngắt RB0 đưa vào từ xung 1Hz của DS1307, tức là mỗi 1s sẽ truyền dữ liệu 1 lần.
Trong chương trình có sử dụng các thư viện: lcd_lib_4bit.cds1307.c.

Sơ đồ nguyên lý mô phỏng trên Proteus:



Truyền lên hyper terminal:



Mã nguồn chương trình chính:



#include "16f877a.h"
#include "def_877a.h"

#device *=16 ADC=10
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use i2c(Master, sda = PIN_C4, scl=PIN_C3)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include "lcd_lib_4bit.c"
#include "ds1307.c"

#define Slave_add 0x68
#define Read 1
#define Write 0

void send(int8 a);

int8 sec,min,hrs,day,month,yr,dow;

//ngat o chan RB0: Truyen len cong RS232
#int_EXT
void EXT_isr(void) //moi 1s truyen len may tinh 1 lan
{
   ds1307_get_date(day,month,yr,dow); 
   ds1307_get_time(hrs,min,sec);
   send(hrs);
   putc(45);
   send(min);
   putc(45);
   send(sec);
   putc(10);
   return;
}
void main()
{
   enable_interrupts(INT_EXT);//cho phep ngat RB0
   ext_int_edge(0,H_TO_L);//dat suon ngat
   enable_interrupts(GLOBAL);//cho phep ngat toan cuc
   
   LCD_init(); //Khoi tao LCD.
   delay_ms(10);
   ds1307_init();// khoi tao DS1307, tao xung 1Hz o chan 7 DS1307.
   // Set date : 12-4-2012
   // Set time : thu 5 - 12 gio, 59 phút 10 giây
   ds1307_set_date_time(12,4,12,5,12,59,10);
   

   while(1) 
   { 
      ds1307_get_date(day,month,yr,dow); 
      ds1307_get_time(hrs,min,sec);
      
      //Truyen len LCD
      //o day chi hien gio, phut, giay. cac thong tin khac thuc hien tuong tu.
      LCD_PutCmd(0x80);
      LCD_PutChar(hrs/10+48);
      LCD_PutChar(hrs%10+48);
      LCD_PutChar(45);
      LCD_PutChar(min/10+48);
      LCD_PutChar(min%10+48);
      LCD_PutChar(45);
      LCD_PutChar(sec/10+48);
      LCD_PutChar(sec%10+48);
   }
}
void send(int8 a)
{
    if(a<10)
     {
         putc(a+48);         
     }
     if(a>9&&a<100)
     {
          unsigned char c=a/10;
          unsigned char d=a%10;
          putc(c+48);
          putc(d+48);       
     }
     if(a>99)
     {
          unsigned char t=a/100;
          unsigned char c=a/10-10*t;
          unsigned char d=a%10;
          putc(t+48);
          putc(c+48);
          putc(d+48);
     }
}


Thư viện lcd_lib_4bit.c:


#include <stddef.h>

#define LCD_RS          PIN_D2
//#define LCD_RW          PIN_A1
#define LCD_EN          PIN_D3

#define LCD_D4          PIN_D4
#define LCD_D5          PIN_D5
#define LCD_D6          PIN_D6
#define LCD_D7          PIN_D7

// misc display defines-
#define Line_1          0x80
#define Line_2          0xC0
#define Clear_Scr       0x01

// prototype statements
#separate void LCD_Init ( void );// ham khoi tao LCD
#separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
#separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
#separate void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD
#separate void LCD_PulseEnable ( void );// Xung kich hoat
#separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data
// D/n Cong
#use standard_io (C)
#use standard_io (D)

//khoi tao LCD**********************************************
#separate void LCD_Init ( void )
    {
    LCD_SetData ( 0x00 );
    delay_ms(200);       /* wait enough time after Vdd rise >> 15ms */
    output_low ( LCD_RS );// che do gui lenh
    LCD_SetData ( 0x03 );   /* init with specific nibbles to start 4-bit mode */
    LCD_PulseEnable();
    LCD_PulseEnable();
    LCD_PulseEnable();
    LCD_SetData ( 0x02 );   /* set 4-bit interface */
    LCD_PulseEnable();      /* send dual nibbles hereafter, MSN first */
    LCD_PutCmd ( 0x2C );    /* function set (all lines, 5x7 characters) */
    LCD_PutCmd ( 0x0C );    /* display ON, cursor off, no blink */
    LCD_PutCmd ( 0x06 );    /* entry mode set, increment & scroll left */
    LCD_PutCmd ( 0x01 );    /* clear display */
    }

#separate void LCD_SetPosition ( unsigned int cX )
    {
    /* this subroutine works specifically for 4-bit Port A */
    LCD_SetData ( swap ( cX ) | 0x08 );
    LCD_PulseEnable();
    LCD_SetData ( swap ( cX ) );
    LCD_PulseEnable();
    }

#separate void LCD_PutChar ( unsigned int cX )
    {
    /* this subroutine works specifically for 4-bit Port A */
        output_high ( LCD_RS );
        LCD_PutCmd( cX );
        output_low ( LCD_RS );
    }

#separate void LCD_PutCmd ( unsigned int cX )
    {
    /* this subroutine works specifically for 4-bit Port A */
    LCD_SetData ( swap ( cX ) );     /* send high nibble */
    LCD_PulseEnable();
    LCD_SetData ( swap ( cX ) );     /* send low nibble */
    LCD_PulseEnable();
    }
#separate void LCD_PulseEnable ( void )
    {
    output_high ( LCD_EN );
    delay_us ( 3 );         // was 10
    output_low ( LCD_EN );
    delay_ms ( 3 );         // was 5
    }

#separate void LCD_SetData ( unsigned int cX )
    {
    output_bit ( LCD_D4, cX & 0x01 );
    output_bit ( LCD_D5, cX & 0x02 );
    output_bit ( LCD_D6, cX & 0x04 );
    output_bit ( LCD_D7, cX & 0x08 );
    }

Thư viện ds1307.c:


BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void) 

   BYTE initsec = 0;
   BYTE initmin=0;
   BYTE inithr=0;                  
   BYTE initdow=0;
   BYTE initday=0;                   
   BYTE initmth=0;
   BYTE inityear=0;
   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_start(); 
   i2c_write(0xD1);      // RD from RTC 
   initsec  = bcd2bin(i2c_read() & 0x7f); 
   initmin  = bcd2bin(i2c_read() & 0x7f); 
   inithr   = bcd2bin(i2c_read() & 0x3f); 
   initdow  = bcd2bin(i2c_read() & 0x7f);   // REG 3 
   initday  = bcd2bin(i2c_read() & 0x3f);   // REG 4 
   initmth  = bcd2bin(i2c_read() & 0x1f);   // REG 5 
   inityear = bcd2bin(i2c_read(0));         // REG 6 
   i2c_stop(); 
   delay_us(3);

   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x00);      // REG 0 
   i2c_write(bin2bcd(initsec));      // Start oscillator with current "seconds value 
   i2c_write(bin2bcd(initmin));      // REG 1 
   i2c_write(bin2bcd(inithr));       // REG 2 
   i2c_write(bin2bcd(initdow));      // REG 3 
   i2c_write(bin2bcd(initday));      // REG 4 
   i2c_write(bin2bcd(initmth));      // REG 5 
   i2c_write(bin2bcd(inityear));     // REG 6 
   i2c_start(); 
   i2c_write(0xD0);      // WR to RTC 
   i2c_write(0x07);      // Control Register 
   i2c_write(0x90);      //  squarewave output pin 1Hz
   i2c_stop(); 



void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);              // I2C write address
  i2c_write(0x00);              // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));      // REG 0
  i2c_write(bin2bcd(min));      // REG 1
  i2c_write(bin2bcd(hr));       // REG 2
  i2c_write(bin2bcd(dow));      // REG 3
  i2c_write(bin2bcd(day));      // REG 4
  i2c_write(bin2bcd(mth));      // REG 5
  i2c_write(bin2bcd(year));     // REG 6
  i2c_write(0x90);              // REG 7 - 1Hz squarewave output pin
  i2c_stop();
}

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);              // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));         // REG 6
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);                     // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));




Author Name

{picture https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN0PUWA2genMqX3Sm26mBTX_30OJgDenoIi4K6BR-E1vl3nI7LALp0X759QZgzqrMcGBB7jEbdZnubJbp4n2ZZ22KT196CWCg9DLs3MfEivocdmkjZEPEn-A42hyphenhyphen9dmsca0VIDQr_LjqM/s512-Ic42/pham-van-ngoc-anh.jpg}

Tôi là Ngọc Anh. Tôi đến từ Nghệ An. Tôi tốt nghiệp một trường đại học tại Sài Gòn. Hiện tôi đang phát triển công ty riêng. Liên lạc với tôi qua:

{facebook https://www.facebook.com/phamvanngocanh}
{twitter https://twitter.com/nghiphong1993}
{google https://plus.google.com/+dientuchiase/posts}
{youtube https://www.youtube.com/channel/UCeJKhA_goBNFmDw6RKNtmYQ}

Biểu mẫu liên hệ

Tên

Email *

Thông báo *

Được tạo bởi Blogger.