自己写的一个有关51单片机控制电机风扇的程序,有LCD1602、ds18b20、红外遥控,还有E2PROM保存按键值的程序,整体的程序结构有点乱,大家可以取一些需要的内容参考,欢迎大家指出不足!
单片机源程序如下:
#include
#include
#define uchar unsigned char
#define uint unsigned int //宏定义
#include "eeprom52.h"
#define LCD1602_DB P0
sbit LCD1602_RS = P2^6;//“RD”接单片机P2.6, 0=输入指令,1=输入数据
sbit LCD1602_RW = P2^5;//“WR”接单片机P2.5,0=向LCD写入指令或数据,1=从LCD读取信息
sbit LCD1602_E = P2^7;//“LCDE”接单片机P2.7,下降沿有效的使能信号
sbit IO_18B20=P3^7;
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit ENA=P1^2;
sbit key1=P2^1;//设置温度
sbit key2=P2^2;//温度加
sbit key3=P2^3;//温度减
bit flag1s=0;//1s定时标志
unsigned char T0RH=0;
unsigned char T0RL=0;
int temp;//读取到的当前温度值
unsigned char len;
int intT,decT;//温度值的整数和小数部分
unsigned char str[12];
unsigned char d1,d2,d3;//显示数据暂存变量
unsigned char flag;
unsigned int shang,xia; //对比温度暂存变量
void Compare();
void GetTemp();
void ConfigTimer0(unsigned int ms);
unsigned char IntToString(unsigned char *str,int dat);
extern bit Start18B20();
extern bit Get18B20Temp(int *temp);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);
/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
SectorErase(0x2000); //清除扇区
byte_write(0x2000, shang); //写上限数值到扇区
byte_write(0x2001, xia); //写下限数值到扇区
byte_write(0x2060, a_a); //写初始变量到扇区指定位置
}
/******************把数据从单片机内部eeprom中读出来*****************/
void read_eeprom()
{
shang = byte_read(0x2000); //从扇区读取上限数据
xia = byte_read(0x2001); //从扇区读取下限数据
a_a = byte_read(0x2060); //从扇区读取初始变量
}
/**************开机自检eeprom初始化*****************/
void init_eeprom()
{
read_eeprom(); //先读扇区的数据
if(a_a != 1) //判断是否是新单片机(原理:新的单片机扇区里的数据都是0,这里判断是否不等于1。如果是不等于1,就是等于0,那就是新单片机了,就会执行下面的上下限值初始化数值的语句,并让a_a变成1,下次开机就会知道是用过的单片机了就会读取EEPROM里的上下限数据了)
{
shang = 30; //上限数值初始为30
xia = 20; //下限数值初始为20
a_a = 1; //初始值变量赋值1,下次开机就会直接读取EEPROM内的上下限数据
write_eeprom(); //将初始的数据保存进单片机的EEPROM
}
}
/**************LCD1602*****************/
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF; //DB0~DB8为11111111
LCD1602_RS = 0; //数据和指令选择控制端
LCD1602_RW = 1; //读操作
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0;
} while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
/* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由输入的屏幕坐标计算显示RAM的地址
addr = 0x00 + x; //第一行字符地址从0x00起始
else
addr = 0x40 + x; //第二行字符地址从0x40起始
LcdWriteCmd(addr | 0x80); //设置RAM地址
}
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y); //设置起始地址
while (*str != '') //连续写入字符串数据,直到检测到结束符
{
LcdWriteDat(*str++);
}
}
/* 初始化1602液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2显示,5*7点阵,8位数据接口
LcdWriteCmd(0x0C); //显示器开,光标关闭
LcdWriteCmd(0x06); //文字不动,地址自动+1
LcdWriteCmd(0x01); //清屏
}
//sbit IO_18B20=P3^2;
/*软件延时函数,延时时间(t*10)us*/
void DelayX10us(unsigned char t)
{
do{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}while(--t);
}
/*复位总线,获取存在脉冲,以启动一次读写操作*/
bit Get18B20Ack()
{
bit ack;
EA=0; //禁止总中断
IO_18B20=0; //产生500us复位脉冲
DelayX10us(50);
IO_18B20=1;
DelayX10us(6); //延时60us
ack=IO_18B20; //读取存在脉冲
while(!IO_18B20); //等待存在脉冲结束
EA=1; //重新使能总中断
return ack;
}
/*向DS18B20写入一个字节,dat-待写入字节*/
void Write18B20(unsigned char dat)
{
unsigned char mask;
EA=0;
for(mask=0x01;mask!=0;mask<<=1)//低位在先,依次移出8个bit
{
IO_18B20=0;//产生2us低电平脉冲
_nop_();
_nop_();
if((mask&dat)==0)//输出该bit值
IO_18B20=0;
else
IO_18B20=1;
DelayX10us(6);//延时60us
IO_18B20=1;//拉高通信引脚
}
EA=1;
}
/*从DS18B20读取一个字节,返回值-读到的字节*/
unsigned char Read18B20()
{
unsigned char dat;
unsigned char mask;
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』