Skip to content

Instantly share code, notes, and snippets.

@donghee
Last active March 10, 2020 19:08
Show Gist options
  • Save donghee/00d1cd293241182eeaf5 to your computer and use it in GitHub Desktop.
Save donghee/00d1cd293241182eeaf5 to your computer and use it in GitHub Desktop.
TM4C Launchpad: i2c lcd from switch-science
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/i2c.h"
void initI2C(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
// Set up the pins as I2C
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
GPIOPinConfigure(GPIO_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);
// master enable
I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);//false for 100kHz mode
I2CMasterEnable(I2C0_BASE);
}
void I2C_byte(unsigned char slave_address, unsigned char data) {
volatile int i = 0;
// start I2C transmit
I2CMasterSlaveAddrSet(I2C0_BASE, slave_address, false);
I2CMasterDataPut(I2C0_BASE, data);
while(I2CMasterBusy(I2C0_BASE)) {} // Check, the bus isn't busy (low?)
// Single Byte
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(I2CMasterBusy(I2C0_BASE)) {} //wait
}
void I2C_write(unsigned char slave_address, unsigned char *data, unsigned long length)
{
volatile int i = 0;
if (length == 1) {
I2C_byte(slave_address, *(data));
return;
}
// start I2C transmit
I2CMasterSlaveAddrSet(I2C0_BASE, slave_address, false);
I2CMasterDataPut(I2C0_BASE, *(data));
while(I2CMasterBusy(I2C0_BASE)) {} // Check, the bus isn't busy (low?)
// Multi Bytes
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
while(I2CMasterBusy(I2C0_BASE)) {} // delay until complete
for(i=1; i < length; i++) {
I2CMasterDataPut(I2C0_BASE, *(data+i));
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
while(I2CMasterBusy(I2C0_BASE)) {} //wait
}
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
while(I2CMasterBusy(I2C0_BASE)) {} // delay until complete
}
unsigned char AQCM0802_addr = 0x3e;
unsigned char mode;
unsigned char contrast = 0; // 0-63
unsigned char contrastFlag = false;
int CGcounter;
int FADEcounter;
void lcd_cmd(char x) {
unsigned char data[2];
data[0] = 0x00; // CO = 0,RS = 0
data[1] = x;
I2C_write(AQCM0802_addr, data, 2);
}
void lcd_contdata(char x) {
unsigned char data[2];
data[0] = 0xC0; //0b11000000 CO = 1, RS = 1
data[1] = x;
I2C_write(AQCM0802_addr, data, 2);
}
void lcd_lastdata(char x) {
unsigned char data[2];
data[0] = 0x40; //0b11000000 CO = 0, RS = 1
data[1] = x;
I2C_write(AQCM0802_addr, data, 2);
}
void lcd_printStr(const char *s) {
while(*s) {
if(*(s)) {
// if(*(s+1)) { // origin from switch-science mag : http://mag.switch-science.com/2013/07/17/i2c-lcd-breakout/ , but duplicate print last charactor!
lcd_contdata(*s);
} else {
lcd_lastdata(*s);
}
s++;
}
}
void lcd_printHex(unsigned char num) {
lcd_contdata(num);
lcd_lastdata(' ');
}
void lcd_clear()
{
lcd_cmd(0x01); // Clear Display
//wait(0.2);
SysCtlDelay(10000);
}
void lcd_init() {
// wait(0.04);
SysCtlDelay(400000);
// LCD initialize
lcd_cmd(0x38); // function set
lcd_cmd(0x39); // function set
lcd_cmd(0x04); // EntryModeSet
lcd_cmd(0x14); // interval osc
lcd_cmd(0x70 | (contrast & 0xF)); // contrast Low
lcd_cmd(0x5C | ((contrast >> 4) & 0x3)); // contast High/icon/power
lcd_cmd(0x6C); // follower control
//wait(0.2);
SysCtlDelay(2000000);
lcd_cmd(0x38); // function set
lcd_cmd(0x0C); // Display On
lcd_clear();
}
void lcd_setContrast(unsigned char c) {
lcd_cmd(0x39);
lcd_cmd(0x70 | (c & 0x0f)); // contrast Low
lcd_cmd(0x5C | ((c >> 4) & 0x03)); // contast High/icon/power
lcd_cmd(0x38);
}
void lcd_setCursor(unsigned char x,unsigned char y) {
lcd_cmd(0x80 | (y * 0x40 + x));
}
char* itoa(int i, char b[]){
char const digit[] = "0123456789";
char* p = b;
if(i<0){
*p++ = '-';
i *= -1;
}
int shifter = i;
do{ //Move to where representation ends
++p;
shifter = shifter/10;
}while(shifter);
*p = '\0';
do{ //Move back, inserting digits as u go
*--p = digit[i%10];
i = i/10;
}while(i);
return b;
}
int main () {
char buffer[8];
initI2C();
lcd_init();
lcd_setContrast(30);
while(1) {
for (int i = 100;i >= 0;i--) {
lcd_setCursor(0, 0);
lcd_printStr("TimeBoom");
lcd_setCursor(0, 1);
lcd_printStr(itoa(i,buffer));
SysCtlDelay(10000000);
lcd_clear();
}
}
}
@donghee
Copy link
Author

donghee commented May 19, 2017

fix to send last byte twice.

Need to test!

void lcd_cmd(char x) {
unsigned char data[3];
data[0] = 0x00; // CO = 0,RS = 0
data[1] = x;
data[1] = 0x00;
I2C_write(AQCM0802_addr, data, 3);
}

void I2C_write(unsigned char slave_address, unsigned char *data, unsigned long length)
{
  volatile int i = 0;
  
  if (length == 1) {
    I2C_byte(slave_address, *(data));
    return;
  }
  
  // start I2C transmit
  I2CMasterSlaveAddrSet(I2C0_BASE, slave_address, false);
  I2CMasterDataPut(I2C0_BASE, *(data));  
  while(I2CMasterBusy(I2C0_BASE)) {} // Check, the bus isn't busy (low?)
  // Multi Bytes
  I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
  while(I2CMasterBusy(I2C0_BASE)) {} // delay until complete
  
  for(i=1; i < length-1; i++) {
    I2CMasterDataPut(I2C0_BASE, *(data+i));
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
    while(I2CMasterBusy(I2C0_BASE)) {}    //wait
  }

  I2CMasterDataPut(I2C0_BASE, *(data+length-1));
  I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
  while(I2CMasterBusy(I2C0_BASE)) {} // delay until complete
  
  
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment