//***************************************
// 使用单片机STC89C51
// 晶振:11.0592M
// 显示:LCD1602
// 编译环境 Keil uVision3
// 参考宏晶网站24c04通信程序
// 时间:2011年4月20日
//****************************************
#include <REG52.H>
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define DataPort P0 //LCD1602数据端口
sbit SCL=P1^0; //IIC时钟引脚定义
sbit SDA=P1^1; //IIC数据引脚定义
sbit LCM_RS=P2^0; //LCD1602命令端口
sbit LCM_RW=P2^1; //LCD1602命令端口
sbit LCM_EN=P2^2; //LCD1602命令端口
sbit rxd=P3^1; //HC-05接入端口
sbit txd=P3^0;
sbit s0=P3^3; //定义按键
sbit s1=P3^6;
sbit s2=P3^7;
sbit s3=P3^2; //定义按键
sbit IN1=P1^0; //定义L298N
sbit IN2=P1^1;
sbit ENA=P1^2;
uchar ge,shi,bai,qian,wan; //显示变量
uchar num,slnum,num0;
uchar light1;
uchar light2;
uchar L1,L2,L3,L4;
int dis_data; //变量
void delay_nms(unsigned int k);
void Uart_Init();
void Recv(void) ;
void InitLcd();
void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar X,uchar Y,uchar DData);
void conversion(uint temp_data);
void light(uchar date);
void KeyRead();
void init_Timer0(void);
void Timer0(void) interrupt 1 using 1;
/**************************串口初使化函数***********************/
void Uart_Init()
{
TMOD = 0x20; //T1方式2,用于产生波特率
TH1 = 0xFD; //装初值
TL1 = 0xFD;
SCON = 0X50; //UART方式1;8位UART
PCON = 0x00; //SMOD=0;波特率不加倍
TR1 = 1; //启动定时器1
EA = 1; //打开全局中断控制
ES = 1; //串行口中断
}
/************************命令数据接收函数**********************/
void Recv(void) //串口中断
{
int temp;
if(RI == 1) //是否有数据传过来
{
temp= SBUF;
RI = 0;
}
light1= temp;
}
void conversion(uint temp_data) // 数据转换出 个,十,百,千,万
{
wan=temp_data/10000+0x30 ;
temp_data=temp_data%10000; //取余运算
qian=temp_data/1000+0x30 ;
temp_data=temp_data%1000; //取余运算
bai=temp_data/100+0x30 ;
temp_data=temp_data%100; //取余运算
shi=temp_data/10+0x30 ;
temp_data=temp_data%10; //取余运算
ge=temp_data+0x30;
}
//毫秒延时**************************
void delay_nms(unsigned int k)
{
unsigned int i,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++)
{;}}
}
/*******************************/
void WaitForEnable(void)
{
DataPort=0xff;
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);
LCM_EN=0;
}
/*******************************/
void WriteCommandLCM(uchar CMD,uchar Attribc)
{
if(Attribc)WaitForEnable();
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/*******************************/
void WriteDataLCM(uchar dataW)
{
WaitForEnable();
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/***********************************/
void InitLcd()
{
DataPort=0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
WriteCommandLCM(0x38,0);
WriteCommandLCM(0x38,0);
WriteCommandLCM(0x38,1); /*显示模式设置*/
WriteCommandLCM(0x08,1); /*显示关闭*/
WriteCommandLCM(0x01,1); /*显示清屏*/
WriteCommandLCM(0x06,1);/*显示光标移动设置*/
WriteCommandLCM(0x0c,1);/*显示开及光标设置*/
}
/***********************************/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1; // 限制X不能大于15,Y不能大于1
X&=15;
if(Y)X|=0x40; // 当要显示第二行时地址码:0xc0
X|=0x80; // 第一行的地址码:0x80
WriteCommandLCM(X,Y);// 这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
/***********设置按键处理程序************/
/****************************************
* 函数名 :KeyRead
* 描述 :按键扫描函数
* 输入 :无
* 输出 :无
* 返回 :无
* 调用 :外部调用
***************************************/
void KeyRead()
{
if(s0==0)
{ delayms(5);
if(s0==0)
{ slnum++;
while(!s0);
if(slnum==1)
{ WriteCommandLCM(0x80+0x0e);
WriteCommandLCM(0x0f);
}
if(slnum==2)
{ WriteCommandLCM(0x80+0x0d);
}
if(slnum==3)
{
WriteCommandLCM(0x80+0x0c);
}
if(slnum==4)
{ WriteCommandLCM(0x80+0x0b);
}
if(slnum==5)
{ slnum=0;
WriteCommandLCM(0x0c);
}
if(slnum==0)
{
}
}
}
if(slnum!=0)
{
if(s1==0)
{ delayms(5);
if(s1==0)
{ while(!s1);
if(slnum==1)
{ L1++;
if(L1==10)
L1=0;
WriteCommandLCM(0x0c,1);
DisplayOneChar(11,1,L1+0x30);Delay_nms(10);
}
if(slnum==2)
{ L2++;
if(L2==10)
L2=0;
WriteCommandLCM(0x0c,1);
DisplayOneChar(10,1,L1+0x30);Delay_nms(10);
}
if(slnum==3)
{ L3++;
if(L3==10)
L3=0;
WriteCommandLCM(0x0c,1);
DisplayOneChar(9,1,L1+0x30);Delay_nms(10);
}
if(slnum==4)
{ L4++;
if(L4==10)
L4=0;
WriteCommandLCM(0x0c,1);
DisplayOneChar(8,1,L1+0x30);Delay_nms(10);
}
}
}
if(s2==0)
{ delayms(5);
if(s2==0)
{ while(!s2);
if(slnum==1)
{ L1--;
if(L1==-1)
L1=9;
WriteCommandLCM(0x0c,1);
DisplayOneChar(11,1,L1+0x30);Delay_nms(10);
}
if(slnum==2)
{ L2--;
if(L2==-1)
L2=9;
WriteCommandLCM(0x0c,1);
DisplayOneChar(10,1,L1+0x30);Delay_nms(10);
}
if(slnum==3)
{ L3--;
if(L3==-1)
L3=9;
WriteCommandLCM(0x0c,1);
DisplayOneChar(9,1,L1+0x30);Delay_nms(10);
}
if(slnum==4)
{ L4--;
if(L4==-1)
L4=9;
WriteCommandLCM(0x0c,1);
DisplayOneChar(8,1,L1+0x30);Delay_nms(10);
}
}
}
}
light1=L1+L2*10+L3*100+L4*1000;
}
// **********PWM产生**********//
/*******************************
* 函数名 :init_Timer0
* 描述 :初始化定时器0
* 输入 :无
* 输出 :无
* 返回 :无
* 调用 :外部调用
******************************/
void init_Timer0(void) //定时器中断初始化
{
TH0 = 0;
TL0 = 0;
TMOD=0x01; //设置定时器0为工作方式1
TH0 = (65536 - 100) / 256; /*右端表达式编译后为0xFF*/
TL0 = (65536 - 100) % 256; /*同上*/
TR0=1; //开定时器T0
ET0 = 1; // //开定时器T0中断
EA = 1; //定时器0中断允许
}
/************LED驱动使能*********************************/
void LEDGo()
{
EN1=1;
EN2=0;
}
//*********************************************************
//主程序********
//*********************************************************
void main()
{
float temp;
delay_nms(200); //延时200ms
Uart_Init(); // 串口初使化函数
KeyRead();
InitLcd(); //初始化LCD
init_Timer0(void); //定时器中断初始化
LEDGo();
while(1) //循环
{
EN1=1;
EN2=0;
if(s0==0)
{ num0=1;}
while(num0)
{ keyscan();
if(slnum==0)
{ num0=0;}
}
CYCLE = 100;// 时间可以调整 这个是10调整 8位PWM就是256步
while(light1=light2) /*渐亮,每一次变化亮度增加1*/
{
if(light1 >= light2) /*若预设值和接受值相等时,pwm不再增加*/
{
delay(200); //延时时间,从一个亮度到下一个亮度的间隔时间,速度快就能看到连续效果
PWM_ON++; //这个使用较长延时,以便能看清楚变化过程
//这个里可以添加其他程序 如到最亮时候控制设备
}
}
while(light1=light2) //渐暗,每一次变化亮度减少1 //
{
if(light1 <= light2) /*若预设值和接受值相等时。pwm不再增加*/
{
delay(200); /*延时*/
PWM_ON--; /*高电平脉宽缩短,即亮度降低*/
}
}
conversion(temp); //计算数据和显示
DisplayOneChar(0,0,'L');
DisplayOneChar(1,0,'i');
DisplayOneChar(2,0,'g');
DisplayOneChar(3,0,'h');
DisplayOneChar(4,0,'t');
DisplayOneChar(5,0,':');
conversion(data);
DisplayOneChar(1,1,'S');
DisplayOneChar(2,1,'e');
DisplayOneChar(3,1,'t');
DisplayOneChar(5,1,':');
DisplayOneChar(7,0,wan); //显示光照采集数据
DisplayOneChar(8,0,qian);//显示光照采集数据
DisplayOneChar(9,0,bai); //显示光照采集数据
DisplayOneChar(10,0,shi);//显示光照采集数据
DisplayOneChar(11,0,ge); //显示光照采集数据
DisplayOneChar(8,1,L1+0x30);//显示按键设定数据
DisplayOneChar(9,1,L2+0x30); //显示按键设定数据
DisplayOneChar(10,1,L3+0x30);//显示按键设定数据
DisplayOneChar(11,1,L4+0x30); //显示按键设定数据
DisplayOneChar(13,0,'L'); //显示光照采集数单位
DisplayOneChar(14,0,'u');
DisplayOneChar(15,0,'x');
DisplayOneChar(13,1,'L'); //显示按键设置数单位
DisplayOneChar(14,1,'u');
DisplayOneChar(15,1,'x');
}
}
/**********************************************************
* 函数名 :Timer0(void) interrupt 1
* 描述 :定时器0中断服务函数,设置pwm输出引脚高低电平,实现pwm输出
* 输入 :无
* 输出 :无
* 返回 :无
* 调用 :无
*********************************************************/
void Timer0(void) interrupt 1 using 1
{
static uchar count;
TH0=(65536-100)/256;
TL0=(65536-100)%256;//定时0.1mS
if(count == PWM_ON) /*若中断次数达到亮度设定值*/
{
ENA=0; /*则熄灯*/
}
count++; /*每次中断记录+1*/
if(count == CYCLE) /*若中断次数达到PWM周期长度*/
{
count = 0; /*则清零中断记录*/
if(PWM_ON != 0) /*若此时亮度值非零*/
{
ENA=1; /*则点灯*/
}
}
}
此帖出自
小平头技术问答
一周热门 更多>