当前位置:网站首页 > 技术博客 > 正文

树莓派硬件pwm引脚频率

Sad news (see http://wiringpi.com/wiringpi-deprecated/) .

Talk is cheap, here is the code.

 

PCF8574ForLCD1602.py

# -*- coding: utf-8 -*- """ Python3 Code for LCD1602 Control via PCF8574 Created on Tue Aug 20 10:21:33 2019 @author: Farman """ import smbus import time ''' Hardware Connection LCD1602 PCF8574T ----------------- 01 - VSS 02 - VDD 03 -- V0 04 -- RS 04 - P0 : 0 - command 1 - data 05 -- RW 05 - P1 : 0 - write 1 - read 06 --- E 06 - P2 : rising edge - data set to bus falling edge - data read/write trig 07 -- D0 08 -- D1 09 -- D2 10 -- D3 11 -- D4 09 - P4 12 -- D5 10 - P5 13 -- D6 11 - P6 14 -- D7 12 - P7 15 --- A 16 --- K Python3 module smbus is used for I2C communication. Use "sudo raspi-config" to enable I2C interface. Use "sudo apt install python3-smbus, i2c-tools" to install smbus module of python3 and make command "i2cdetect" ready. I2C address of PCF8574 is hardware configurable, use "i2cdetect -y 1" for PCF8574 address detection after correct hardware connection. I2C bus related pins (physical name) of RaspberryPi: pin 1 - 3.3V 2 - 5.0V 3 - SDA of I2C bus 4 - 5.0V 5 - SCL of I2C bus 6 - GND Adjust the LCD contrast risistor first for perfect display after LCD power-on. ''' class PCF8574ForLCD1602: def __init__(self, bus=1, addr=0x27): self.bus = bus self.smbus = smbus.SMBus(self.bus) self.addr = addr return def write_command_byte(self, byte): def write_half_command_byte(smbus, half_byte): i2c_data = (half_byte<<4) & 0xF0 # RS = RW = E = 0 smbus.write_byte(self.addr, i2c_data) time.sleep(0.001) i2c_data |= 0x04 # RS = RW = 0, E = 1 smbus.write_byte(self.addr, i2c_data) time.sleep(0.001) i2c_data ^= 0x04 # RS = RW = 0, E = 1 smbus.write_byte(self.addr, i2c_data) time.sleep(0.001) return write_half_command_byte(self.smbus, byte >> 4) # high half-byte write_half_command_byte(self.smbus, byte) # low half_byte return def write_command_bytes(self, command_bytes): for byte in command_bytes: #print('Output:', hex(byte)) self.write_command_byte(byte) return def write_data_byte(self, byte): def write_half_data_byte(smbus, half_byte): i2c_data = (half_byte<<4) & 0xF0 # RS = RW = E = 0 i2c_data |= 0x01 smbus.write_byte(self.addr, i2c_data) i2c_data |= 0x04 # RS = RW = 0, E = 1 smbus.write_byte(self.addr, i2c_data) i2c_data ^= 0x04 # RS = RW = 0, E = 1 smbus.write_byte(self.addr, i2c_data) return write_half_data_byte(self.smbus, byte >> 4) # high half-byte write_half_data_byte(self.smbus, byte) # low half_byte return def write_data_bytes(self, byte_list): for byte in byte_list: self.write_data_byte(byte) return if __name__ == '__main__': pcf8574 = PCF8574ForLCD1602() bus_width=4 lines=2 font_big=0 display_on=1 cursor_on=0 blink_on=0 display_entire_shift_on=1 display_shift_increase=1 commands = [0x02, # set bus width 0x20 + (0x10 if bus_width==8 else 0x00) + (0x08 if lines==2 else 0x00) + (0x04 if font_big else 0x00), # function set 0x08 + (0x04 if display_on else 0x00) + (0x02 if cursor_on else 0x00) + (0x01 if blink_on else 0x00), 0x01, 0x06, ] pcf8574.write_command_bytes(commands) pcf8574.write_command_byte(0x80) pcf8574.write_data_bytes("".encode())

LCD1602.py

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ LCD1602 Display Control in Python3 on RaspberryPi Created on Tue Aug 20 10:21:33 2019 @author: Farman """ from PCF8574ForLCD1602 import PCF8574ForLCD1602 as pcf8574 import time ''' Commands of HD44780/KS0066(Controller of LCD1602) ------------------------------------------------ clear display 0x01 return home 0x02 entry mode 0x04 + ID*2 + S | |: 1 - entire shift on 0 - entire shift off | |: 1-increment 0 - decrement display on/off 0x08 + D*4 + C*2 + B | | |: blink of cursor, 1 - on 0 - off | | | |: cursor on/off, 1 - on 0 - off | |: entire display on/off, 1 - on 0- off cursor/display shift 0x10 + SC*8 + RL*4 | |: 1-shift to right 0-shift to left | |: 1-display shift 2-cursor move function set 0x20 + DL*0x10 + N*8 + F*4 | | F: 1 - 5*10dots 0-5*8 dots | N: 1 - 2 lines 0 - 1 lines DL: 1 - 8-bit bus 0 - 4-bit bus set CGRAM address 0x40 + addr (6-bit width) set DDRAM address 0x80 + addr (7-bit width) read buzy flag and address : RS=0, RW=1 write data to CG or DDRAM : RS=1, RW=0 read data from CG or DDRAM: RS=1, RW=1 For any character LCD display module with cotroller compatible with HD44780 and/or KS0066, such as LCD2002, LCD2402, LCD4002 and LCD4004, this code should could be used with perfect hardware parameter configuration. ''' class LCD1602: def __init__(self, communicator): self.communicator = communicator self.lines = 2 return def reset(self, bus_width=4, lines=2, font_big=0, display_on=1, cursor_on=0, blink_on=0, display_entire_shift_on=0, display_shift_increase=1): ''' bus_width : 8 - 8-bit, else - 4-bit lines : 2 - 2-line, else - 1-line font_big : 1 - 5*10, else - 5*8 display_on: 1 - on, else off cursor_on : 1 - on, else off blink_on : 1 - on, else off display_entire_shift_on : 1 - on, else off display_shift_increase : 1 - on, else off ''' self.lines = lines self.communicator.write_command_bytes( [0x02, # set bus width 0x20 + (0x10 if bus_width==8 else 0x00) + (0x08 if lines==2 else 0x00) + (0x04 if font_big else 0x00), # function set 0x08 + (0x04 if display_on else 0x00) + (0x02 if cursor_on else 0x00) + (0x01 if blink_on else 0x00), # display cursor set 0x01, # clear display 0x04 + (0x01 if display_entire_shift_on else 0x00) + (0x02 if display_shift_increase else 0x01), # entry mode ]) if self.lines == 1: self.write_string(0, 0, "LCD1602 DISPLAY Farman@2019") else: self.write_string(0, 0, "LCD1602 DISPLAY") self.write_string(1, 0, "Farman@*") time.sleep(3) self.clear_all() def write_string(self, line, column, string): ''' line : 0 - the upper line, else the lower line (2-line mode) column : the first column to write string, value should be [0, 80) for 1-line mode [0, 40) for 2-line mode ''' line = min(line, 1) data = string.encode() if self.lines == 1: column = min(column, 79) addr = column data = data[:min(len(data), 79-column)] else: column = min(column, 39) addr = line * 0x40 + column data = data[:min(len(data), 39-column)] self.communicator.write_command_byte(0x80|addr) self.communicator.write_data_bytes(string.encode()) return def clear_line(self, line): ''' line : 0 - the upper line, else the lower line (2-line mode) ''' self.write_string(line, 0, ' '*20) return def clear_all(self): ''' Clear all display. ''' self.communicator.write_command_byte(0x01) return if __name__ == '__main__': communicator = pcf8574() lcd = LCD1602(communicator) lcd.reset() lcd.clear_all() lcd.write_string(0, 0, 'jhu0') while True: for line in range(2): for column in range(16): lcd.clear_all() lcd.write_string(line, column, '#') lcd.write_string(0, 0, "%s %s"%(line, column)) time.sleep(0.2) break if lcd.lines == 1: lcd.write_string(0, 0, "LCD1602 DISPLAY Farman@2019") else: lcd.write_string(0, 0, "LCD1602 DISPLAY") lcd.write_string(1, 0, "Farman@*") time.sleep(1) lcd.clear_line(0) time.sleep(1) lcd.clear_line(1) time.sleep(1) if lcd.lines == 1: lcd.write_string(0, 0, "LCD1602 DISPLAY Farman@2019") else: lcd.write_string(0, 0, "LCD1602 DISPLAY") lcd.write_string(1, 0, "Farman@*") time.sleep(1) lcd.clear_all() 

pcf8574.h

#ifndef __PCF8574_H__ #define __PCF8574_H__ #include <wiringPi.h> // in /usr/include #include <wiringPiI2C.h> // in /usr/include /* device_addr : I2C addr of PCF8574, which is hardware configurable. Use "sudo raspi-config" to enable I2C interface. Use "sudo apt install i2c-tools" to make command "i2cdetect" ready. I2C address of PCF8574 is hardware configurable, use "i2cdetect -y 1" for PCF8574 address detection after correct hardware connection. */ int pcf8574_init(int device_addr); /* device is get by pcf8574_init(). Low half of half_byte is actual value send. */ void pcf8574_write_half_command_byte(int device, char half_byte); /* device is get by pcf8574_init(). */ void pcf8574_write_command_byte(int device, char byte); /* device is get by pcf8574_init(). bytes[] contains bytes to send. n is length in byte of bytes[]. */ void pcf8574_write_command_bytes(int device, char bytes[], int n); /* device is get by pcf8574_init(). Low half of half_byte is actual value send. */ void pcf8574_write_half_data_byte(int device, char half_byte); /* device is get by pcf8574_init(). */ void pcf8574_write_data_byte(int device, char byte); /* device is get by pcf8574_init(). bytes[] contains bytes to send. n is length in byte of bytes[]. */ void pcf8574_write_data_bytes(int device, char bytes[], int n); #endif // #ifndef __PCF8574_H__

pcf8574.c

#include <unistd.h> #include "pcf8574.h" int pcf8574_init(int device_addr) { wiringPiSetupGpio(); return wiringPiI2CSetup(device_addr); } void pcf8574_write_half_command_byte(int device, char half_byte) { half_byte <<= 4; wiringPiI2CWrite(device, half_byte); usleep(50); half_byte |= 0x04; wiringPiI2CWrite(device, half_byte); usleep(50); half_byte ^= 0x04; wiringPiI2CWrite(device, half_byte); usleep(50); return; } void pcf8574_write_command_byte(int device, char byte) { pcf8574_write_half_command_byte(device, byte>>4); pcf8574_write_half_command_byte(device, byte); usleep(50); return; } void pcf8574_write_command_bytes(int device, char bytes[], int n) { int i; for(i=0; i<n; ++i) { pcf8574_write_command_byte(device, bytes[i]); } return; } void pcf8574_write_half_data_byte(int device, char half_byte) { half_byte <<= 4; half_byte |= 0x01; wiringPiI2CWrite(device, half_byte); //usleep(50); half_byte |= 0x04; wiringPiI2CWrite(device, half_byte); //usleep(50); half_byte ^= 0x04; wiringPiI2CWrite(device, half_byte); usleep(40); return; } void pcf8574_write_data_byte(int device, char byte) { pcf8574_write_half_data_byte(device, byte>>4); pcf8574_write_half_data_byte(device, byte); return; } void pcf8574_write_data_bytes(int device, char bytes[], int n) { int i; for(i=0; i<n; ++i) { pcf8574_write_data_byte(device, bytes[i]); } return; } 

pcf8574_test.c

 #include <stdio.h> #include "pcf8574.h" int main() { int device; device = init(); if (device < 0) { printf("I2C bus initialize failed ---.\n"); return 0; } int bus_width = 4; int lines = 2; int font_big = 0; int display_on = 1; int cursor_on = 0; int blink_on = 0; int display_entire_on = 1; int display_shift_increase = 1; char command; write_command_byte(device, 0x02); command = 0x20; command += bus_width==8 ? 0x10 : 0x00; command += lines==2 ? 0x08 : 0x00; command += font_big==1 ? 0x04 : 0x00; write_command_byte(device, command); command = 0x08; command += display_on==1 ? 0x04 : 0x00; command += cursor_on==1 ? 0x02 : 0x00; command += blink_on==1 ? 0x01 : 0x00; write_command_byte(device, command); write_command_byte(device, 0x01); command = 0x04; command += display_entire_on==1 ? 0x02 : 0x00; command += display_shift_increase==1 ? 0x01 : 0x00; write_command_byte(device, command); write_data_bytes(device, "0!", 12); return 0; }

lcd1602.h

#include <stdio.h> #include <string.h> #include <unistd.h> #include "pcf8574.h" /* CONNECTIONS OF LCD1602 PCF8574T ----------------- 01 - VSS 02 - VDD 03 -- V0 04 -- RS 04 - P0 05 -- RW 05 - P1 06 --- E 06 - P2 07 -- D0 08 -- D1 09 -- D2 10 -- D3 11 -- D4 09 - P4 12 -- D5 10 - P5 13 -- D6 11 - P6 14 -- D7 12 - P7 15 --- A 16 --- K */ /* hold the parameter of LCD1602 display lines, which is used by hd44780_write_string(). */ int hd44780_display_lines; /* device_addr : I2C addr of PCF8574, which is hardware configurable. Use "sudo raspi-config" to enable I2C interface. Use "sudo apt install i2c-tools" to make command "i2cdetect" ready. I2C address of PCF8574 is hardware configurable, use "i2cdetect -y 1" for PCF8574 address detection after correct hardware connection. return device id for further operation by other functions. */ int hd44780_init(int device_addr); void hd44780_reset( int device, // get by hd44780_init() int bus_width, // 8 - 8-bit bus, 4 - 4-bit bus int lines, // 1 - 1-line, 2 - 2-line, depend on LCD hardware. int font_big, // 1 - 8*10 font, 0 - 5*8 font int display_on, // 1 - entire display on, 0 - entire display off int cursor_on, // 1 - cursor on, 0 - cursor off int blink_on, // 1 - cursor blink on, 0 - cursor blink off. int display_entire_shift_on, // entire display shift : 1 - on, 0 - off int display_shift_increase // DDRAM address (cursor or blink): 1 - increase 0 -decrease ); void hd44780_write_string( int device, // get by hd44780_init() int line, // write to which line. If hd44780_display_lines==1, this parameter is ignored. int column, // write to which column, max column is 39 for hd44780_display_lines==2, else 79. char string[], // buffer contains string to write. int str_len // buffer length in byte. ); /* device : get by hd44780_init() line : which line to clear, 1 or 2. If hd44780_display_lines==1, this parameter is ignored. */ void hd44780_clear_line(int device, int line); /* device : get by hd44780_init() Clear all display. */ void hd44780_clear_all(int device);

lcd1602.c

#include "lcd1602.h" /* device_addr : I2C addr of PCF8574, which is hardware configurable. Use "sudo raspi-config" to enable I2C interface. Use "sudo apt install i2c-tools" to make command "i2cdetect" ready. I2C address of PCF8574 is hardware configurable, use "i2cdetect -y 1" for PCF8574 address detection after correct hardware connection. */ int hd44780_init(int device_addr) { return pcf8574_init(device_addr); } void hd44780_reset( int device, int bus_width, int lines, int font_big, int display_on, int cursor_on, int blink_on, int display_entire_shift_on, int display_shift_increase ) { hd44780_display_lines = lines; char command; pcf8574_write_command_byte(device, 0x02); command = 0x20; command += bus_width==8 ? 0x10 : 0x00; command += lines==2 ? 0x08 : 0x00; command += font_big==1 ? 0x04 : 0x00; pcf8574_write_command_byte(device, command); command = 0x08; command += display_on==1 ? 0x04 : 0x00; command += cursor_on==1 ? 0x02 : 0x00; command += blink_on==1 ? 0x01 : 0x00; pcf8574_write_command_byte(device, command); pcf8574_write_command_byte(device, 0x01); usleep(50000); command = 0x04; command += display_entire_shift_on==1 ? 0x02 : 0x00; command += display_shift_increase==1 ? 0x01 : 0x00; pcf8574_write_command_byte(device, command); return; } void hd44780_write_string( int device, int line, int column, char string[], int str_len ) { int addr; line = line < 1 ? line : 1; if (hd44780_display_lines == 1) { column = column < 79 ? column : 79; str_len = str_len < 79 - column ? str_len : 79 - column; addr = column; } else { column = column < 39 ? column : 39; str_len = str_len < 39 - column ? str_len : 39 - column;; addr = line * 0x40 + column; } pcf8574_write_command_byte(device, 0x80 | addr); pcf8574_write_data_bytes(device, string, str_len); return; } void hd44780_clear_line(int device, int line) { char blanks[80]; int n; for (n=0; n<80; ++n) { blanks[n] = 0x20; // ' ' } hd44780_write_string(device, line, 0, blanks, 80); return; } void hd44780_clear_all(int device) { pcf8574_write_command_byte(device, 0x01); usleep(1600); return; } 

lcd1602_test.c

#include "lcd1602.h" int main() { int device = hd44780_init(0x27); if (device < 0) { printf("Init PCF8574 Failed."); return 0; } hd44780_reset(device, 4, 2, 1, 1, 0, 0, 1, 0); hd44780_clear_all(device); hd44780_write_string(device, 0, 0, "Too young, ", 16); hd44780_write_string(device, 1, 0, "Too naive, boy!!", 16); //return 0; sleep(2); hd44780_clear_all(device); int n; char buf[40]; for (n=0; n<64; ++n) { sprintf(buf, "%016X", n); hd44780_write_string(device, 1, 0, buf, strlen(buf)); usleep(50000); } return 0; }

command for compile and run

rm pcf gcc -Wall -o pcf pcf8574.c lcd1602.c lcd1602_test.c -lwiringPi ./pcf

That's all.

版权声明


相关文章:

  • vue2到vue3的极简迁移之路2024-10-21 17:30:02
  • JS switch 语句格式 使用方法2024-10-21 17:30:02
  • js switch语句多个条件相同处理写法2024-10-21 17:30:02
  • nftables(6)表达式(4)使用举例2024-10-21 17:30:02
  • 在Ubuntu下rtorrent编译安装笔记2024-10-21 17:30:02
  • 树莓派 lcd16022024-10-21 17:30:02
  • vite vue3 typescript2024-10-21 17:30:02
  • 扩展pci express2024-10-21 17:30:02
  • 使用HiPrint批量打印条码,二维码2024-10-21 17:30:02
  • openwrt esir2024-10-21 17:30:02