MSP430F5529LP(一)IIC與OLED的HELLOWRLD

簡單理解下什麼是IIC
I2C(Inter-Integrated Circuit BUS) 集成電路總線,該總線由NXP(原PHILIPS)公司設計,多用於主控制器和從器件間的主從通訊,在小數據量場合使用,傳輸距離短,任意時刻只能有一個主機等特性。
總線信號 :ide

  SDA :串行數據線函數

  SCL :串行時鐘字體

總線空閒狀態 :ui

  SDA :高電平設計

  SCL :高電平code

起始位:SCL爲高電平期間 SDA出現降低沿 輸入圖片說明
終止位:SCL爲高電平期間 SDA出現上升沿
輸入圖片說明
數據傳輸 :SDA的數據在SCL高電平期間被寫入從機。因此SDA的數據變化要發生在SCL低電平期間。
輸入圖片說明 先簡單寫出IIC.h頭文件orm

#ifndef _IIC_H
#define _IIC_H
#include 	"msp430f5529.h"
//IIC通訊接口引腳輸出宏定義
#define   SCL_HIGH    P6OUT|=BIT3  //定義引腳6.3爲高電平時的輸出
#define   SCL_LOW     P6OUT&=~BIT3//定義引腳6.3爲低電平時的輸出
#define   SDA_HIGH    P6OUT|=BIT4//定義引腳6.4爲高電平時的輸出
#define   SDA_LOW     P6OUT&=~BIT4//定義引腳6.4爲低電平時的輸出


#define XLevelL           0x00//低位地址
#define XLevelH           0x10//高位地址
#define XLevel            ((XLevelH&0x0F)*16+XLevelL)
#define Max_Column        128//最大屏幕像素寬度
#define Max_Row           64 //最大屏幕像素寬度
#define Brightness        0xCF //IIC起始地址
#define X_WIDTH           128//屏幕像素寬度
#define Y_WIDTH           64 //屏幕像素高度
void IIC_delayus(unsigned int i);
void IIC_ioinit(void);//初始化IIC
void IIC_start(void);//開始IIC通訊
void IIC_stop(void);//結束IIC通訊
void IIC_writebyte(unsigned char IIC_byte);//寫字節
void IIC_writecmd(unsigned char IIC_command);//寫命令
void IIC_writedata(unsigned char IIC_data);//寫數據
void LCD_Set_Pos(unsigned char x, unsigned char y);//設置顯示位置
void LCD_CLS(void);//清屏
void LCD_Init(void);//OLED屏初始化
void LCD_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size);//顯示字符
void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size);//顯示字符串
void LCD_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size2);//顯示數字
unsigned long oled_pow(unsigned char m,unsigned char n);//字符求冪函數
#endif //_IIC_H
#include        "IIC.h"
#include "font.h"
//延時函數延時=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初始化函數
void IIC_ioinit()
{
  P6DIR|=BIT1|BIT2|BIT3|BIT4; //配置IIC IO口爲輸出方向
  P6REN|=BIT3|BIT4; //配置IIC IO口使能上拉電阻
  P6OUT&=~BIT1;//6.1 拉高
  P6OUT|=BIT2;//6.2 拉低
}


//開始一個IIC通訊
void IIC_start()
{
    //產生信號上升沿
   SCL_HIGH;//SCL拉高
   SDA_HIGH;//SDA拉高
//接下來產生SDA信號降低沿,注意,這裏SDA必定比SCL先拉低
   //IIC_delayus(2);
   SDA_LOW;//SDA拉低
   //IIC_delayus(2);
   SCL_LOW;//SCL拉低
//主機開始讀寫信號產生完畢
}


//中止IIC通訊
void IIC_stop()
{
     SCL_LOW;
     SDA_LOW;
     //IIC_delayus(2);
//接下來產生SDA信號上升沿,注意,這裏SCL必定比SDA先拉高
     SCL_HIGH;
     SDA_HIGH;
     //IIC_delayus(2);
}


//IIC發送一個byte
void IIC_writebyte(unsigned char IIC_byte)
{
   unsigned char i;
//一個字節8bit所以,循環從0開始到7共8次寫數據
   for(i=0;i<8;i++)  
   {
      if(IIC_byte&0x80)  //若是寫滿8字節且不爲0
        SDA_HIGH;//拉高SDA信號
      else//沒有寫滿8字節
        SDA_LOW;//寫入0
      SCL_HIGH;//拉高SCL結束一bit的寫
      SCL_LOW;//拉低SCL使得SDA可寫
      IIC_byte<<=1;   //IIC_byte左移一位,故名思意了
//假設IIC_byte數據爲字符c 那麼它的二進制就是01100011寫入寄存器就是
//第一遍循環11000110
//第二遍循環10001100
//第三遍循環00011000
//第四遍循環00110000
//第五遍循環01100000
//第六遍循環11000000
//第七遍循環10000000
//第八遍循環00000000 全爲0拉高SDA
   }
   SDA_HIGH;//恢復拉高SDA
   SCL_HIGH;//恢復拉高SCL
   SCL_LOW;//拉低SCL等待SDA電平變更
}


void IIC_writecmd(unsigned char IIC_command)
{
   IIC_start();
   IIC_writebyte(0x78);   //Slave address,SA0=0 從機寄存器地址
   IIC_writebyte(0x00);   //發送指令寫指令
   IIC_writebyte(IIC_command);//寫入指令
   IIC_stop();//結束IIC通訊
}


void IIC_writedata(unsigned char IIC_data)
{
    IIC_start();
    IIC_writebyte(0x78);   //IIC寫從機起始地址
    IIC_writebyte(0x40);   //write data寫數據
    IIC_writebyte(IIC_data);//寫入字符數據
    IIC_stop();
}


/**************************LCD 設置座標*******************************/
void LCD_Set_Pos(unsigned char x, unsigned char y)
{
//OLED寄存器指令集查看OLED芯片手冊
    IIC_writecmd(0xb0+y);
    IIC_writecmd(((x&0xf0)>>4)|0x10);
    IIC_writecmd((x&0x0f)|0x01);
}


/***************************LCD復位************************************/
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初始化************************************/
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);
}


//在指定位置顯示一個字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白顯示;1,正常顯示				 
//size:選擇字體 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-' ';//獲得偏移後的值			
  if(x>Max_Column-1)//若是,字符座標大於行最大像素值寫到下一行開始位置
  {
     x=0;
     y=y+2;
  }
  if(Char_Size ==16)//若是字符恰好等於16字符
  {
     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 //不然寫到下一行
   {	
     LCD_Set_Pos(x,y);
     for(i=0;i<6;i++)
     IIC_writedata(F6x8[c][i]);			
   }
}


//顯示一個字符號串
void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size)
{
   unsigned char j=0;
   while (chr[j]!='\0')//遍歷字符串,x+8至關於每一個字符間隔8個座標 循環調用顯示字符函數,直到字符串爲空
   {		
     LCD_ShowChar(x,y,chr[j],Char_Size);	
     x+=8;
     if(x>128)
     {
       x=0;
       y+=2;
     }
     j++;	
   }
}

//m^n函數
unsigned long oled_pow(unsigned char m,unsigned char n)
{
	unsigned long result=1;	 
	while(n--)result*=m;    
	return result;
}	



//顯示一個數字將數字取模獲取每一位的數字,以字符的形式顯示
//當輸入數字爲9876時座標爲0,0時
//取得每一位數
//第一遍循環 9876%10=987 餘6 6+'0'='6' 座標 x=0 y=0
//第二遍循環 987%10=98 餘7 7+'0'='7‘ 座標 x=0+8=8 y=0
//第三遍循環 98%10=9 餘6 6+'0'='7' 座標 x=8+8=16 y=0
//第四遍循環 9%10=0 餘9 9+'0'='9' 座標 x=16+8=24 y=0
//其餘以此類推
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); 
	}
}
相關文章
相關標籤/搜索