Bài 04. Giao tiếp với OLED 0.96 inch SSD1306.

Bài 04. Giao tiếp với OLED 0.96 inch SSD1306.

Bài 04. Giao tiếp với OLED 0.96 inch SSD1306.

  1. LÝ THUYẾT.
  2. Xin chào các bạn,

    Hôm nay mình xin chia sẻ một số thông tin và hướng dẫn sử dụng OLed 0.96 inch SSD1306. Hiện tại trên thị trường có rất nhiều loại oled 0.96 inch với các thông số như chip điều khiển(SSD1306, SSD1325, SSD1331, SSH1106..) và chuẩn khác nhau(I2C, SPI..). Ở đây mình xin chia sẻ thông tin về oled 0.96 inch sử dụng chip điều khiển là SSD1306 và sử dụng chuẩn giao tiếp I2C.

    Mục đích chính của oled là để hiển thị thông tin với màn hình nhỏ và thông tin tương đối rõ ràng, chúng ta có thể sử dụng chúng với một số ứng dụng như: hiển thị thời gian, hiển thị thông số nhiệt độ, độ ẩm để theo dõi, hiển thị thông tin cho robot, các thiết bị cầm tay nhỏ gọn… Một vài thông số cơ bản :

    • Sử dụng chip điều khiển SSD1306.
    • Sử dụng chuẩn giao tiếp thông dụng I2C nên tương thích với hầu hết các loại MCU có trên thị trường.
    • Kích thước màn hình 0.96inch(128x64 điểm).
    • Công suất tiêu thụ 0.08W.
    • Điện áp cung cấp 3 - 5VDC.
    • Góc hiển thị > 160 độ.
    • Màu hiển thị trắng/xanh dương.
  3. Code với MX cube.
  4. Sơ đồ kết nối:

    Một số lưu ý khi sử dụng module:

    • Loại ARM sử dụng là STM32F103C8T6, 48 pin out, clock là 72Mhz, Flash memory 64 Kbytes.
    • OlED 0.96 inch , giao tiếp I2C.
    • Địa chỉ của OLED này khi giao tiếp I2C là 0x78.
    • Giao tiếp I2C với mode Standard speed (100 Khz).
    • Trình biên dịch là Kiel C V5, thư viện sử dụng là thư viện HAL( HAL libraries).
    • Hàm ssd1306_refresh_gram(); được sử dụng để làm mới màn hình, hiển thị những thông tin mới ghi vào bộ nhớ.
    • Sử dụng hàm ssd1306_draw_bitmap() để vẽ các kí tự, ssd1306_draw_3216char() hoặc ssd1306_draw_1616char() để ghi các kí tự với font khác nhau, ssd1306_display_string() để hiển thị chuỗi kí tự với các thông số input tương ứng.
    • Bộ thư viện mình tìm được trên mạng và đã chỉnh sửa lại. Để xem thêm các function liên quan về OLED thì các bạn có thể vào tab Function như hình ở dưới.
    1. Cấu hình dung Mx Cube:
      • Cấu hình xung clock:
      • Cấu hình chân debug.
      • Cấu hình I2C ở chế độ standard mode, tốc độ là 100khz, port I2C2.
      • Cấu hình xung clock hệ thống Max là 72Mhz, giúp tốc độ xử lý lệnh là nhanh nhất.
      • Cấu hình trình Ide và code generate -> click button generate code.
    2. Modify code generate:
      • Copy thư viện từ project download sang project của bạn trong thư mục src and inc. Thư mục src : file Fonts.c, SSD1306.c. Thư mục inc: MacroAndConst.h, Fonts.c, SSD1306.c.
      • Add các file .c vào project của bạn.
      • Include các thư viện vào file main.c, lưu ý add vào giữa các dòng command code BEGIN và END để tránh mất code khi generate code lại tự Mxcube.
      • Modify code để ghi một số ký tự mẫu lên oled.
      • Cấu hình reset and run để code được thực thi khi flashing code mà không cần nhấn nút reset.

      Note: Đây chỉ là ví dụ cơ bản để hiện thị một số ký tự lên oled, các bạn có thể tự tìm hiểu và modify code để có những ứng dụng riêng của mình. Mọi thắc mắc các bạn có thể comment hoặc inbox mình, mình sẽ trả lời nhanh nhất trong thời gian có thể.

  5. Một số link tham khảo.
    1. Một số link mua hàng các bạn có thể tham khảo.
    2. Link 1 Link 2 Link 3
    3. Link download tài liệu.
    4. Download datasheet của chip điều khiển SSD1306 : Download các file thư viện :

01. Giao tiếp với cảm biến ánh sáng BH1750.

Giao tiếp với cảm biến ánh sáng BH1750.

01. Giao tiếp với cảm biến ánh sáng BH1750.

  1. LÝ THUYẾT.
  2. Với BH1750 chúng ta có thể tạo được nhiều ứng dụng tiện lợi trong đời sống như bật tắt đèn ngoài sân khi trời tối, ứng dụng bật đèn cho nông nghiệp… , là ic dùng trong điện thoại, tivi. So với quang trở(điện trở thay đổi theo ánh sáng) thì BH1750 có độ chính xác và dải đo rộng hơn, tuy nhiên quá trình đo đạc cũng phức tạp hơn.

    BH1750 dùng chuẩn giao tiếp I2C, dải đo từ 1 – 65535 lux. Lux là đơn vị đo ánh sáng. Dành cho những bạn chưa biết về đơn vị lux : https://vi.wikipedia.org/wiki/Lux

    Một số tính năng của IC:

    • Giao tiếp bằng chuẩn I2C.
    • Dải quang phổ gần với tần số mắt người nhìn thấy.
    • Tín hiệu đầu ra là tín hiệu số.
    • Thang đo từ 1 – 65535 lux.
    • Mức độ tiêu thụ điện năng thấp.
    • Lọc nhiễu trong dải tần 50 – 60 Hz.
    • Mức logic giao tiếp có thể đến 1.8V.
    • Không cần các thiết bị bên ngoài để hỗ trợ chạy Ic như thạch anh …
    • Có thể tương thích với nhiều nguồn sáng như mặt trời, đèn led trắng, đèn halogen…
    • Có thể thay đổi địa chỉ giao tiếp(địa chỉ I2C).
    • Có thể config để đọc được giá trị nhỏ nhất là 0.23 lux.
    • Sai số nhỏ (20%).
    • Ảnh hưởng của tia hồng ngoại đến việc đo lường là nhỏ.

    Nếu bạn dùng module GY-30 BH1750 thì một số thông số đầu vào như sau:

    • VCC : chân cấp nguồn, điện áp đầu vào từ khoảng 3.3 -> 6VDC.
    • ADD: chân này là chân thay đổi địa chỉ nếu cần thiết, default nó sẽ là mức thấp: địa chỉ I2C sẽ là 0x23, nếu ở mức cao sẽ là 0x5C.
    • SCL : chân clock của giao tiếp I2C.
    • SDA: chân Data của giao tiếp I2C.
    • GND: chân nối mass của module.

    Một số command thông dụng khi giao tiếp với IC:

    • Power down(0x00) : Set IC ở chế độ không hoạt động.
    • Power on(0x01) : Set IC ở chế độ hoạt động.
    • Reset(0x07) : Reset giá trị các thanh ghi của IC. Command này không hoạt động khi IC ở mode Power down.
    • Continuously H-Resolution Mode(0x10): Cài đặt IC ở chế độ đo liên tục với độ phân giải là 1 lux. Thời gian đo cập nhật giá trị trung bình sẽ là 120ms.
    • Continuously H-Resolution Mode2(0x11): Cài đặt IC ở chế độ đo liên tục với độ phân giải là 0.5 lux. Thời gian đo cập nhật giá trị trung bình sẽ là 120ms.
    • Continuously L-Resolution Mode(0x13): Cài đặt IC ở chế độ đo liên tục với độ phân giải là 4 lux. Thời gian đo cập nhật giá trị trung bình sẽ là 16ms.
    • One Time H-Resolution Mode(0x20): Cài đặt IC ở chế độ đo 1 lần với độ phân giải là 0.5 lux, thời gian đo cập nhật giá trị trung bình sẽ là 120ms. Sau khi cập nhật giá trị IC sẽ chuyển sang power down, muốn đo lại thì chúng ta phải gửi command power on để tiếp tục.
    • One Time H-Resolution Mode2(0x21): Cài đặt IC ở chế độ đo 1 lần với độ phân giải là 0.5 lux, thời gian đo cập nhật giá trị trung bình sẽ là 120ms. Sau khi cập nhật giá trị IC sẽ chuyển sang power down, muốn đo lại thì chúng ta phải gửi command power on để tiếp tục.
    • One Time L-Resolution Mode(0x23): Cài đặt IC ở chế độ đo 1 lần với độ phân giải là 4 lux, thời gian đo cập nhật giá trị trung bình sẽ là 16ms. Sau khi cập nhật giá trị IC sẽ chuyển sang power down, muốn đo lại thì chúng ta phải gửi command power on để tiếp tục.
    • Change Measurement time(01000_MT[7,6,5], 011_MT[4,3,2,1,0]): Thay đổi độ phân giải trong quá trình đo lường, muốn tăng độ chính xác thì thời gian đo sẽ chậm hơn và ngược lại.

    Note : Nhà sản xuất khuyến cáo chúng ta nên sử dụng mode H-resolution Mode, Với những môi trường tối chúng ta có thể sử dụng H-resolution Mode2 thay cho H-resolution Mode hoặc có thể thay đổi độ phân giải để đo được các giá trị nhỏ hơn.

    Cách tính toán giá trị đo lường. Với H-resolution Mode và thanh ghi độ phân giải có giá trị mặc định.

    Output = Value_Read/1.2/Mode.

    • Output là giá trị của độ sáng đơn vị là lux.
    • Value_Read : là giá trị đọc ra từ command read, giá trị này có 16 bit.
    • 1.2 là hệ số mặc định trong datasheet.
    • Mode: với H-resolution Mode2 thì Mode = 0.5 còn H-resolution Mode thì Mode = 1.
  3. Code với MX cube.
  4. Lưu đồ giải thuật:

    Call function reset -> Set sensitive with default value(MTreg) -> Set mode sensor -> read and process data.

    Sơ đồ kết nối.

    1. Cấu hình dung Mx Cube:
      • Cấu hình xung clock:
      • Cấu hình chân debug.
      • Cấu hình I2C.
      • Cấu hình clock hệ thống.
      • Cấu hình và generate code.
    2. Modify code generate:
      • Copy file thư viện là bh1750.h và main.h từ thư mục download vào project mà các bạn vừa generate ra, tương tự với file bh1750.c và main.c. Link download mình sẽ để ở dưới.
      • Thêm file thư viện bh1750.c trước khi build.
      • Build code.
      • Download Firmware.
      • Debug to view change.
    3. Note:
      • Để debug, các bạn cần có mạnh nạp có chức năng debug và đã được cài driver để máy tính nhận được mạch nạp này.
      • Ở trên mình sử dụng MCU là STM32F103C8T6, khi sử dụng các loại MCU khác thì cần chú ý các define, import, các chân chức năng…
      • Chú ý chọn reset and run trong chế độ config mạch nạp + chọn đúng loại mạch nạp.
      • Ở đây mình chỉ hướng dẫn cách lấy data, tùy vào ứng dụng khác nhau mà các bạn có thể sử dụng linh hoạt.
      • Source code gốc mình lấy từ github và có chỉnh sửa. Link source code gốc : https://github.com/lamik/Light_Sensors_STM32.
      • Ở đây mình chỉ hướng dẫn một số bước để lấy thư viện và thực thi code, để hiểu rõ hơn về cảm biến và cách thức xử lí các bạn cần đọc hiểu datasheet đồng đời debug thêm trong code, chúc các bạn thành công. Nếu có thắc mắc gì các bạn cứ để comment mình sẽ trả lời nhanh nhất trong thời gian có thể.
  5. Một số link tham khảo.
    1. Một số link mua hàng các bạn có thể tham khảo.
    2. Link 1 Link 2 Link 3 Link 4
    3. Link download tài liệu.
    4. Link datasheet Link manual Link thư viện cảm biến

14. OPTION BYTES TRONG STM8S

OPTION BYTES TRONG STM8S.

14. OPTION BYTES TRONG STM8S.

  1. CƠ SỞ LÝ THUYẾT.
  2. Option byte trong STM8S003 phục vụ một số chức năng riêng biết được liệt kế như sau:

    • ROP(Memory Readout protection) : Mục đích của chức năng này là sẽ khóa code, không cho phép đọc ngược, bảo vệ chương trình tránh khỏi tình trạng copy source code cũng như flash đè code. Trong trường hợp đã write ROP option byte là ON thì chúng ta chỉ có thể write ROP off và flash đè code khác xuống MCU, không thể đọc lại được code(nhà sản xuất có cách nào chưa công bố thì mình không biết).
    • UBC[0:7] : Config size cho bootloader. Một số ứng dụng cần update Firmware theo version chúng ta sẽ cần viết bootloader và application cho nó, các bit này sẽ hữu dụng khi chuyển vector ngắt đến địa chỉ mà application bắt đầu cũng như bảo vệ code cho vùng bootloader. Phần config này sẽ hữu dụng khi chúng ta sử dụng STVD và có nhược điểm vùng nhớ application bắt đầu phải chẵn và chia hết cho 64(Không config linh động được địa chỉ bắt đầu của application). Trong IAR sẽ có một số cách để config bootloader mà k cần sử dụng đến option này, các bạn có thể tham khảo thêm với IAR ở đây : http://laptrinharmst.blogspot.com/2021/11/bai-15-bootloader-stm8s-tren-iar.html và file AN2659.
    • AFR[0:7]: Config cho Alternate function. Như các bạn đã biết mỗi chân vi điều khiển có thể có nhiều chức năng khác nhau,để linh hoạt trong việc config các chức năng này nhà sản xuất đã thêm tính năng để việc sử dụng chân điều khiển linh hoạt hơn. Ví dụ: Chân PC5 của STM8S003 có chức năng mặc định sẽ là SPI tạo xung clock, ngoài ra nó cũng là chân Timer2 chanel1, để sử dụng tính năng timer chúng ta bắt buộc phải write thêm bit config AFR0. Chức năng khác nhau của config này các bạn có thể tham khảo thêm trong datasheet.
    • HSITRIM : config độ phân giải cho bộ xung clock HIS.
    • LSI_EN : config cho phép bộ dao động LSI như là bộ cung cấp clock chính cho MCU.
    • IWDG_HW, WWDG_HW, WWDG_HALT : cho phép bộ independent watchdog, window watchdog hoạt động 1 cách tự động sau khi cấp nguồn hay không.
    • EXTCLK: cho phép sử dụng thạch anh ngoài hay không.
    • CKAWUSEL : config low-speed clock source cho bộ AWU(Analog wakeup) lấy từ LSI hay HSE.
    • PRSC : đi chung với config CKAWUSE, nếu lấy từ HSE thì tương ứng với tỷ lệ chia.
    • HSECNT[0:7] : config thời gian để bộ dao động ngoại được ổn định trước khi vận hành, option này sẽ sử dụng EXTCLK on.

    Về mặt lí thuyết chúng ta có thể nạp option byte mỗi lần flash code theo tool nạp tuy nhiên khi viết chương trình bootloader hoặc một số mục đích khác chúng ta có thể dùng các tập lệnh trong thư viện flash để ghi các option byte này mà k cần sử dụng tool nạp. Vùng nhớ của các option tương ứng với bảng bên dưới.

  3. Ví dụ với Option byte.
  4. Ví dụ: viết chương trình sử dụng TIM2_CH3 chớp tắt led với chu kì 1s,duty cycle là 50% trên chân PD2, sử dụng dụng tính năng ghi flash để ghi các byte option mà không cần dùng tool. Chân PD2 có chức năng TIM2_CH3, tuy nhiên nó là Aternate function, cần write option byte mới sử dụng được nếu không chỉ còn cách flash lại các option byte.

    1. Cấu hình bộ nhớ Flash.
    2. Chú ý việc cấu hình ở đây sẽ tương tự như việc cấu hình ghi vào EEPROM.

    3. Cấu hình bộ Timer 2.
    4. Ghi các option byte.
    5. Sử dụng STVP để nạp chương trình mà k cần ghi các option byte.
    6. Kết quả thu được sẽ là led trên chân PD2 sẽ chớp tắt với chu kì 1s(0.5s sáng và 0.5s tắt). Chúc các bạn thành công.

Link tải ví dụ với option bytes ở trên.

13. FLASH và EEPROM TRONG STM8S.

FLASH và EEPROM TRONG STM8S.

FLASH và EEPROM TRONG STM8S.

  1. Cơ Sở Lý Thuyết.
  2. Chào các bạn, Hôm nay mình sẽ tiếp tục một số tìm hiểu về Flash và EEPROM.Chúng là 2 vùng nhớ khác nhau trong STM8S, tuy nhiên về cấu tạo và bản chất thì tương đối giống nhau. Tổng quan về bộ nhớ của của STM8S.

    Bảng thống kê dưới đây sẽ so sánh một số thông tin chung giữa 2 loại:

    Bộ nhớ Flash sử dụng các cổng logic NAND nên giá thành sẽ rẻ hơn, tốc độ truy cập cũng sẽ chậm hơn, bộ nhớ Flash thường truy cập theo khối trong khi EEPROM thì là byte, chức năng tương ứng cũng khác nhau. Ở STM8S003 thì bộ nhớ Flash(8k byte) dùng để lưu trữ chương trình trong khi EEPROM(128 bytes) thì thường dùng để lưu một số thông tin không xóa sau khi Flash hoặc mất điện. Với những thông tin bạn không muốn mất sau khi Flash Firmware mới và tốc độ truy cập cao thì thường chúng ta sẽ sử dụng bộ nhớ EEPROM, ngược lại nhưng thông số thay đổi mỗi lần Flash, tốc độ truy cập thông thường và khối lượng data lớn thì chúng ta sẽ sử dụng bộ nhớ Flash.

  3. Ví dụ với bộ nhớ Flash.
  4. Ví dụ: Ghi data vào 16 byte cuối cùng của bộ nhớ Flash với địa chỉ 0x9FF0 -> 0x9FFF data tương ứng từ 0 -> 15, Sau khi đọc lại data đã ghi, nếu đúng đèn led trên chân PD3 sẽ sáng, ngược lại nếu ghi bị failed hoặc read bị failed thì đèn ở chân PD3 sẽ tắt.

    Cách thức kiểm tra: các bạn sẽ dùng mạch nạp stlink_v2 + phần mềm “ST Visual Programmer” để đọc lại toàn bộ vùng nhớ và kiểm tra data thuộc địa chỉ từ 0x9FF0 -> 0x9FFF.

    1. Config bộ nhớ Flash.
    2. Trước khi thực hiện đọc ghi vào vùng nhớ Flash, chúng ta cần thực hiện một số config quan trọng như: Deinit lại toàn bộ vùng nhớ, Cài đặt thời gian xử lí, đồng thời mở khóa vùng nhớ. “FLASH_MEMTYPE_PROG” tương ứng với việc chọn vùng nhớ Flash để giao tiếp.

    3. Thực thi code giao tiếp với bộ nhớ Flash
    4. Trước tiên chúng ta sẽ ghi data với giá trị từ 0 -> 15 vào địa chỉ bắt đầu từ 0x9FF0 -> 0x9FFF(16 bytes). Đợi 1 khoảng thời gian nhỏ để chắc chắn rằng việc ghi đã thực thi xong, tiếp đến chúng ta sẽ đọc lại và kiểm tra vùng nhớ đã ghi, nếu chỉ cần 1 địa chỉ sai thì sẽ thoát quá trình đọc. Nếu kết quả ghi vào đọc lại giống nhau thì đèn led trên chân PD3 sẽ sang, ngược lại thì tắt.

      Chú ý: Để thao tác với vùng nhớ Flash thì chúng ta cần chú ý rằng code của quá trình biên dịch k được tràn vào vùng nhớ cần đọc/ghi. Ngoài lệnh đọc/ghi thông thường chúng ta có thể sử dụng đọc/ghi các block(IN_RAM trong thư viện) để với mục đích nâng cao tốc độ tương tác khi thao tác với số lượng data lớn.

    5. Kết quả thực thi.
    6. Sau khi dùng stlink_V2 và phần mềm “ST Visual Programmer” để đọc lại toàn bộ vùng nhớ, kết quả sẽ như hình bên dưới.

  5. Ví dụ với bộ nhớ EEPROM.
  6. Ví dụ: ghi data vào 16 byte cuối cùng của bộ nhớ Flash với địa chỉ 0x4000 -> 0x400F data tương ứng từ 0 -> 15, Sau khi đọc lại data đã ghi, nếu đúng đèn led trên chân PD3 sẽ sáng, ngược lại nếu ghi bị failed hoặc read bị failed thì đèn ở chân PD3 sẽ tắt. Cách thức kiểm tra: các bạn sẽ dùng mạch nạp stlink_v2 + phần mềm “ST Visual Programmer” để đọc lại toàn bộ vùng nhớ và kiểm tra data thuộc địa chỉ từ 0x4000 -> 0x400F.

    Tương tự như bộ nhớ Flash, giao tiếp với EEPROM cũng tương tự, chỉ khác cấu hình và địa chỉ.

    1. Config bộ nhớ EEPROM.
    2. Thực thi code giao tiếp với bộ nhớ Flash.
    3. Kết quả.
    4. Note : ngoài lệnh Read/Write , chúng ta còn một số lệnh như xóa, ghi 1 word… Các bạn có thể tham khảo trong file stm8s_flash.c và áp dụng thử cho project của mình. Bộ nhớ EEPROM của STM8S003 chỉ là 128 bytes tức là bắt đầu từ 0x4000 ->0x407F.

Link tải ví dụ với bộ nhớ flash. Link tải ví dụ giao tiếp với EEPROM