|
|
View previous topic :: View next topic |
Author |
Message |
Guido_Batan
Joined: 20 May 2019 Posts: 7 Location: Argentina
|
Connecting lcd 4x20 i2c and Display TM1637 |
Posted: Mon May 20, 2019 12:43 am |
|
|
Hi, I need to use the same i2c pins to connect a 20x4 lcd and a tm1637 display. But when I connect the 2 at the same time one does not turn on. Is this possible to do? Thanks
Pic16F887 Pic C compiler
code of tm1637:
Code: | //#use fast_io(B)
#define _BV(n) (1<<n)
#define PC4 4
#define PC3 3 //clock antes b6 b3
#define uint8_t unsigned int8
#define bool int8
#define _delay_us delay_us
#define _delay_ms delay_ms
#byte PORT_DIO = getenv("SFR:PORTC") //portb, como una simple variable de 8 bits
#byte DDR_DIO = getenv("SFR:TRISC") //Data Direction port b
#byte PIN_DIO = getenv("SFR:PORTC")
#byte DDR_CLK = getenv("SFR:TRISC") //Data Direction port b
#byte PORT_CLK = getenv("SFR:PORTC") //portb, como una simple variable de 8 bits
//#include <stdint.h>
//#include <avr/io.h>
//#include <util/delay.h>
// Main Settings
#define TM1637_DIO_PIN PC4 // Puerto del pic numero 33
#define TM1637_CLK_PIN PC3 // Puerto del pic numero 39
#define TM1637_DELAY_US (50)
#define TM1637_DEFAULT_BRIGHTNESS (2)
// TM1637 commands
#define TM1637_CMD_SET_DATA 0x40
#define TM1637_CMD_SET_ADDR 0xC0
#define TM1637_CMD_SET_DSIPLAY 0x80
// TM1637 data settings (use bitwise OR to contruct complete command)
#define TM1637_SET_DATA_WRITE 0x00 // write data to the display register
#define TM1637_SET_DATA_READ 0x02 // read the key scan data
#define TM1637_SET_DATA_A_ADDR 0x00 // automatic address increment
#define TM1637_SET_DATA_F_ADDR 0x04 // fixed address
#define TM1637_SET_DATA_M_NORM 0x00 // normal mode
#define TM1637_SET_DATA_M_TEST 0x10 // test mode
// TM1637 address settings (use bitwise OR to contruct complete command)
#define TM1637_SET_ADR_00H 0x00 // address 00
#define TM1637_SET_ADR_01H 0x01 // address 01
#define TM1637_SET_ADR_02H 0x02 // address 02
#define TM1637_SET_ADR_03H 0x03 // address 03
#define TM1637_SET_ADR_04H 0x04 // address 02
#define TM1637_SET_ADR_05H 0x05 // address 03
// TM1637 display control command set (use bitwise OR to consruct complete command)
#define TM1637_SET_DISPLAY_OFF 0x00 // off
#define TM1637_SET_DISPLAY_ON 0x08 // on
/**
* Initialize TM1637 display driver.
* Clock pin (TM1637_CLK_PIN) and data pin (TM1637_DIO_PIN)
* are defined at the top of this file.
*/
void TM1637_init(void);
/**
* Display digits ('0'..'9') at positions (0x00..0x03)
*/
void TM1637_display_digit( uint8_t addr, uint8_t digit);
/**
* Display raw segments at positions (0x00..0x03)
*
* bits: hex:
* -- 0 -- -- 01 --
* | | | |
* 5 1 20 02
* | | | |
* -- 6 -- -- 40 --
* | | | |
* 4 2 10 04
* | | | |
* -- 3 -- -- 08 --
*
* Example segment configurations:
* - for character 'H', segments=0b01110110
* - for character '-', segments=0b01000000
* - etc.
*/
void TM1637_display_segments( uint8_t addr, uint8_t segments);
/**
* Display colon on/off.
*/
void TM1637_display_colon(bool value);
/**
* Clear all display segments (including colon).
*/
void TM1637_clear(void);
/**
* Set display brightness.
* Min brightness: 0
* Max brightness: 7
*/
void TM1637_set_brightness( uint8_t brightness);
/**
* Turn display on/off.
*/
void TM1637_enable( bool value);
#define TM1637_DIO_HIGH() (PORT_DIO |= _BV(TM1637_DIO_PIN))
#define TM1637_DIO_LOW() (PORT_DIO &= ~_BV(TM1637_DIO_PIN))
#define TM1637_DIO_OUTPUT() (DDR_DIO &= ~_BV(TM1637_DIO_PIN))
#define TM1637_DIO_INPUT() (DDR_DIO |= _BV(TM1637_DIO_PIN))
#define TM1637_DIO_READ() (((PIN_DIO & _BV(TM1637_DIO_PIN)) > 0) ? 1 : 0)
#define TM1637_CLK_HIGH() (PORT_CLK |= _BV(TM1637_CLK_PIN))
#define TM1637_CLK_LOW() (PORT_CLK &= ~_BV(TM1637_CLK_PIN))
#define TM1637_FLAG_ENABLED (1 << 0)
#define TM1637_FLAG_SHOWCOLON (1 << 1)
static void TM1637_configure(void);
static void TM1637_cmd(uint8_t value);
static void TM1637_start(void);
static void TM1637_stop(void);
static uint8_t TM1637_write_byte(uint8_t value);
static uint8_t _digit2segments[] =
{
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
static uint8_t _brightness = TM1637_DEFAULT_BRIGHTNESS;
static uint8_t _digit = 0xff;
static uint8_t _flags = 0x00;
void TM1637_init(void)
{
DDR_DIO &= ~(_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
PORT_DIO &= ~(_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
_flags |= TM1637_FLAG_ENABLED;
TM1637_clear();
}
void TM1637_display_digit( uint8_t addr, uint8_t digit)
{
uint8_t segments = digit < 10 ? _digit2segments[digit] : 0x00;
if (addr == TM1637_SET_ADR_01H) {
_digit = digit;
if (_flags & TM1637_FLAG_SHOWCOLON) {
segments |= 0x80;
}
}
TM1637_display_segments(addr, segments);
}
void TM1637_display_segments( uint8_t addr, uint8_t segments)
{
TM1637_cmd(TM1637_CMD_SET_DATA | TM1637_SET_DATA_F_ADDR);
TM1637_start();
TM1637_write_byte(TM1637_CMD_SET_ADDR | addr);
TM1637_write_byte(segments);
TM1637_stop();
TM1637_configure();
}
void TM1637_display_colon(bool value)
{
if (value) {
_flags |= TM1637_FLAG_SHOWCOLON;
} else {
_flags &= ~TM1637_FLAG_SHOWCOLON;
}
TM1637_display_digit(TM1637_SET_ADR_01H, _digit);
}
void TM1637_clear(void)
{
TM1637_display_colon(false);
TM1637_display_segments(TM1637_SET_ADR_00H, 0x00);
TM1637_display_segments(TM1637_SET_ADR_01H, 0x00);
TM1637_display_segments(TM1637_SET_ADR_02H, 0x00);
TM1637_display_segments(TM1637_SET_ADR_03H, 0x00);
TM1637_display_segments(TM1637_SET_ADR_04H, 0x00);
TM1637_display_segments(TM1637_SET_ADR_05H, 0x00);
}
void TM1637_set_brightness( uint8_t brightness)
{
_brightness = brightness & 0x07;
TM1637_configure();
}
void TM1637_enable(bool value)
{
if (value) {
_flags |= TM1637_FLAG_ENABLED;
} else {
_flags &= ~TM1637_FLAG_ENABLED;
}
TM1637_configure();
}
void TM1637_configure(void)
{
uint8_t cmd;
cmd = TM1637_CMD_SET_DSIPLAY;
cmd |= _brightness;
if (_flags & TM1637_FLAG_ENABLED) {
cmd |= TM1637_SET_DISPLAY_ON;
}
TM1637_cmd(cmd);
}
void TM1637_cmd(uint8_t value)
{
TM1637_start();
TM1637_write_byte(value);
TM1637_stop();
}
void TM1637_start(void)
{
TM1637_DIO_HIGH();
TM1637_CLK_HIGH();
_delay_us(TM1637_DELAY_US);
TM1637_DIO_LOW();
}
void TM1637_stop(void)
{
TM1637_CLK_LOW();
_delay_us(TM1637_DELAY_US);
TM1637_DIO_LOW();
_delay_us(TM1637_DELAY_US);
TM1637_CLK_HIGH();
_delay_us(TM1637_DELAY_US);
TM1637_DIO_HIGH();
}
uint8_t TM1637_write_byte(uint8_t value)
{
uint8_t i, ack;
for (i = 0; i < 8; ++i, value >>= 1) {
TM1637_CLK_LOW();
_delay_us(TM1637_DELAY_US);
if (value & 0x01) {
TM1637_DIO_HIGH();
} else {
TM1637_DIO_LOW();
}
TM1637_CLK_HIGH();
_delay_us(TM1637_DELAY_US);
}
TM1637_CLK_LOW();
TM1637_DIO_INPUT();
TM1637_DIO_HIGH();
_delay_us(TM1637_DELAY_US);
ack = TM1637_DIO_READ();
if (ack) {
TM1637_DIO_OUTPUT();
TM1637_DIO_LOW();
}
_delay_us(TM1637_DELAY_US);
TM1637_CLK_HIGH();
_delay_us(TM1637_DELAY_US);
TM1637_CLK_LOW();
_delay_us(TM1637_DELAY_US);
TM1637_DIO_OUTPUT();
return ack;
}
|
code of lcd 4x20:
Code: |
//-----------------------------------------------------------------------------
// Title: i2c_Flex_LCD
// Description: Driver for common LCD with 1/2/3 or 4 row modules using PCF8574T interface board with I2C protocol.
// Date: Nov-2013
// Ver.Rev.: 1.0
// Author: Hugo Silva ([email protected]) #Based on the routines of 20X4_LCD_I2C_DRIVER.h from Pumrin S.
//-----------------------------------------------------------------------------
//
// lcd_init() Must be called before any other function.
//
// lcd_putc(c) Will display c on the next position of the LCD.
//
// \f Clear LCD dispay
// \1 Set write position on LCD Line 1
// \2 Set write position on LCD Line 2
// \3 Set write position on LCD Line 3
// \4 Set write position on LCD Line 4
//
// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)
//
//-----------------------------------------------------------------------------
// LCD pins D0-D3 are not used.
//-----------------------------------------------------------------------------
//
// Commment : Control of a compatible LCD HITACHI from a bus I2C with
// an EXPANDER of I/O with connection I2C. The tests of these
// routines have been programmed using the IC PCF8574T of Phillips.
// I used 4 bits mode programming. The 8 bits mode programming
// is possible if you use 2 x PCF8574T.
//
// As defined in the following structure the pin connection is as follows:
//
// PCF8574P LCD
// ======== ======
// P0 RS
// P1 RW
// P2 Enable
// P3 Led Backlight
// P4 D4
// P5 D5
// P6 D6
// P7 D7
//
// The SCL and SDA pins should be pull-up resistor as shown below:
//
// +5v
// |
// <
// > 4.7K
// <
//To PIC | To i2c slave
//pin xx ------------------ SDA pin
//(SDA)
// +5v
// |
// <
// > 4.7K
// <
//To PIC | To i2c slave
//pin xx ------------------ SCL pin
//(SCL)
//
//To PIC To i2c slave
//Vss pin ----------------- Vss or ground pin
// |
// -----
// --- Ground
// -
//
// THIS DOCUMENT IS PROVIDED TO THE USER "AS IS"
//-----------------------------------------------------------------------------
#define LCD_ADDR 0x4E //I2C slave address for LCD module
#define ON 1
#define OFF 0
#define RS 0b00000001 //P0 - PCF8574T Pin connected to RS
#define RW 0b00000010 //P1 - PCF8574T Pin connected to RW
#define EN 0b00000100 //P2 - PCF8574T Pin connected to EN
#define BACKLIGHT_LED 0b00001000 //P3 - PCF8574T Pin connected to BACKLIGHT LED
#define lcd_line_one 0x80 // LCD RAM address for line 1
#define lcd_line_two 0xC0 // LCD RAM address for line 2
#define lcd_line_three 0x94 // LCD RAM address for line 3
#define lcd_line_four 0xD4 // LCD RAM address for line 4
byte address;
int1 lcd_backlight=ON;
void i2c_send_nibble(unsigned char data)
{
i2c_start();
delay_us(20);
i2c_write(LCD_ADDR); //the slave addresse
delay_us(20);
i2c_write(data);
delay_us(20);
i2c_stop();
delay_us(20);
}
void lcd_send_byte(unsigned char data)
{
if (lcd_backlight) data=data|EN|BACKLIGHT_LED; else data=data|EN; //set pin EN
i2c_send_nibble(data);
data=data-4; //toggle EN back to 0
i2c_send_nibble(data);
}
void lcd_clear()
{
lcd_send_byte(0x00);
lcd_send_byte(0x10);
delay_ms(2);
}
void lcd_init()
{
delay_ms(200); //LCD power up delay
//Request works on the command by set the RS = 0 R/W = 0 write
lcd_send_byte(0x00);
lcd_send_byte(0x10);
lcd_send_byte(0x00);
lcd_send_byte(0x00);
lcd_send_byte(0x10);
//First state in 8 bit mode
lcd_send_byte(0x30);
lcd_send_byte(0x30);
//Then set to 4-bit mode
lcd_send_byte(0x30);
lcd_send_byte(0x20);
//mode 4 bits, 2 lines, characters 5 x 7 (28 h)
lcd_send_byte(0x20);
lcd_send_byte(0x80);
//no need cursor on (0Ch)
lcd_send_byte(0x00);
lcd_send_byte(0xC0);
//the cursor moves to the left (06 h)
lcd_send_byte(0x00);
lcd_send_byte(0x60);
//clears the display
lcd_clear();
}
void lcd_gotoxy( byte x, byte y)
{
static char data;
switch(y)
{
case 1: address= lcd_line_one; break;
case 2: address= lcd_line_two; break;
case 3: address= lcd_line_three; break;
case 4: address= lcd_line_four; break;
default: address= lcd_line_one; break;
}
address+=x-1;
data=address&0xF0;
lcd_send_byte(data);
data=address&0x0F;
data=data<<4;
lcd_send_byte(data);
}
//Display the character on LCD screen.
void LCD_PUTC(char in_data)
{
char data;
switch(in_data)
{
case '\f': lcd_clear() ; break;
case '\1': lcd_gotoxy(1,1); break;
case '\2': lcd_gotoxy(1,2); break;
case '\3': lcd_gotoxy(1,3); break;
case '\4': lcd_gotoxy(1,4); break;
default:
data=in_data&0xF0;
data=data|RS; //set RS pin to 1
lcd_send_byte(data);
data=in_data&0x0F;
data=data<<4;
data=data|RS; //set RS pin to 1
lcd_send_byte(data);
break;
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Mon May 20, 2019 2:08 am |
|
|
You need to move your display onto PORTB, instead of PORTC. The PIC I2C
pins are in the middle of PORTC.
You could also just use software I2C on different pins. |
|
|
Guido_Batan
Joined: 20 May 2019 Posts: 7 Location: Argentina
|
|
Posted: Mon May 20, 2019 5:40 am |
|
|
Hello Ttelmah, thanks for responding, now change the direction of the ports, lcd works, but disconnecting the screen and disconnecting the lcd works the screen, can I use both screens with the same pins?
Code: | //#use fast_io(B)
#define _BV(n) (1<<n)
#define PB4 4
#define PB3 3 //clock antes b6 b3
#define uint8_t unsigned int8
#define bool int8
#define _delay_us delay_us
#define _delay_ms delay_ms
#byte PORT_DIO = getenv("SFR:PORTB") //portb, como una simple variable de 8 bits
#byte DDR_DIO = getenv("SFR:TRISB") //Data Direction port b
#byte PIN_DIO = getenv("SFR:PORTB")
#byte DDR_CLK = getenv("SFR:TRISB") //Data Direction port b
#byte PORT_CLK = getenv("SFR:PORTB") //portb, como una simple variable de 8 bits
//#include <stdint.h>
//#include <avr/io.h>
//#include <util/delay.h>
// Main Settings
#define TM1637_DIO_PIN PB4 // Puerto del pic numero 33
#define TM1637_CLK_PIN PB3 // Puerto del pic numero 39
#define TM1637_DELAY_US (50)
#define TM1637_DEFAULT_BRIGHTNESS (2) |
Code: | #use i2c(master, Fast=40000, sda=PIN_B4, scl=PIN_B3)
#include <i2c_Flex_LCD.c> |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Mon May 20, 2019 8:26 am |
|
|
No.
I2C, requires it's pins running as 'open collector' devices. Not standard I/O.
Also, if the data patterns being sent to another device just happened to
have the sequence in them that triggered an I2C_start, the I2C device
could start to respond. You can't mix I2C on the same bus with another
device really. Unlike SPI, where an extra pin is needed, but when this is
not operated, the signal lines could be re-used, I2C offers no such ability. |
|
|
Guido_Batan
Joined: 20 May 2019 Posts: 7 Location: Argentina
|
|
Posted: Mon May 20, 2019 11:58 am |
|
|
Ttelmah, infinitely grateful for the answer. I had that doubt about whether i2c could be used together with the display. I understood the explanation perfectly. thank you very much blessings!
|
|
|
koyuncu.qcuk
Joined: 19 Feb 2016 Posts: 1
|
|
Posted: Tue Jan 10, 2023 6:38 am |
|
|
Guido_Batan Thanks a lot.
Only your code work for my design.
Most codes have acknowledge problem. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Tue Jan 10, 2023 12:02 pm |
|
|
It is a good practice to give credit to the author when using code of another and in
order to recognize the effort of who had shared his knowledge with the community.
The copyright of the posted code belongs to Ćukasz Marcin Podkalicki.
https://blog.podkalicki.com/atlib-getting-started/ _________________ Humber |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|