1. Chuẩn giao tiếp SPI:

SPI (Serial Peripheral Interface) được phát triển bởi Motorola. Đây là một chuẩn đồng bộ nối tiếp để truyền dữ liệu ở chế độ song công toàn phần (full- duplex) tức trong cùng một thời điểm có thể xảy ra đồng thời quá trình truyền và nhận. Đôi khi SPI còn được gọi là chuẩn giao tiếp 4 dây (Four-wire).

SPI là giao diện đồng bộ, bất cứ quá trình truyền nào cũng được đồng bộ hóa với tín hiệu clock chung. Tín hiệu này sinh ra bởi master.

Giao diện SPI có bốn tín hiệu số:

  • MOSI hay SI – cổng ra của bên Master ( Master Out Slave IN). Đây là chân dành cho việc truyền tín hiệu từ thiết bị chủ động đến thiết bị bị động.
  • MISO hay SO – Công ra bên Slave (Master IN Slave Out). Đây là chân dành cho việc truyền dữ liệu từ Slave đến Master.
  • SCLK hay SCK là tín hiệu clock đồng bộ (Serial Clock). Xung nhịp chỉ được tạo bởi Master.
  • CS hay SS là tín hiệu chọn vi mạch ( Chip Select hoặc Slave Select). SS sẽ ở mức cao khi không làm việc. Nếu Master kéo SS xuông thấp thì sẽ xảy ra quá trình giao tiếp. Chỉ có một đường SS trên mỗi slave nhưng có thể có nhiều đường điều khiển SS trên master, tùy thuộc vào thiết kế của người dùng.

Các kiểu kết nối ở chế độ Multiple slaves:

alt text

+Ở chế độ này mổi Slave được kích hoạt mởi 1 chân SS riêng biệt. Tại mổi thời điểm chỉ có 1 Slave giao tiếp với Master. Nếu muốn tiết kiệm chân khi có nhiều Slave thì có thể sử dụng Binary Decoder IC.

alt text

Chế độ này gọi là daisy-chained mode. Master kích hoạt tất cả các Slave cùng lúc. Hoạt động như kiểu dịch thanh ghi. (Sẽ tìm hiểu sâu hơn)

Dạng sóng của SPI:

alt text

Nguyên lý hoạt động:

Để bắt đầu hoạt động thì kéo chân SS xuống thấp và kích hoạt clock ở cả Maser và Slave.

Mỗi chip Master hay Slave có một thanh ghi dữ liệu 8 bits.

Cứ mỗi của xung nhịp do Master tạo ra trên đường giữ nhịp SCK, một bit trong thanh ghi dữ liệu của Master được truyền qua Slave trên đường MOSI, đồng thời một bit trong thanh ghi dữ liệu của chip Slave cũng được truyền qua Master trên đường MISO.

Sim setting1

Để đảm bảo cho tín hiệu trên SPI được phát và thu đúng, SPI Master và SPI Slave phải được thiết kế phù hợp với nhau. Trong bảng mô tả đặc tính của một giao tiếp SPI, ta thường gặp các thông tin sau:

  • SS Active Low/High: thông số này cho biết mạch SPI Slave được chuyển sang trạng thái active khi tín hiệu Slave Select là thấp hay cao. Mạch SPI Master sẽ điều khiển tín hiệu Slave Select tương ứng để kích hoạt hoặc ngừng kích hoạt mạch SPI Slave.
  • CPOL (viết tắt của Clock POLarity): thông số này cho biết tín hiệu SCLK có dạng như thế nào.
    • CPOL = 0: cạnh đầu tiên của SCLK là cạnh lên (khi không hoạt động thì SCLK ở mức thấp) và mỗi xung clock bao gồm cạnh thứ nhất là cạnh lên và cạnh thứ hai là cạnh xuống.
    • CPOL = 1: cạnh đầu tiên của SCLK là cạnh xuống (khi không hoạt động thì SCLK ở mức cao) và mỗi xung clock bao gồm cạnh thứ nhất là cạnh xuống và cạnh thứ hai là cạnh lên.

spi_6

  • CPHA (viết tắt của Clock PHAse): thông số này cho biết tín hiệu MOSI và MISO được setup và sample ở cạnh nào của SCLK.
    • CPHA = 0: tín hiệu được sample ở cạnh thứ nhất của xung SCLK và được setup ở cạnh thứ hai của xung SCLK. Chú ý rằng trong trường hợp này bit dữ liệu đầu tiên sẽ được setup trước khi có xung SCLK.
    • CPHA = 1: tín hiệu được setup ở cạnh thứ nhất của xung SCLK và được sample ở cạnh thứ hai của xung SCLK.

spi_7

Tổng hợp hai thông số CPOL và CPHA cho ta bốn kiểu (mode) định dạng dữ liệu trên MISO/MOSI (xem Hình 7):

  • Kiểu 0 (Mode 0) (CPOL = 0, CPHA = 0): dữ liệu được bên phát setup ở cạnh xuống của xung clock trước đó và được bên thu sample ở cạnh lên của xung clock hiện tại.
  • Kiểu 1 (Mode 1) (CPOL =0, CPHA = 1): dữ liệu được bên phát setup ở cạnh lên của xung clock và được bên thu sample ở cạnh xuống của xung clock.
  • Kiểu 2 (Mode 2) (CPOL =1, CPHA = 0): dữ liệu được bên phát setup ở cạnh lên của xung clock trước đó và được bên thu sample ở cạnh xuống của xung clock hiện tại.
  • Kiểu 3 (Mode 3) (CPOL =1, CPHA = 1): dữ liệu được bên phát setup ở cạnh xuống của xung clock và được bên thu sample ở cạnh lên của xung clock.

Ngoài ra còn có hai thông số khác:

  • Clock-rate: thông số này cho biết tốc độ tối đa của tín hiệu SCLK mà mạch SPI (Master và Salve) hoạt động được một cách đáng tin cậy.
  • MSB first hay LSB first: thông số này liên quan đến cách một byte dữ liệu được truyền đi như thế nào-với bit MSB trước hay với bit LSB trước. Mặc dù thông số này không trực tiếp liên quan đến đặc tính điện của tín hiệu trên giao tiếp SPI, nhưng đây cũng là một thông số cần để ý khi phát triển các ứng dụng để xử lý các bit dữ liệu được thu/phát trên giao tiếp SPI.

2. LCD Nokia 5110:

Tài Liện Hướng Dẫn + Datasheet của LCD: https://www.mediafire.com/?gde8o115sb4spsf

Pinout:

1: RST : Chân reset LCD
2: CE: Chân cho phép hoặc không cho phép LCD hoạt động.
3: DC: Chân chọn dữ liệu gửi đến LCD là lệnh hay là dữ liệu để hiển thị ra màn hình.
4: DIN: Chân truyền dữ liệu theo chuẩn SPI.
5: CLK: Chân truyền xung nhịp theo chuẩn SPI.
6: VCC: Chân cấp nguồn cho LCD.
7: BL: Chân cấp nguồn cho led nền màn hình LCD.
8: GND: Chân mass.

Ngoài chuẩn SPI với 3 đường tín hiệu chuẩn ( CS (CE), SCK(CLK), MOSI(DI) ) thì Nokia LCD này cần thêm 2 đường nữa, đó là D/C (Data/Command) và RST (Reset).

Giao tiếp với LCD NOKIA 5110

Quá trình gửi dữ liệu từ vi điều khiển đến LCD NOKIA 5110 được chia làm 2 chế độ. Chế độ gửi lệnh điiều khiển LCD và chế độ gửi dữ liệu hiển thị ra LCD. Đường tín hiệu DC cho phép chọn 1 trong 2 chế độ này.
+ Nếu DC=0: dữ liệu gửi đến LCD được lưu vào thanh ghi Command. Thanh ghi Command lưu trữ và thực thi các lệnh dùng để điều khiển sự hoạt động của Nokia LCD (dữ liệu này không được hiển thị ra màn hình).


+ Nếu DC=1: dữ liệu gửi đến LCD được lưu vào thanh ghi Data. Thanh ghi Data lưu trữ các giá trị dữ liệu hiển thị lên màn hình LCD.

Tín hiệu reset LCD được tạo ra khi chân RST được kéo xuống mức thâp (tức RST=0).
Khi đang truyền dữ liệu, nếu có tín hiệu reset LCD thì quá trình truyền sẽ bị hủy. Cho đến khi chân RST ở mức cao (tức RST=1), trong chu kì xung clock tiếp theo, quá trinh truyền dữ liệu của byte vừa bị hủy sẽ được thực hiện lại.

Khi đường tín hiệu CE ở mức cao (tức CE=1), thì LCD sẽ không chấp nhận bất kỳ một dữ liệu nào từ VĐK gửi đến hay mọi dữ liệu hoặc lệnh lúc này đều không ảnh hưởng đến LCD.
Khi đường tín hiệu CE ở mức thấp (tức CE=0) thì data gửi đến LCD sẽ được chấp nhận cứ Sau mỗi chu kì của xung clock (xung cạnh lên) thì 1 bit dữ liệu được dịch vào LCD trên chân DIN.
Chân CE phải được giữ ở mức thấp(tức CE=0) cho tới khi việc gửi dữ liệu đến LCD hoàn tất.
Một số lệnh cơ bản điều khiển LCD NOKIA 5110.

a : Lệnh Function set : Set chế độ hoạt động cho LCD.

           Bit         Tên          Mô tả

           0            H             là bit chọn cách sử dụng lệnh điều khiển LCD là cơ bản hay
thêm lệnh bổ sung.
+
Nếu H=0: cho phép sử dụng các lệnh cơ bản.
+ Nếu H=1: cho phép sử dụng thêm 1 số lệnh bổ sung.
1            V             là bit chọn chiều tăng giá trị địa chỉ của bộ nhớ (DDRAM)
của LCD.

                              + Nếu V=0: Giá trị của địa chỉ tăng theo chiều ngang.
                              + Nếu V=1: Giá trị của địa chỉ tăng theo chiều dọc.

 2            PD           Là bit chọn chế độ hoạt động.

                              + Nếu PD=0: kích hoạt LCD hoạt động.
                              + Nếu PD=1: chế độ “power down”.

3-7                         DB3-DB7.
 00100.

b : Các lệnh trong chế độ cho phép sử dụng các lệnh cơ bản (khi H=0).

– Lệnh Set địa chỉ dòng (set Y address).

LCD Nokia 5110 hiển thị được 6 dòng (0 ->5), vì vậy chỉ cần 3 bit Y2, Y1, Y0, để chứa giá trị lựa chọn dòng hiển thị.

– Lệnh Set địa chỉ cột (Set X address).

   

LCD Nokia 5110 có tất cả 84 cột (0 ->83), nên cần đến 7 bít (X0->X6 ) để chứa giá trị lựa chọn cột hiển thị.

– Lệnh cài đặt hiển thị (Display Control).

   

ý nghĩa của các bit D, E :

   

c : Các lệnh trong chế độ cho phép sử dụng các lệnh bổ sung (H=1).

– Lệnh Set Bias (CommandBias System ).

Đây là lệnh để thiết lập giá trị của Bias được xác định bởi các Bit BS2, BS1 và BS0.

– Lệnh Set điện áp hoạt động cho LCD. (Set Vop).

Các bạn có thể set các bit từ Vop6 ->Vop0 để chọn điện áp hoạt động cho LCD, dựa vào công thức sau.

với giá trị của a, b là: a=3.06, b=0.06

Ví dụ: Để chọn điện áp hoạt động của LCD là 5V, ta làm như sau:
Theo công thức ta sẽ có:
5V = 3.06 + (Vop6 ->Vop0)*0.06
từ đó suy ra: (Vop6 ->Vop0) =32,33. Ta sẽ chọn số nguyên là 32 hay bằng 20H=0100000B.
Vậy, giá trị đưa vào LCD để set giá trị điên áp cho LCD là: 11000000B hay C0h.
Có 1 số lệnh khác trong chế độ H=1, các bạn có thể tham khao thêm trong datasheet của LCD Nokia 5110 các bạn download ở mục III phía dưới

d : Thuật toán Cài đặt khởi tạo cho LCD NOKIA.

– Mỗi khi sử dụng các thiết bị ngoại vi chúng ta đều phải gọi hàm khơi tạo các thông số cài đặt ban đầu cho thiết bị sau đây mình đưa ra trình tự       cài   đặt để các bạn tham khảo.

e : Tiếp theo: Tạo dữ liệu ảnh Graphic

– Đầu tiên các bạn tải phần mềm này về nhé: http://en.radzio.dxp.pl/bitmap_conve…DAssistant.zip

Do LCD của chúng ta có độ phân giải 84×48 nên độ phân giải cho ảnh cũng phải là 84×48. Nếu bạn add ảnh với độ phân giải cao hơn thì LCD     chỉ lấy vừa đủ 84×48 thôi (chỉ lấy 1 góc của ảnh). Do đó mình cần resize ảnh về độ phân giải chính xác.

Các bước tạo dữ liệu file ảnh:
1. Open LCDAssistant.exe

2. File > Load image > chọn ảnh bạn cần > Open
(Lưu ý: Do Nokia 5110 LCD hiển thị ảnh trắng đen nên trước khi load ảnh, các bạn nên mở ảnh bằng Paint, save as lại với mục “Save as type” là Monochrome Bitmap hoặc 16 Color Bitmap rồi hẵng load image mới tạo nhé. Nếu không thì khi xuất data tất cả các giá trị sẽ là 0x00)

Ngoài ra, các bạn có thể mở Paint, nhấn Ctrl + E và set độ phân giải là 84×48. Sau đó bạn có thể “vẽ bùa” vào ảnh thoải mái (chỉ trắng/đen thôi nhé) (nếu ảnh nhỏ quá, khó vẽ, bạn có thể Zoom lớn lên rồi vẽ ). Sau đó save ảnh lại với phần mở rộng như hướng dẫn trên rồi mới Load image với LCDAssistant.exe

3. File > Save output. Chọn tên cho file của bạn rồi bấm Save. Thế là bạn đã có dữ liệu của tấm ảnh rồi đấy ^^

3. Code:

3.1 SPI mềm:

Tạo ra một giao thức truyền thông giống SPI nhưng chỉ sử dụng các cổng GPIO của vi điều khiển.  Điều này cũng có nghĩa bạn có thể sử dụng giao thức này trên bất kì vi điều khiển nào mà không cần phải nhớ thanh ghi hay các chân phần cứng.

Đầu tiên định nghĩa chân sử dụng:

#define LCD_PIN_RST GPIO_Pin_0
#define LCD_PORT_RST GPIOB

#define LCD_PIN_CE GPIO_Pin_1
#define LCD_PORT_CE GPIOB

#define LCD_PIN_DC GPIO_Pin_2
#define LCD_PORT_DC GPIOB

#define LCD_PIN_DIN GPIO_Pin_3
#define LCD_PORT_DIN GPIOB

#define LCD_PIN_CLK GPIO_Pin_4
#define LCD_PORT_CLK GPIOB

Tiếp theo là cấu hình chân:

void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_NOKIA_5110, ENABLE);

GPIO_InitStructure.GPIO_Pin = LCD_PIN_RST;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_PORT_RST, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = LCD_PIN_CE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_PORT_CE, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = LCD_PIN_DC;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_PORT_DC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = LCD_PIN_DIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_PORT_DIN, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = LCD_PIN_CLK;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LCD_PORT_CLK, &GPIO_InitStructure);

}

Cấu hình LCD:

GPIO_SetBits(LCD_PORT_RST, LCD_PIN_RST); 
GPIO_SetBits(LCD_PORT_CE, LCD_PIN_CE);
GPIO_SetBits(LCD_PORT_DC, LCD_PIN_DC);
GPIO_SetBits(LCD_PORT_CLK, LCD_PIN_CLK);
GPIO_SetBits(LCD_PORT_DIN, LCD_PIN_DIN);

GPIO_ResetBits(LCD_PORT_RST, LCD_PIN_RST); // clr RST Reset the LCD to a known state
GPIO_SetBits(LCD_PORT_RST, LCD_PIN_RST); // set RST;

LCDWrite(LCD_CMD, 0x21); // Tell LCD that extended commands follow
LCDWrite(LCD_CMD, 0x80 + contrast); // Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark (max 127);
LCDWrite(LCD_CMD, 0x04 + coefficent); // Set Temp coefficent (max 4);
LCDWrite(LCD_CMD, 0x10 + bias); // LCD bias mode (max 15);
LCDWrite(LCD_CMD, 0x20); // We must send 0x20 before modifying the display control mode
LCDWrite(LCD_CMD, 0x0C); // Set display control, normal mode. 0x0D for inverse

Hàm gửi 1 byte sang LCD: Hàm này mô phỏng quá trình SPI gửi tín hiệu (tương ứng với hàm SPI_I2S_SendData(SPI1,data) khi có cờ báo bộ đệm truyền trống (Mức 0 la trống))

Các hàm còn lại xem trong code:

3.1 SPI cứng:

Dùng module SPI sẽ được tích hợp trong STM32. Trong STM32F103 có SPI1 và SPI2. trong code này ta sử dụng SPI 1.