Last active
March 10, 2020 19:08
-
-
Save donghee/00d1cd293241182eeaf5 to your computer and use it in GitHub Desktop.
TM4C Launchpad: i2c lcd from switch-science
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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);
}