/**************************************
*液晶控制函数
***************************************/
#include<reg52.H>
#include<intrins.h>
typedefunsigned char BYTE;
typedefbit BOOL;
sbitLCD_RS = P2^5;
sbitLCD_RW = P2^6;
sbitLCD_EP = P2^7;
/*******************************************
*函数名称:delay1() 延时函数
*函数作用:延时 t ms
*********************************************/
voidDelay_ms(int ms)
{
int i,j;
for (i=ms;i>0; i--)
for (j=110; j>0; j--);
}
voidDelay_us(int ms)
{
int i;
for (i=ms;i>0; i--);
}
/*******************************************
*函数名称:lcd_bz() 液晶忙信号检测
*函数作用:读取液晶是否处于忙状态
*********************************************/
BOOLlcd_bz()
{ //测试LCD忙碌状态
BOOL result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EP = 1; //E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令
Delay_us(4);
result = (BOOL)(P0 & 0x80);//高电平表示忙状态
LCD_EP = 0;
return result;
}
/*******************************************
*函数名称:lcd_wcmd() 液晶写指令字函数
*函数作用:向液晶写控制指令字
*********************************************/
voidlcd_wcmd(BYTE cmd)// 写入指令数据到LCD
{
while(lcd_bz());
LCD_RS = 0;
LCD_RW = 0;
LCD_EP = 0;
Delay_us(2);
P0 = cmd; //此处要模仿时序状态
Delay_us(4);
LCD_EP = 1;//高电平到低电平转变时开始写入数据
Delay_us(4);
LCD_EP = 0;
}
/*******************************************
*函数名称:lcd_pos() 液晶数据地址函数
*函数作用:确定写入液晶的数据的地址
*********************************************/
voidlcd_pos(BYTE pos)
{
lcd_wcmd(pos | 0x80); //设定显示位置
}
/*******************************************
*函数名称:lcd_wdat() 液晶写数据函数
*函数作用:向液晶中写入数据
*********************************************/
void lcd_wdat(BYTE dat)
{ //写入字符显示数据到LCD
while(lcd_bz());
LCD_RS = 1; //写数据到ddram
LCD_RW = 0;
LCD_EP = 0;
P0 = dat; //要送的数据
Delay_us(4);
LCD_EP = 1; //执行
Delay_us(4);
LCD_EP = 0;
}
/*******************************************
*函数名称:lcd_init() 液晶初始化配置函数
*函数作用:配置液晶的工作状态
*********************************************/
voidlcd_init()
{ //LCD初始化设定,命令字
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
Delay_ms(1);
lcd_wcmd(0x0c); //显示开,关光标
Delay_ms(1);
lcd_wcmd(0x06); //移动光标
Delay_ms(1);
lcd_wcmd(0x01); //清除LCD的显示内容
Delay_ms(100);
}
voidlcd_str(unsigned char* dis,unsigned char N,unsigned char t,unsigned char st)
{
unsigned char i=0;
for(i=0;i<N;i++)
{
lcd_pos(64*t+i+st);
lcd_wdat(*(dis+i));
Delay_ms(1);
}
}
voidlcd_string(bit bRow, unsigned char btColumn, unsigned char *pData)
{
while (*pData != '\0')
{
if (bRow)
{
lcd_wcmd(0xc0 + btColumn);//显示在第1行
}
else
{
lcd_wcmd(0x80 + btColumn); //显示在第0行
}
lcd_wdat(*(pData++)); //要显示的数据
btColumn++; //列数加一
Delay_ms(1);
}
}
voiddelay1(int );
voidlcd_wcmd(unsigned char );
voidlcd_pos(unsigned char );
voidlcd_wdat(unsigned char );
voidlcd_init();
voidlcd_str(unsigned char* dis,unsigned char N,unsigned char t,unsigned char st);
voidDelay_ms(int ms);
voidlcd_string(bit bRow, unsigned char btColumn, unsigned char *pData);
/****************************************************************
#include<reg52.h>
#include"lcd.h"
#defineuint unsigned int
#defineuchar unsigned char
/******数模转换器接口定义********/
sbitclk=P3^1;
sbitcs=P3^0;
sbitdin=P3^2;
// 粗调参数
uintcode vol[10]={0,145,250,315,365,430,465,492,508,549};//
// 细调参数
uintcode small_vol[52]={0,30,56,95,120,145,168,183,203,230,250,270,288,300,307,
315,325,335,349,359,365,385,400,410,423,430,438,443,449,452,465,468,472,476,486,492,
495,498,501,504,508,516,524,532,540,549};//
sbitadd=P1^0; // 增加按键
sbitsub=P1^1; // 减小按键
sbitk0=P1^2; // 模式按键
unsignedint vol_n=0; //对应数组中的位置
unsignedchar mode=0; //模式变量
voiddelay();
voidDAconver(uint DAValue); //数模转换器
/******************************************************
函数名称:delayms
输入参数:t
函数说明:延时t毫秒
*******************************************************/
voiddelayms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<100;j++);
}
/******************************************************
函数名称:scan
输入参数:无
函数说明:键盘扫描函数
*******************************************************/
voidscan()
{
uint t=0;
if(k0==0) //模式切换键按下
{
delayms(20);
if(k0==0)
{
if(mode==0)
{
mode=1;
lcd_pos(15);
lcd_wdat('B'); // 模式字符
}
else
{
mode=0;
lcd_pos(15);
lcd_wdat('A');
}
vol_n=0;//
delayms(800);
}
}
if(add==0) //增加按键按下
{
delayms(20);
if(add==0)
{
if(mode==0) //粗调模式,总共有10种情况
{
if(vol_n<9) vol_n=vol_n+1;
}
else //细调模式
{
if(vol_n<45) vol_n=vol_n+1;
}
}
delayms(800);
}
else if(sub==0)
{
delayms(20);
if(sub==0)
{
if(vol_n>0)vol_n=vol_n-1;
}
delayms(800);
} //显示的功能
if(mode==0)
{
t=50+vol_n*50;
}
else
{
t=50+10*vol_n;
}
lcd_pos(4);
lcd_wdat(t/100+48);
lcd_pos(5);
lcd_wdat('.');
lcd_pos(6);
lcd_wdat(t%100/10+48);
lcd_pos(7);
lcd_wdat(t%10+48);
lcd_pos(8);
lcd_wdat('V');
}
/******************************************************
函数名称:main
输入参数:无
函数说明:系统主函数
*******************************************************/
voidmain()
{vol_n=0; lcd_init(); // 液晶初始化
lcd_string(0,4,"Welcome");
lcd_string(1,0,"fengzhengliang");
delayms(2000);
lcd_wcmd(0x01);
delayms(100);
lcd_string(0,0,"VPP:0.5V");
lcd_pos(15);
lcd_wdat('A');
while(1)
{
scan();
if(mode==0)
{
DAconver(vol[vol_n]);
}
else
{
DAconver(small_vol[vol_n]); //不断地输出数据
}
delayms(500);
}
}
/******************************************************
函数名称:delay
输入参数:无
函数说明:延时10us左右
*******************************************************/
voiddelay()
{
char i = 5;
while(i--);
}
/******************************************************
函数名称:DAconver
输入参数:无
函数说明:这个是用了12个时钟的驱动,根据PDF的数据格式,十位数据在12位的前面,后面两位没有用,所以要先把16位数据DAValue先左移6位,使到剩下的十位是有效数据
*******************************************************/
voidDAconver(uint DAValue)
{
uchar i;
DAValue <<= 6;
cs = 0;
clk = 0;
for(i = 0; i < 12; i++) //内输入的是10位DA数据,后两个时钟周期为填充字节
{
din = (bit)(DAValue &0x8000);
clk = 1;
DAValue <<= 1;
clk = 0;
}
cs = 1; // CS的上升沿和下降沿只有在CLK为低的时候才有效
clk = 0;
}
|