CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Connecting lcd 4x20 i2c and Display TM1637

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guido_Batan



Joined: 20 May 2019
Posts: 7
Location: Argentina

View user's profile Send private message Visit poster's website

Connecting lcd 4x20 i2c and Display TM1637
PostPosted: Mon May 20, 2019 12:43 am     Reply with quote

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 (sergio-hugo@bol.com.br) #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: 19195

View user's profile Send private message

PostPosted: Mon May 20, 2019 2:08 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Mon May 20, 2019 5:40 am     Reply with quote

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: 19195

View user's profile Send private message

PostPosted: Mon May 20, 2019 8:26 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Mon May 20, 2019 11:58 am     Reply with quote

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!

Very Happy Very Happy Very Happy Idea Mr. Green
koyuncu.qcuk



Joined: 19 Feb 2016
Posts: 1

View user's profile Send private message

PostPosted: Tue Jan 10, 2023 6:38 am     Reply with quote

Guido_Batan Thanks a lot.
Only your code work for my design.
Most codes have acknowledge problem. Very Happy
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Tue Jan 10, 2023 12:02 pm     Reply with quote

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/
_________________
Humberto
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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