求助各路高手请教用430驱动12864(OCM12864-3_ks0108)
#include"msp430x54x.h"
#define uint unsigned int
#define uchar unsigned char
//LED配置
#define LED1 (1<<0)
#define LED1_H P1DIR|= LED1,P1OUT|= LED1
#define LED1_L P1DIR|= LED1,P1OUT&= ~LED1
//KS0108配置引脚
#define KS0108_RET (1<<6)
#define KS0108_RET_H P5DIR|= KS0108_RET,P5OUT|= KS0108_RET
#define KS0108_RET_L P5DIR|= KS0108_RET,P5OUT&= ~KS0108_RET
#define KS0108_RW (1<<4)
#define KS0108_RW_H P5DIR|= KS0108_RW,P5OUT|= KS0108_RW
#define KS0108_RW_L P5DIR|= KS0108_RW,P5OUT&= ~KS0108_RW
#define KS0108_EN (1<<5)
#define KS0108_EN_H P5DIR|= KS0108_EN,P5OUT|= KS0108_EN
#define KS0108_EN_L P5DIR|= KS0108_EN,P5OUT&= ~KS0108_EN
#define KS0108_CS1 (1<<4)
#define KS0108_CS1_H P9DIR|= KS0108_CS1,P9OUT|= KS0108_CS1
#define KS0108_CS1_L P9DIR|= KS0108_CS1,P9OUT&= ~KS0108_CS1
#define KS0108_CS2 (1<<5)
#define KS0108_CS2_H P9DIR|= KS0108_CS2,P9OUT|= KS0108_CS2
#define KS0108_CS2_L P9DIR|= KS0108_CS2,P9OUT&= ~KS0108_CS2
#define KS0108_RS (1<<6)
#define KS0108_RS_H P9DIR|= KS0108_RS,P9OUT|= KS0108_RS
#define KS0108_RS_L P9DIR|= KS0108_RS,P9OUT&= ~KS0108_RS
#define KS0108_LCD (1<<7)
#define KS0108_LCD_H P9DIR|= KS0108_LCD,P9OUT|= KS0108_LCD
#define KS0108_LCD_L P9DIR|= KS0108_LCD,P9OUT&= ~KS0108_LCD
//==============================================================================
//KS0108配置 ,指令宏定义
#define Display_On 0x3f //显示开指令
#define Display_Off 0x3e //显示关指令
#define Y_Col_Addr 0x40 //定位到第0列指令(列起始地址)(0-63)
#define X_Page_Addr 0xb8 //定位到第0页指令(页起始地址)(0-7)
#define Start_Line 0xc0 //定位从DDROM中的第0行开始往屏幕上显示
//==============================================================================
void Init_Clk(void);
void delay(int n);
void delay1 (uint ms);
/*--------------------------------------------------------------*/
//函数声明
void LCD_pos(unsigned char x, unsigned char y); //液晶定位(8*8)
void SetStartLine(unsigned char startline);
void init_ks0108(void);
void Lcd_clear(void) ;
void AllScreen(void) ;
void Write_command(unsigned char command) ;
void Write_data(unsigned char data) ;
void main()
{
WDTCTL = WDTPW + WDTHOLD; //停止看门狗定时器
//P11DIR |= BIT2 + BIT1 + BIT0; //P11:012设为输出模式
//P11SEL |= BIT2 + BIT1 + BIT0; //设为第二功能作为频率输出
Init_Clk(); //时钟初始化
init_ks0108();
while(1)
{
LED1_H;
//LCD_pos(5, 2);
Write_command(0xb8);
Write_command(0x40);
Write_data(0xff);
AllScreen();
LED1_L;
delay1(400);
}
}
//delay
void delay(int n)
{
while(n--);
}
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1000;j++)
;
}
//时钟初始化
void Init_Clk(void)
{
P7SEL |= 0x03; // Port select XT1
UCSCTL6 &= ~(XT1OFF); // Set XT1 On
UCSCTL6 |= XCAP_3; // Internal load cap
UCSCTL3 |= SELREF_0; // 选 FLL 时钟源
UCSCTL4 = SELA_0 + SELM_4 + + SELS_4; //选时钟源:ACLK = XT1 = 32768Hz, MCLK = SMCLK = 8MHz
UCSCTL5 = DIVPA_0 + DIVA_0 + DIVM_0 + DIVS_0;
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
UCSCTL2 = FLLD_1 + 243; // Set DCO Multiplier for 8MHz
// (N + 1) * FLLRef = Fdco
// (243 + 1) * 32768 = 8MHz
// Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0); // Enable the FLL control loop
// Loop until XT1,XT2 & DCO stabilizes
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}
while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
//KS0108
//==============================================================================
//检查忙标志位
void chk_busy (void)
{
unsigned char lcd_status;
P10OUT = 0XFF;
P10DIR= 0x00;//设为输入口
KS0108_RS_L;
KS0108_RW_H;
do
{
KS0108_EN_H;
delay1(10);
KS0108_EN_L;
lcd_status = P10IN;
//delay1(10);
//KS0108_EN_L;
}
while((lcd_status&0x80)!=0);
P10DIR= 0xFF;
}
//==============================================================================
//写命令
void Write_command(unsigned char command)
{
chk_busy ();
KS0108_RS_L;
KS0108_RW_L;
P10DIR|= 0xFF,
P10OUT = command;
KS0108_EN_H;
delay1(10);
KS0108_EN_L;
}
//==============================================================================
//写数据
void Write_data(unsigned char data)
{
chk_busy ();
KS0108_RS_H;
KS0108_RW_L;
P10DIR|= 0xFF,
P10OUT = data;
KS0108_EN_H;
delay1(10);
KS0108_EN_L;
}
//==============================================================================
//设定行地址(页)--X 0-7
void SetLine(unsigned char line)
{
line=(line&0x07); // 0<=line<=7
line=(line|0xb8); //1011 1xxx
Write_command(line);
}
//设定列地址--Y 0-63
void SetColumn(unsigned char column)
{
column=(column&0x3f); // 0=<column<=63
column=(column|0x40); //01xx xxxx
Write_command(column);
}
//设定显示开始行--XX
void SetStartLine(unsigned char startline) //0--63
{
startline=(startline&0x3f); //??0x3f
startline=(startline|0xc0); //1100 0000
Write_command(startline);
}
void SetOnOff(unsigned char onoff)
{
onoff=(0x3e | onoff); //0011 111x
Write_command(onoff);
}
//==============================================================================
//清屏
void Lcd_clear(void)
{
unsigned char j,k;
SetLine(0);
SetColumn(0);
for(k=0;k<8;k++)
{
SetLine(k); //第K页
delay1(1);
for(j=0;j<64;j++)
{
Write_data(0x00);
delay1(10);
}
}
}
//==============================================================================
//全屏显示
void AllScreen(void)
{
unsigned char j,k;
SetLine(0);
SetColumn(0);
for(k=0;k<8;k++)
{
SetLine(k); //第K页
delay1(1);
for(j=0;j<64;j++)
{
Write_data(0xff);
delay1(10);
}
}
Write_command(0x3f);
}
//==============================================================================
//初始化
void init_ks0108(void)
{
KS0108_CS1_L;
KS0108_CS2_L;
KS0108_RET_L;
delay(1000);
KS0108_RET_H;
Write_command(0x3e);
delay1(1000);
SetLine(0x00); // 设定页
delay1(100);
SetStartLine(0x00);
delay1(100);
SetColumn(0x00);
delay1(100);
Write_command(0x3f);
delay1(1000);
}
//==============================================================================
//液晶定位(8*8)
//液晶规划:
//x: 0 - 7 (行)
//y: 0 -15 (列)
void LCD_pos(unsigned char x, unsigned char y)
{
if(y < 8)
{
//左半屏
KS0108_CS1_L;
KS0108_CS2_H;
}
else
{
y -= 8;
KS0108_CS1_H;
KS0108_CS2_L;
} //右半屏
Write_command(X_Page_Addr + x); //页地址
Write_command(Y_Col_Addr + (y * 8));//列地址 |