|
本人是用GCC写的,可能有很多漏洞请求指出,谢谢!
源程序奉上:
#include<avr/io.h>
#include<avr/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define lcm_bus_ddr DDRB
#define lcm_bus_out PORTB
#define lcm_bus_in PINB
uchar col,row;
#define lcm_rs PA7
#define lcm_rw PD1
#define lcm_e PD2
#define lcm_rest PA1
#define lcm_cs1 PA0
#define lcm_cs2 PA2
#define lcm_cs3 PA3
#define lcm_rest_h PORTA|=_BV(PA1)
#define lcm_rest_l PORTA&=~_BV(PA1)
#define lcm_rs_h PORTA|=_BV(PA7)
#define lcm_rs_l PORTA&=~_BV(PA7)
#define lcm_rw_h PORTD|=_BV(PD1)
#define lcm_rw_l PORTD&=~_BV(PD1)
#define lcm_e_h PORTD|=_BV(PD2)
#define lcm_e_l PORTD&=~_BV(PD2)
#define lcm_cs1_h PORTA|=_BV(PA0)
#define lcm_cs1_l PORTA&=~_BV(PA0)
#define lcm_cs2_h PORTA|=_BV(PA2)
#define lcm_cs2_l PORTA&=~_BV(PA2)
#define lcm_cs3_h PORTA|=_BV(PA3)
#define lcm_cs3_l PORTA&=~_BV(PA3)
#define lcm_read_status() (lcm_bus_in&0x80)
/*****************************************
延时函数
*****************************************/
void delay(uchar ms)
{
uchar i;
for(i=0;i<ms;i++)
_delay_loop_2(8*250);
}
/*****************************************
分区操作允许等待,返回时保留分区选择状态
函数功能:选择LCM的分区
*****************************************/
void lcm_busy(uchar back)
{
if(back==1)
{
lcm_cs1_l;
lcm_cs2_h;
lcm_cs3_h;
wtcom();
}
else if(back==2)
{
lcm_cs1_h;
lcm_cs2_l;
lcm_cs3_h;
wtcom();
}
else if(back==3)
{
lcm_cs1_h;
lcm_cs2_h;
lcm_cs3_l;
wtcom();
}
}
/**************************************
函数功能:等待LCM使能
**************************************/
void wtcom(void)
{
lcm_bus_ddr=0x00;
lcm_rs_l;
lcm_rw_h;
lcm_e_h;
asm("nop");
while(lcm_read_status()==0x80)
{
lcm_rest_l;
}
lcm_e_l;
lcm_bus_ddr=0xff;
}
/*************************************
命令输出到控制口
*************************************/
void wrcmd(int x)
{
uchar i;
for(i=1;i<4;i++)
{
lcm_busy(i);//选择分区
lcm_rs_l;
lcm_rw_l;
asm("nop");
lcm_bus_ddr=0xff;//定义输出
lcm_bus_out=x;//数据输出
lcm_e_h;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
lcm_e_l;
}
}
/***********************************
将坐标(col,row)转为x命令,
y命令,选中DDRAM中的行列地址
***********************************/
void locatexy(void)
{
int x,y;
switch(col&0xc0)
{
case 0:{lcm_busy(1);break;}//左区显示
case 0x40:{lcm_busy(2);break;}//中区显示
case 0x80:{lcm_busy(3);break;}//右区显示
}
x=(col&0x3f)|0x40;
y=(row&0x07)|0xb8;
wtcom();
asm("nop");
lcm_rs_l;
lcm_rw_l;
asm("nop");
lcm_bus_ddr=0xff;
lcm_bus_out=y;
lcm_e_h;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
lcm_e_l;
wtcom();
lcm_rs_l;
lcm_rw_l;
asm("nop");
lcm_bus_ddr=0xff;
lcm_bus_out=x;
lcm_e_h;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
lcm_e_l;
}
/************************************
将数据x的值,写入坐标(col,row)
************************************/
void wrdata(int x)
{
locatexy();
wtcom();
lcm_rs_h;
lcm_rw_l;
asm("nop");
lcm_bus_ddr=0xff;
lcm_bus_out=x;
lcm_e_h;
asm("nop");
lcm_e_l;
}
/*****************************************
液晶初始化
*****************************************/
void lcm_init(void)
{
wrcmd(0x3e);//关显示
asm("nop");
wrcmd(0x3f);//开显示
asm("nop");
wrcmd(0xc0);//显示第一行
lcm_clear(0,0,192,8);//清屏,全屏清零
}
/*****************************************
清屏函数:坐标方式清除子程序
*****************************************/
void lcm_clear(uchar x1,uchar y1,uchar x2,uchar y2)
{
for(row=y1;row<y2;row++)
{
for(col=x1;col<x2;col++)
wrdata(0x00);
}
}
/***************************************
端口初始化
***************************************/
void PORT_init(void)
{
DDRA=0X0F;
DDRB=0XFF;
DDRD=0X0F;
PORTA=0X8F;
PORTB=0X00;
PORTD=0X06;
}
/****************************************
主函数:1、初始化端口
2、复位关闭
3、初始化液晶
4、开左显示区域
5、写数据0xf0
6、点亮(5,5)坐标的点
****************************************/
int main(void)
{
PORT_init();
delay(100);
while(1)
{
lcm_rest_h;
lcm_init();
col=0xb8;
row=0x40;
locatexy();
wrdata(0xf0);
delay(5);
}
}
关键是无显示内容,什么都没有,很头痛 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|