/**********************************
*action: meg16 LCD1602控制程序
**********************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define RS_CLR PORTD &= ~(1 << 4)
#define RS_SET PORTD |= (1 << 4)
#define RW_CLR PORTD &= ~(1 << 5)
#define RW_SET PORTD |= (1 << 5)
#define EN_CLR PORTD &= ~(1 << 6)
#define EN_SET PORTD |= (1 << 6)
#define I_MAX 2000
#define U_MAX 2000
#define I_MIN 0
#define U_MIN 0
uint I=500; //当前电流
uint flag=0; //功能选择标志
uchar n;
uchar a='0',b='0',c='0',d='0',e='0';
void delay_us(uint n)
{
while(n--)
{
NOP();NOP();NOP();NOP();
NOP();NOP();NOP();NOP();
}
}
void delay_ms(uint n)
{
while(n--)
{
delay_us(1000);
}
}
void LCD_en_write() //产生一个下降沿脉冲来写入数据或命令
{
EN_SET;
delay_us(20);
EN_CLR;
delay_us(20);
}
void LCD_clear() //LCD清零
{
Write_CMD(0x01);
delay_ms(5);
}
void Write_CMD(uchar cmd)//写命令
{
RS_CLR;
RW_CLR;
EN_SET;
PORTB=cmd;
LCD_en_write();
}
void Write_Data(uchar data)//写数据
{
RS_SET;
RW_CLR;
EN_SET;
PORTB=data;
LCD_en_write();
}
void LCD_SET_XY(uchar X,uchar Y)//设置写入位置
{
uchar address;
Y==0?(address=0x80+X):(address=0xc0+X);
Write_CMD(address);
}
void LCD_write_str(uchar x,uchar y,uchar *s)//写入字符串
{
LCD_SET_XY(x,y);
while(*s)
{
Write_Data(*s);
s++;
}
}
void LCD_write_char(uchar x,uchar y,uchar data)//写入单个字符
{
LCD_SET_XY(x,y);
Write_Data(data);
}
void port_init()
{
PORTA=0XFF;
DDRA =0X00;
PORTB=0XFF;
DDRB =0X00;
PORTC=0X7F;
DDRC =0X80;
PORTD=0XFF;
DDRD =0X00;
}
void LCD_init()
{
DDRB=0xff;
DDRD|=(BIT(4)|BIT(5)|BIT(6));
delay_ms(15);
Write_CMD(0x38);
delay_ms(5);
Write_CMD(0x38);
delay_ms(5);
Write_CMD(0x38);
Write_CMD(0x08);
Write_CMD(0x01);
delay_ms(5);
Write_CMD(0x04);
delay_ms(5);
Write_CMD(0x0c);
}
void update() //数据更新
{
a=I/10000+'0';
b=I/1000%10+'0';
c=I/100%10+'0';
d=I/10%10+'0';
e=I%10+'0';
LCD_write_str(0,0,"I: mA");
LCD_write_str(0,1,"U: mV");
LCD_write_char(3,0,a);
LCD_write_char(4,0,b);
LCD_write_char(5,0,c);
LCD_write_char(6,0,d);
LCD_write_char(7,0,e);
}
/*********************************
以下键盘输入函数
*********************************/
void key_1()
{
if(I<=I_MAX-10)
if(flag%2==0)I+=10;
else I+=1;
update();
//LCD_clear();
}
void key_2()
{
if(I>=I_MIN+10)
if(flag%2==0)I-=10;
else I-=1;
update();
}
void key_3()
{
flag++;
}
void key_4()//输出接口
{
;
}
void key_scan(void)
{
unsigned char key;
DDRB = 0XFF;
DDRD = 0Xff;
PORTD = 0Xff;
if(PIND != 0XFF) //检测D口电平,如果全是高电平则退出
{
delay_ms(50); //防抖
if(PIND !=0xff) //再次检测D口电平,如果不全是高电平则继续执行程序
{
key=PIND;
switch(key)
{
case 0xfd: key_1();break;
case 0xfe: key_2();break;
case 0xfb: key_3();break;
case 0xf7: key_4();break;
default : PORTB=key;
}
// while(PIND != 0XFF); //当前有按键处于按下状态,再按其他按键时程序维持当前
//状态,不会有对应LED点亮发生
}
}
}
void UI() //开机说明界面
{
LCD_write_str(0,0," Welcome to our ");
LCD_write_str(0,1," System ");
delay_ms(500);
LCD_clear();
LCD_write_str(0,0,"key_1--> +10mA");
LCD_write_str(0,1,"key_2--> -10mA");
delay_ms(500);
LCD_clear();
LCD_write_str(0,0,"key_3--> choose");
LCD_write_str(0,1,"key_4--> sure");
delay_ms(500);
LCD_clear();
}
void main()
{
flag=0;
port_init();
LCD_init();
LCD_clear();
UI();
LCD_clear();
LCD_write_str(0,0,"I: 00500 mA");
LCD_write_str(0,1,"U: 00500 mV");
while(1)
{
key_scan();
}
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』