Tải bản đầy đủ (.docx) (18 trang)

điều khiển led matrix bằng hồng ngoại

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (327.03 KB, 18 trang )

Báo Cáo
Đồ Án Hệ Thống Nhúng

Lớp D11XLTH
Thành viên: Nguyễn anh văn
Trần văn thịnh
Nguyễn minh hoàng
Nguyễn đức thuật

Điều Khiển Led Matrix Bằng Hồng Ngoại
I.Giới thiệu chung
Ngày nay công nghệ ngày càng phát triển và quảng cáo cũng là một trong những lĩnh
vực hàng đầu của cuộc sống.Các biển quảng cáo bằng led matrix có ở khắp mọi nơi trên thế
giới.Vì vậy để đảm bảo sự tiện lợi trong việc điều khiển các biển quảng cáo này một cách
nhanh nhất công nghệ điều khiển từ xa bằng hồng ngoại là một trong những giải pháp để
giải quyết vấn đề này .
II.Cấu tạo chi tiết
A.Ma trận led
Ma trận LED tức Dot Matrix LED là tập hợp nhiều đèn LED được bố trí thành dạng
“ma trận” hình chữ nhật hoặc vuông với số hàng là a và số cột là b. Ma trận LED được dùng
rất nhiều trong các ứng dụng hiển thị như các biển quảng cáo, hiển thị thay thế LCD hoặc
thậm chí dùng hiển thị video…Để giảm số lượng các đường điều khiển, trong các ma trận
LED các LED được nối chung với nhau theo hàng và cột. Số lượng LED trên ma trận LED là
axb trong khi số lượng ngõ ra bằng tổng số hàng và cột: a + b. Việc điều khiển 1 ma trận LED
kích thước lớn đòi hỏi thiết kế một mạch driver và điều khiển rất phức tạp. Với mục đích
giúp bạn đọc làm quen khái niệm ma trận LED, trong phạm vi bài này tôi chỉ trình bày thao
tác với 1 ma trận LED có kích thước 7x5 (7 hàng, 5 cột). ma trận LED 7x5 thường được dùng
để hiển thị các ký tự trong bảng mã ASCII thay cho Text LCD. Tuy nhiên, bạn có thể ghép các
ma trận LED này lại để hiển thị các loại hình ảnh bất kỳ có độ phân giải thấp.



Bên trong các ô của ma trận LED là các LED phát sang. Cathod (cực âm) của các LED
trên mỗi hàng được nối chung với nhau và ngõ ra chung là các ngõ D (Data). Các Anod của
các LED trên mỗi cột được nối chung tạo thành các đường C (Control). Thông thường, các
đường D và C được chọn sao số số lượng đường D nhiều hơn đường C hoặc sao cho số
lương các đường D gần nhất với số 8, 16, 32…(lũy thừa của 2). Lý do của việc chọn này nhằm
giảm kích thước bộ font chứa các ký tự hoặc hình ảnh hiển thị lên ma trận LED, bạn sẽ hiểu


rõ hơn khi tìm hiểu các điều khiển ma trận LED 7x5 bên dưới.

B.Khái niệm về hồng ngoại
1.1 Ánh sáng hồng ngoại là ánh sáng không thể nhìn thấy bằng mắt thường có bước sóng
0.8 đến 0.9 um có vận tốc truyền bằng vận tốc ánh sáng.Tia hồng ngoại có thể truyền đi
được nhiều kênh tín hiệu .Tia hồng ngoại dễ hấp thụ ,khả năng xuyên thấu kém.Trong điều
kiện từ xa trùm tia hồng ngoại phát đi hẹp, có hướng do đó khi thu phải đúng hướng.
1.2 Mạch thu phát hồng ngoại
a.Mạch thu


b.Mạch phát

1.3 Nguyên lý thu phát hồng ngoại
Việc thu hoặc phát bức xạ hồng ngoại bằng nhiều phương tiện khác nhau, có thể
nhận tia hồng ngoại từ ánh sáng mặt trời. Nhiều thứ có thể phát tia hồng ngoại như: lò bức
xạ, lò điện, đèn, cơ thể người,… Để có thể truyền tia hồng ngoại tốt phải tránh xung nhiễu
bắt buộc phải dùng mã phát và nhận ổn định để xác định xem đó là xung truyền hay
nhiễu.Tần số làm việc tốt nhất từ 30 KHz đến 60 KHz, nhưng thường sử dụng khoảng 36 KHz.
Ánh sáng hồng ngoại truyền 36 lần/1s khi truyền mức 0 hay mức .
Dùng tần số 36 KHz để truyền tín hiệu hồng ngoại thì dễ, nhưng khó thu và giải mã phải sử
dụng bộ lọc để tín hiệu ngõ ra là xung vuông, nếu ngõ ra có xung nghĩa là đã nhận được tín

hiệu ở ngõ vào


a.Phần phát

Khối chọn chức năng và khối mã hóa: Khi người sử dụng bấm vào các phím chức
năng để phát lệnh yêu cầu của mình, mổĩ phím chức năng tương ứng với một số thập phân.
Mạch mã hóa sẽ chuyển đổi thành mã nhị phân tương ứng dưới dạng mã lệnh tín hiệu số
gồm các bít 0 và 1. Số bit trong mã lệnh nhị phân có thể là 4 bit hay 8 bit… tùy theo số lượng
các phím chức năng nhiều hay ít.
-Khối dao động có điều kiện: Khi nhấn 1 phím chức năng thì dồng thời khởi động mạch dao
động tạo xung đồng hồ, tần số xung đồng hồ xác định thời gian chuẩn của mỗi bit.
-Khối chốt dữ liệu và khối chuyển đổi song song ra nối tiếp: Mã nhị phân tại mạch mã hóa sẽ
được chốt để đưa vào mạch chuyển đổi dữ liệu song song ra nối tiếp. Mạch chuyển đổi dữ
liệu song song ra nối tiếp được điều khiển bởi xung đồng hồ và mạch định thời nhằm đảm
bảo kết thúc đúng lúc việc chuyển đổi đủ số bit của một mã lệnh.
-Khối điều chế và phát FM: mã lệnh dưới dạng nối tiếp sẽ được đưa qua mạch điều chế và
phát FM để ghép mã lệnh vào sóng mang có tần số 38Khz đến 100Khz, nhờ sóng mang cao
tần tín hiệu được truyền đi xa hơn, nghĩa là tăng cự ly phát.
-Khối thiết bị phát : là một LED hồng ngoại. Khi mã lệnh có giá trị bit
=’1’ thì LED phát hồng ngoại trong khoảng thời gian T của bit đó. Khi mã lệnh có giá trị
bit=’0’ thì LED không sáng. Do đó bên thu không nhận được tín hiệu xem như bit = ‘0’ .
b.Phần thu


Khối thiết bị thu: Tia hồng ngoại từ phần phát được tiếp nhận bởi LED thu hồng ngoại hay
các linh kiện quang khác.
- Khối khuếch đại và Tách sóng: trước tiên khuếch đại tính hiệu nhận rồi
đưa qua mạch tách sóng nhằm triệt tiêu sóng mang và tách lấy dữ liệu cần thiết là mã lệnh.
- Khối chuyển đổi nối tiếp sang song song và Khối giải mã: mã lệnh

được đưa vào mạch chuyển đổi nối tiếp sang song song và đưa tiếp qua khối giải mã ra
thành số thập phân tương ứng dưới dạng một xung kích tại ngõ ra tương ứng để kích mở
mạch điều khiển.
- Tần số sóng mang còn được dùng để so pha với tần số dao động bên
phần thu giúp cho mạch thu phát hoạt động đồng bộ, đảm bảo cho mạch tách sóng và mạch
chuyển đổi nối tiếp sang song song hoạt động chính xác.
C.Khối vi điều khiển
Giới thiệu dòng vi điều khiển STM32
Những đặc điểm nổi trội của dòng ARM Cortex đã thu hút các nhà sản xuất IC, hơn 240
dòng vi điều khiển dựa vào nhân Cortex đã được giới thiệu. Không nằm ngoài xu hướng đó,
hãng sản xuất chip ST Microelectronic đã nhanh chóng đưa ra dòng STM32. STM32 là vi điều
khiển dựa trên nền tảng lõi ARM Cortex-M3 thế hệ mới do hãng ARM thiết kế. Lõi ARM
Cortex-M3 là sự cải tiến từ lõi ARM7 truyền thống từng mang lại thành công vang dội cho
công ty ARM

Một vài đặc điểm nổi bật của STM32
ST đã đưa ra thị trường 4 dòng vi điều khiển dựa trên ARM7 và ARM9, nhưng STM32
là một bước tiến quan trọng trên đường cong chi phí và hiệu suất (price/performance), giá
chỉ gần 1 Euro với số lượng lớn, STM32 là sự thách thức thật sự với các vi điều khiển 8 và
16-bit truyền thống. STM32 đầu tiên gồm 14 biến thể khác nhau, được phân thành hai dòng:
dòng Performance có tần số hoạt động của CPU lên tới 72Mhz và dòng Access có tần số hoạt
động lên tới 36Mhz. Các biến thể STM32 trong hai nhóm này tương thích hoàn toàn về cách
bố trí chân (pin) và phần mềm, đồng thời kích thước bộ nhớ FLASH ROM có thể lên tới 512K
và 64K SRAM.
a. Sự tinh vi


Thoạt nhìn thì các ngoại vi của STM32 cũng giống như những vi điều khiển khác, như
hai bộ chuyển đổi ADC, timer, I2C, SPI, CAN, USB và RTC. Tuy nhiên mỗi ngoại vi trên đều có
rất nhiều đặc điểm thú vị. Ví dụ như bộ ADC 12-bit có tích hợp một cảm biến nhiệt độ để tự

động hiệu chỉnh khi nhiệt độ thay đổi và hỗ trợ nhiều chế độ chuyển đổi. Mỗi bộ định thời
có 4 khối capture compare (dùng để bắt sự kiện với tính năng input capture và tạo dạng
sóng ở ngõ ra với output compare), mỗi khối định thời có thể liên kết với các khối định thời
khác để tạo ra một mảng các định thời tinh vi hơn. Một bộ định thời cao cấp chuyên hỗ trợ
điều khiển động cơ, với 6 đầu ra PWM với dead time (khoảng thời gian được chèn vào giữa
hai đầu tín hiệu xuất PWM bù nhau trong điều khiển mạch cầu H) lập trình được và một
đường break input (khi phát hiện điều kiện dừng khẩn cấp) sẽ buộc tín hiệu PWM sang một
trạng thái an toàn đã được cài sẵn. Ngoại vi nối tiếp SPI có một khối kiểm tổng (CRC) bằng
phần cứng cho 8 và 16 word hỗ trợ tích cực cho giao tiếp thẻ nhớ SD hoặc MMC.
STM32 có hỗ trợ thêm tối đa 12 kênh DMA (Direct Memory Access). Mỗi kênh có thể
được dùng để truyền dữ liệu đến các thanh ghi ngoại vi hoặc từ các thanh ghi ngoại vi đi với
kích thước từ (word) dữ liệu truyền đi có thể là 8/16 hoặc 32-bit. Mỗi ngoại vi có thể có một
bộ điều khiển DMA (DMA controller) đi kèm dùng để gửi hoặc đòi hỏi dữ liệu như yêu cầu.
Một bộ phân xử bus nội (bus arbiter) và ma trận bus (bus matrix) tối thiểu hoá sự tranh chấp
bus giữa truy cập dữ liệu thông qua CPU (CPU data access) và các kênh DMA. Điều đó cho
phép các đơn vị DMA hoạt động linh hoạt, dễ dùng và tự động điều khiển các luồng dữ liệu
bên trong vi điều khiển.
STM32 là một vi điều khiển tiêu thụ năng lượng thấp và đạt hiệu suất cao. Nó có thể
hoạt động ở điện áp 2V, chạy ở tần số 72MHz và dòng tiêu thụ chỉ có 36mA với tất cả các
khối bên trong vi điều khiển đều được hoạt động. Kết hợp với các chế độ tiết kiệm năng
lượng của Cortex, STM32 chỉ tiêu thụ 2μA khi ở chế độ Standby. Một bộ dao động nội RC
8MHz cho phép chip nhanh chóng thoát khỏi chế độ tiết kiệm năng lượng trong khi bộ dao
động ngoài đang khởi động. Khả năng nhanh đi vào và thoát khỏi các chế độ tiết kiệm năng
lượng làm giảm nhiều sự tiêu thụ năng lượng tổng thể.
b. Sự an toàn
Ngày nay các ứng dụng hiện đại thường phải hoạt động trong môi trường khắc khe,
đòi hỏi tính an toàn cao, cũng như đòi hỏi sức mạnh xử lý và càng nhiều thiết bị ngoại vi tinh
vi. Để đáp ứng các yêu cầu khắc khe đó, STM32 cung cấp một số tính năng phần cứng hỗ trợ
các ứng dụng một cách tốt nhất. Chúng bao gồm một bộ phát hiện điện áp thấp, một hệ
thống bảo vệ xung Clock và hai bộ Watchdogs. Bộ đầu tiên là một Watchdog cửa sổ

(windowed watchdog). Watchdog này phải được làm tươi trong một khung thời gian xác
định. Nếu nhấn nó quá sớm, hoặc quá muộn, thì Watchdog sẽ kích hoạt. Bộ thứ hai là một
Watchdog độc lập (independent watchdog), có bộ dao động bên ngoài tách biệt với xung
nhịp hệ thống chính. Hệ thống bảo vệ xung nhịp có thể phát hiện lỗi của bộ dao động chính
bên ngoài (thường là thạch anh) và tự động chuyển sang dùng bộ dao động nội RC 8MHz.
c. Tính bảo mật
Một trong những yêu cầu khắc khe khác của thiết kế hiện đại là nhu cầu bảo mật mã
chương trình để ngăn chặn sao chép trái phép phần mềm. Bộ nhớ Flash của STM32 có thể
được khóa để chống truy cập đọc Flash thông qua cổng Debug. Khi tính năng bảo vệ đọc
được kích hoạt, bộ nhớ Flash cũng được bảo vệ chống ghi để ngăn chặn mã không tin cậy
được chèn vào bảng vector ngắt. Hơn nữa bảo vệ ghi có thể được cho phép trong phần còn
lại của bộ nhớ Flash. STM32 cũng có một đồng hồ thời gian thực và một khu vực nhỏ dữ liệu
trên SRAM được nuôi nhờ nguồn pin. Khu vực này có một đầu vào chống giả mạo (antitamper input), có thể kích hoạt một sự kiện ngắt khi có sự thay đổi trạng thái ở đầu vào này.


Ngoài ra một sự kiện chống giả mạo sẽ tự động xóa dữ liệu được lưu trữ trên SRAM được
nuôi bằng nguồn pin.
d. Phát triển phần mềm
Nếu bạn đã sử dụng một vi điều khiển dựa trên lõi ARM, thì các công cụ phát triển
cho ARM hiện có đã được hỗ trợ tập lệnh Thumb-2 và dòng Cortex. Ngoài ra ST cũng cung
cấp một thư viện điều khiển thiết bị ngoại vi, một bộ thư viện phát triển USB như là một thư
viện ANSI C và mã nguồn đó là tương thích với các thư viện trước đó được công bố cho vi
điều khiển STR7 và STR9. Có rất nhiều RTOS mã nguồn mở và thương mại và middleware
(TCP/IP, hệ thống tập tin, v.v.) hỗ trợ cho họ Cortex. Dòng Cortex-M3 cũng đi kèm với một
hệ thống gỡ lỗi hoàn toàn mới gọi là CoreSight. Truy cập vào hệ thống CoreSight thông qua
cổng truy cập Debug (Debug Access Port), cổng này hỗ trợ kết nối chuẩn JTAG hoặc giao
diện 2 dây (serial wire-2 Pin), cũng như cung cấp trình điều khiển chạy gỡ lỗi, hệ thống
CoreSight trên STM32 cung cấp hệ thống điểm truy cập(data watchpoint) và một công cụ
theo dõi (instrumentation trace). Công cụ này có thể gửi thông tin về ứng dụng được lựa
chọn đến công cụ gỡ lỗi. Điều này có thể cung cấp thêm các thông tin gỡ lỗi và cũng có thể

được sử dụng trong quá trình thử nghiệm phần mềm.
III.Ghép nối hệ thống
Sơ đồ khối

Nguyên lý hoạt động:
Khối phát hồng ngoại sử dụng một remote có chức năng phát ra tia hồng ngoại tới
mắt thu hồng ngoại.Sau đó tín hiệu từ mắt thu sẽ được gửi tới khối vi điều khiển để sử lý .từ
các chân đầu ra của vi điều khiển sẽ được ghép nối với các chân của led matrix để điều khiển
led matrix theo ý muốn bằng cách lập trình.
Code chính của vi điều khiển
#include "Matrix_driver.h"
#include "main.h"

#define A

16358

#define B

16362

int8_t target=0;
uint16_t DATA_IRF;
uint16_t Value_IR;
uint16_t last, first;
unsigned char Hang1[512] =
{


0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00,

//

H

0x00, 0x7C, 0x7E, 0x03, 0x03, 0x7E, 0x7C, 0x00,

// V

0x00, 0x7F, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00,

// B

0x00, 0x3E, 0x7F, 0x41, 0x41, 0x22, 0x00, 0x00,

// C

0x00, 0x7C, 0x7E, 0x03, 0x03, 0x7E, 0x7C, 0x00,

// V

0x00, 0x40, 0x40, 0x7F, 0x7F, 0x40, 0x40, 0x00,

//

T


0x00, 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00,

//

-

0x00, 0x7F, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00,

// D

0x00, 0x01, 0x21, 0x7f, 0x7f, 0x01, 0x01, 0x00,

// 1

0x00, 0x01, 0x21, 0x7f, 0x7f, 0x01, 0x01, 0x00,

// 1

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x3f, 0x7f, 0x48, 0x48, 0x7f, 0x3f, 0x00,
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00,

// B

0x00, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00,

// H

//

A

0x00, 0x7F, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00,

// D

0x00, 0x01, 0x21, 0x7f, 0x7f, 0x01, 0x01, 0x00,

// 1

0x00, 0x01, 0x21, 0x7f, 0x7f, 0x01, 0x01, 0x00,

// 1

0x00, 0x3f, 0x7f, 0x48, 0x48, 0x7f, 0x3f, 0x00,

//

A



0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00,

// B

0x00, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00,

// H

0x00, 0x7F, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00,

// D

};

unsigned char Hang2[256] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7F, 0x7F, 0x41, 0x41, 0x7F, 0x3E, 0x00,

// D

0x00, 0x01, 0x21, 0x7f, 0x7f, 0x01, 0x01, 0x00,

// 1

0x00, 0x01, 0x21, 0x7f, 0x7f, 0x01, 0x01, 0x00,

// 1


0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

};

GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
static __IO uint32_t TimingDelay;

void RCC_Configuration(void)
{
//SystemInit();

// no need because SystemInit() is already called in start up code

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_AFIO, ENABLE); // cap xung lock cho cac port
/* Enable UART clock, if using USART2 or USART3 ... we must use
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) */
}

void Delay_us_t(__IO uint32_t nTime)
{

long i;
i = nTime*10;


while(i)
{

i--;
}
}
void Delay_ms_t(__IO uint32_t nTime)
{

long i;
i = nTime*10100;
while(i)
{
i--;
}
}

void Chay_Chu_1(void)
{
uint8_t index = 0, value = 0;
unsigned char temp, i;
for(temp=0; temp<168; temp++)
{
if(Value_IR!=A)
{
break;
}
for(i=0; i<32; i++)
{
Row_Data_Offset_1[i] = Hang1[temp+i];

// gan du lieu vao mang luu du


lieu dem
if(value == 0)
Row_Data_Offset_2[i] = Hang2[index+1+i];
mang luu du lieu dem

// gan du lieu vao


else if(value == 1)
Row_Data_Offset_2[i] = Hang2[(8-index)+i];

// gan du lieu vao mang luu du lieu dem

}

index++;
if(index == 9)
{
index = 0;
value = 1 - value;
}
Data(100);
}
}

void Chay_Chu_2(void)
{
unsigned char temp, i;
for(temp=0; temp<168; temp++)
{

if(Value_IR!=B)
{
break;
}
for(i=0; i<32; i++)
{
Row_Data_Offset_1[i] = Hang1[temp+i];
// gan du lieu vao mang luu du lieu dem
Row_Data_Offset_2[i] = Hang1[(168-temp)+i];
gan du lieu vao mang luu du lieu dem
}

Data(100);
}
}

//


int main(void)
{
/* Configure the system clocks */
RCC_Configuration();

/* Disable the Serial Wire Jtag Debug Port SWJ-DP */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

// tat cac pin Jtag Debug Port SWJ-DP

Timer4_init();

MATIX_Init();
config_IRF();
GPIO_ResetBits(GPIOC, GPIO_Pin_7);
//--------------------------------------------------------------------------------//

while (1)
{
//Value_IR=INFR_GetKey();
if(Value_IR==A)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_7);
Delay_ms_t(500);
Chay_Chu_1();

// dich du lieu vao hang 1

}
if(Value_IR==B)
{
GPIO_SetBits(GPIOC, GPIO_Pin_7);
Delay_ms_t(500);
Chay_Chu_2();
// dich du lieu vao hang 2
}

//GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));
nhap nhay

// led



//Delay_ms(100);
}
}
void config_IRF(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

// chon la input pull up

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

// chon la input pull up

GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void Timer4_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


/* Khoi tao timer 2 thanh ngat 1 ms */

/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel

= TIM4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority
NVIC_InitStructure.NVIC_IRQChannelCmd

NVIC_Init(&NVIC_InitStructure);

// Khoi tao vecto ngat timer2
// Muc uu tien cua ngat

= 1;
= ENABLE;

// Cho phep ngat


/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

// Enable Clock Timer2 on APB1 with frequency 36Mhz

/* ----------------------------------------------------------------------APB1 prescaler = 36 # 1 => TIM2CLK = PCLK1x2 = 2 MHz, Prescaler = 0x0 => TIM2 counter clock = 2 MHz
----------------------------------------------------------------------- */


/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period
TIM_TimeBaseStructure.TIM_Prescaler

= 2000 - 1; //1ms

// Do precaler = 36 # 1 --> tan so dau vao timer2 la 2 MHz

= 36 - 1; // 36MHz Clock down to 1 MHz (adjust per your clock)

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

// ????

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

// Che do Timer counter dem tien

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

/* TIM IT enable */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

/* TIM2 enable counter */
TIM_Cmd(TIM4, ENABLE);

// Bat timer2

}

uint8_t INFR_CheckStart()
{
uint8_t i;
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)

// Neu co canh xuong cua tin hieu

{
Delay_us_t(10);

// Delay de chong nhieu

if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)

// Neu dung la co canh xuong cua tin hieu

{
for(i=0;i<40;i++)
{
Delay_us_t(200);

// Chia nho xung START thanh 40 doan, moi
doanđiều
dai 200us
Khối
khiển trung tâm
Khối
Thu phát hồng
ngoại


khối Led ma trận


if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1) return 0; // Neu tin hieu len muc cao (1) --> khong phai xung START
}
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0);
return 1;

// Dung la xung start

}

}
return 0;
}
/*******************************************************************************
Noi Dung : Lay ma infr.
Tham Bien : Khong.
Tra Ve

: 0

: Khong co tin hieu hong ngoai.

Khac : Gia tri cua tin hieu hong ngoai.
********************************************************************************/
uint16_t INFR_GetKey(void)
{
uint8_t i;
uint16_t Data_Infr;

Data_Infr=0;
if(INFR_CheckStart())

// Neu dung xung START

{
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1);
for(i=0;i<6;i++)

// Cho het bit 1 tiep theo

// bo qua 6 Bit dua lieu

{
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0);

// cho canh xuong

while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1);

// cho canh len

}
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0);
for(i=0;i<16;i++)

// Lay 16 bit du lieu (bao gom 8 bit 0 va 8 bit 1 dau tien sau xung start)

{
Delay_us_t(750);


// Cho het bit 0 tiep theo

// Delay 750us de kiem tra bit

Data_Infr=Data_Infr<<1;


if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1) Data_Infr|=1;
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1);

// cho canh xuong

while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0);

// cho canh len

}
Delay_ms_t(400);

// Cho het tin hieu (chong nhieu)

}
return Data_Infr;

// Gia tri ma kenh tra ve

}

#ifdef USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* Infinite loop */
while (1)
{
}
}




×