MSP430F5529LP (I) HELLOWRLD of IIC and OLED
[Copy link]
Briefly understand what IIC is.
I2C (Inter-Integrated Circuit BUS) is an integrated circuit bus designed by NXP (formerly PHILIPS). It is mostly used for master-slave communication between the master controller and the slave device. It is used in situations with small data volumes, short transmission distances, and only one host at any time.
Bus signal:
SDA: Serial Data Line
SCL: Serial Clock
Bus idle state:
SDA: High level
SCL: High level
Start bit: SDA has a falling edge during SCL is high level
End bit: SDA has a rising edge during SCL is high level
Data transmission: SDA data is written to the slave during SCL high level. Therefore, the data change of SDA must occur during SCL low level.
#ifndef _IIC_H
#define _IIC_H
#include "msp430f5529.h"
//IIC communication interface pin output macro definition
#define SCL_HIGH P6OUT|=BIT3 //Define the output when pin 6.3 is high level
#define SCL_LOW P6OUT&=~BIT3 //Define the output when pin 6.3 is low level
#define SDA_HIGH P6OUT|=BIT4 //Define the output when pin 6.4 is high level
#define SDA_LOW P6OUT&=~BIT4 //Define the output when pin 6.4 is low level
#define XLevelL 0x00 // low address
#define XLevelH 0x10 // high address
#define XLevel ((XLevelH&0x0F)*16+XLevelL)
#define Max_Column 128 // maximum screen pixel width
#define Max_Row 64 // maximum screen pixel width
#define Brightness 0xCF // IIC starting address
#define X_WIDTH 128 // screen pixel width
#define Y_WIDTH 64 // screen pixel height
void IIC_delayus(unsigned int i);
void IIC_ioinit(void); // initialize IIC
void IIC_start(void); // start IIC communication
void IIC_stop(void); // end IIC communication
void IIC_writebyte(unsigned char IIC_byte); // write byte
void IIC_writecmd(unsigned char IIC_command); // write command
void IIC_writedata(unsigned char IIC_data);//write data
void LCD_Set_Pos(unsigned char x, unsigned char y);//set display position
void LCD_CLS(void);//clear screen
void LCD_Init(void);//OLED screen initialization
void LCD_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size);//display character
void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size);//display string
void LCD_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size2);//display number
unsigned long oled_pow(unsigned char m,unsigned char n);//Character power function
#endif //_IIC_H
#include "IIC.h"
#include "font.h"
//Delay function delay=4*i
void IIC_delayus(unsigned int i)
{
unsigned int j,k;
for(k=0;k<i;k++)
for(j=0;j<4;i++);
}
//IIC initialization function
void IIC_ioinit()
{
P6DIR|=BIT1|BIT2|BIT3|BIT4; //Configure IIC IO port to output direction
P6REN|=BIT3|BIT4; //Configure IIC IO port to enable pull-up resistor
P6OUT&=~BIT1; //6.1 pull high
P6OUT|=BIT2; //6.2 pull low
}
//Start an IIC communication
void IIC_start()
{
//Generate a rising edge of the signal
SCL_HIGH; //SCL pulls high
SDA_HIGH; //SDA pulls high
//Next, generate a falling edge of the SDA signal. Note that SDA must be pulled low before SCL here
//IIC_delayus(2);
SDA_LOW; //SDA pulls low
//IIC_delayus(2);
SCL_LOW; //SCL pulls low
//Host starts reading and writing signals
}
//Stop IIC communication
void IIC_stop()
{
SCL_LOW;
SDA_LOW;
//IIC_delayus(2);
//Next, generate the rising edge of the SDA signal. Note that SCL must be pulled high before SDA.
SCL_HIGH;
SDA_HIGH;
//IIC_delayus(2);
}
//IIC sends a byte
void IIC_writebyte(unsigned char IIC_byte)
{
unsigned char i;
//A byte is 8 bits. Therefore, the loop starts from 0 to 7 and writes data 8 times in total
for(i=0;i<8;i++)
{
if(IIC_byte&0x80) //If 8 bytes are fully written and not 0
SDA_HIGH;//Pull up the SDA signal
else//8 bytes are not fully written
SDA_LOW;//Write 0
SCL_HIGH;//Pull up SCL to end one-bit writing
SCL_LOW;//Pull down SCL to make SDA writable
IIC_byte<<=1; //IIC_byte is shifted left by one bit, so the name suggests.//Assuming
that the IIC_byte data is character c, then its binary value is 01100011. The value written to the register is
//11000110 for the first loop
//10001100 for the second loop
//00011000 for the third loop
//Fourth loop 00110000
//Fifth loop 01100000
//Sixth loop 11000000
//Seventh loop 10000000
//Eighth loop 00000000 All are 0, pull SDA high
}
SDA_HIGH;//Resume pulling SDA high
SCL_HIGH;//Resume pulling SCL high
SCL_LOW;//Pull SCL low and wait for SDA level change
}
void IIC_writecmd(unsigned char IIC_command)
{
IIC_start();
IIC_writebyte(0x78); //Slave address, SA0=0 Slave register address
IIC_writebyte(0x00); //Send command Write command
IIC_writebyte(IIC_command); //Write command
IIC_stop(); //End IIC communication
}
void IIC_writedata(unsigned char IIC_data)
{
IIC_start();
IIC_writebyte(0x78); //IIC writes the starting address of the slave device
IIC_writebyte(0x40); //write data
IIC_writebyte(IIC_data); //write character data
IIC_stop();
}
/**************************LCD sets coordinates*******************************/
void LCD_Set_Pos(unsigned char x, unsigned char y)
{
//OLED register instruction set, see OLED chip manual
IIC_writecmd(0xb0+y);
IIC_writecmd(((x&0xf0)>>4)|0x10);
IIC_writecmd((x&0x0f)|0x01);
}
/******************************LCD Reset************************ ****************/
void LCD_CLS(void)
{
unsigned char y,x;
for(y=0;y<8;y++)
{
IIC_writecmd(0xb0+y);
IIC_writecmd (0x01);
IIC_writecmd(0x10);
for(x=0;x<X_WIDTH;x++)
IIC_writedata(0);
}
}
/******************************LCD initialization************************ ****************/
void LCD_Init(void)
{
IIC_ioinit();
IIC_writecmd(0xAE); //display off
IIC_writecmd(0x20); //Set Memory Addressing Mode
IIC_writecmd(0x10 ); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
IIC_writecmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
IIC_writecmd(0xc8 ); //Set COM Output Scan Direction
IIC_writecmd(0x00);//---set low column address
IIC_writecmd(0x10);//---set high column address
IIC_writecmd(0x40);//--set start line address
IIC_writecmd(0x81);//--set contrast control register
IIC_writecmd(0x7f);
IIC_writecmd(0xa1);//--set segment re-map 0 to 127
IIC_writecmd(0xa6);//--set normal display
IIC_writecmd(0xa8);//--set multiplex ratio(1 to 64 )
IIC_writecmd(0x3F);//
IIC_writecmd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
IIC_writecmd(0xd3);//-set display offset
IIC_writecmd(0x00);//-not offset
IIC_writecmd (0xd5);//--set display clock divide ratio/oscillator frequency
IIC_writecmd(0xf0);//--set divide ratio
IIC_writecmd(0xd9);//--set pre-charge period
IIC_writecmd(0x22); //
IIC_writecmd(0xda);//--set com pins hardware configuration
IIC_writecmd(0x12);
IIC_writecmd(0xdb);//--set vcomh
IIC_writecmd(0x20);//0x20,0.77xVcc
IIC_writecmd(0x8d);//-- set DC-DC enable
IIC_writecmd(0x14);//
IIC_writecmd(0xaf);//--turn on oled panel
LCD_CLS();
LCD_Set_Pos(0,0);
}
//Display a character at the specified position, including partial characters
//x:0~127
//y:0~63
//mode:0, reverse display; 1, normal display
//size: select font 16/12
void LCD_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//Get the offset value
if(x>Max_Column-1)//If the character coordinate is greater than the maximum pixel value of the row, write to the beginning of the next row
{
x=0;
y=y+2;
}
if(Char_Size ==16)//If the character is exactly equal to 16 characters
{
LCD_Set_Pos(x,y);
for(i=0;i<8;i++)
IIC_writedata(F8X16[c*16+i]);
LCD_Set_Pos(x,y+1);
for(i=0;i<8;i++)
IIC_writedata(F8X16[c*16+i+8]);
}
else //Otherwise write to the next line
{
LCD_Set_Pos(x,y);
for(i=0;i<6;i++)
IIC_writedata(F6x8[c][i]);
}
}
//Display a character string
void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0') //Traverse the string, x+8 is equivalent to calling the display character function in a loop with 8 coordinates between each character until the string is empty
{
LCD_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>128)
{
x=0;
y+=2;
}
j++;
}
}
//m^n function
unsigned long oled_pow(unsigned char m,unsigned char n)
{
unsigned long result=1;
while(n--)result*=m;
return result;
}
//Display a number. Take the modulus of the number to get each digit and display it in the form of characters.
//When the input number is 9876 and the coordinates are 0,0,
//get each digit
. //First loop 9876%10=987 Remainder 6 6+'0'='6' Coordinate x=0 y=0
//Second loop 987%10=98 Remainder 7 7+'0'='7' Coordinate x=0+8=8 y=0
//Third loop 98%10=9 Remainder 6 6+'0'='7' Coordinate x=8+8=16 y=0
//Fourth loop 9%10=0 Remainder 9 9+'0'='9' Coordinate x=16+8=24 y=0
//Others and so on
void LCD_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size2)
{
unsigned char t,temp;
//unsigned char enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
LCD_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
|