void spi2_init(void)
{
IFS1bits.SPI2IF = 0; // Clear the Interrupt Flag
IEC1bits.SPI2IE = 0; // Disable the Interrupt
SPI2CONbits.FRMEN = 0; // Internal Serial Clock is Enabled
SPI2CONbits.DISSDO = 0;
SPI2CONbits.MODE16 = 0; // Communication is byte-wide
SPI2CONbits.SMP = 0; //
SPI2CONbits.CKE = 0; // Idle state for clock is a high level;
SPI2CONbits.SSEN = 0; // Input data is sampled at the end of data
SPI2CONbits.CKP=0;
SPI2CONbits.MSTEN=1;
SPI2CONbits.SPRE = 0x05;
SPI2CONbits.PPRE = 0x00;
SPI2STATbits.SPIEN = 1; // Enable SPI module
SPI2STATbits.SPISIDL = 0;
}
#include <p30f5011.h>
//#include <spi.h>
#define FCY 7372800
#define __delay_ms(d) __delay32( (unsigned long) (d)*(FCY/1000))
#define __delay_us(d) __delay32( (unsigned long) (d)*(FCY/1000000))
_FOSC(CSW_FSCM_OFF & XT_PLL4); //4倍频晶振,Failsafe 时钟关闭
_FWDT(WDT_OFF); //关闭看门狗定时器
_FBORPOR(PBOR_OFF & MCLR_EN); //掉电复位禁止,MCLR复位使能。
_FGS(CODE_PROT_OFF); //代码保护禁止
// RST------RD11
// CS ----- RD10
// SID ---- RG8
// CLK ---- RG6
#define RST LATDbits.LATD11
#define CS LATDbits.LATD10
#define SID LATGbits.LATG8
#define CLK LATGbits.LATG6
void spi2_init(void)
{
IFS1bits.SPI2IF = 0; // Clear the Interrupt Flag
IEC1bits.SPI2IE = 0; // Disable the Interrupt
SPI2CONbits.FRMEN = 0; // Internal Serial Clock is Enabled
SPI2CONbits.DISSDO = 0;
SPI2CONbits.MODE16 = 0; // Communication is byte-wide
SPI2CONbits.SMP = 0; //
SPI2CONbits.CKE = 0; // Idle state for clock is a high level;
SPI2CONbits.SSEN = 0; // Input data is sampled at the end of data
SPI2CONbits.CKP=0;
SPI2CONbits.MSTEN=1;
SPI2CONbits.SPRE = 0x05;
SPI2CONbits.PPRE = 0x00;
SPI2STATbits.SPIEN = 1; // Enable SPI module
SPI2STATbits.SPISIDL = 0;
}
void spi_send(unsigned char data)
{
unsigned char tmp;
SPI2BUF = data;
while(SPI2STATbits.SPITBF);
tmp = SPI2BUF;
}
void lcd_send_com(unsigned char com)
{
CS=1;
spi_send(0xf8);
spi_send(com & 0xf0);
spi_send(com << 4);
CS=0;
if (com == 0x01)
__delay_us(1600); //1.6mS
else __delay_us(72); //72uS
}
void lcd_send_data(unsigned char data)
{
CS=1;
spi_send(0xfa);
spi_send(data & 0xf0);
spi_send(data << 4);
CS=0;
__delay_us(72);
}
void lcd_init(void)
{
CS = 0;
CLK = 0;
SID = 0;
RST=1;
__delay_ms(100);
spi2_init();
lcd_send_com(0x30); //基本指令动作
lcd_send_com(0x01); //清屏
lcd_send_com(0x06); //光标的移动方向
lcd_send_com(0x02); //地址归位
lcd_send_com(0x80);
lcd_send_com(0x0c); //开显示,关游标
}
void set_cursor(unsigned char row, unsigned char col)
{
unsigned char i;
switch(row)
{
case 0x00:i=0x80;break;
case 0x01:i=0x90;break;
case 0x02:i=0x88;break;
case 0x03:i=0x98;break;
default:break;
}
i=col+i;
lcd_send_com(i);
}
void display_string(unsigned char row, unsigned char col, const char *string)
{
set_cursor(row,col);
while(*string)
lcd_send_data(*string ++);
}
//任意行汉字的反白程序(固定高度为16dot)
void disp_reverse(unsigned char row)
{
//unsigned char i,j;
unsigned char addr_x,addr_y;
unsigned char uscol,usvalue;
lcd_send_com(0x36);
for(addr_y=0x80;addr_y<0xa0;addr_y++)
{
lcd_send_com(addr_y);
lcd_send_com(0x80);
for(addr_x=0;addr_x<16;addr_x++)
{
lcd_send_data(0);
}
}
for(addr_y=0x80;addr_y<0xa0;addr_y++)
{
lcd_send_com(addr_y);
lcd_send_com(0x88);
for(addr_x=0;addr_x<16;addr_x++)
{
lcd_send_data(0);
}
}
if((row&0x01)==0)
{ uscol=0x80;}
else
{ uscol=0x90;}
if((row>>1)==0)
{usvalue=0x80;}//st7920显示的第一、二行
else
usvalue=0x88; //st7920显示的第三、四行
for(addr_y=uscol;addr_y<(uscol+16);addr_y++)
{
lcd_send_com(addr_y);
lcd_send_com(usvalue);
for(addr_x=0;addr_x<16;addr_x++)
{
lcd_send_data(0xff);
}
}
// lcd_send_com(0x36);
lcd_send_com(0x30);
}
//========main=======================
int main(void)
{
TRISD&=0xF3FF;
TRISG&=0xF2BF;
RST=1;
lcd_init();
display_string(0,0,"LCD DRIVES OK.");
display_string(1,0,"IT'S VERY GOOD!");
display_string(2,0,"1.阿房宫建起了。");
display_string(3,0,"2.秦王朝倒下了。");
disp_reverse(2);
while(1);
return 0;
}
一周热门 更多>