|
本人以前学单片机时学的是汇编,所以C语言的keil单片机编程不是很懂,我打算做一个酒精测试仪的课程设计,这个是我网上找到的程序代码,我试着编译,但是总是报错,想问问各位大师怎么解决,是设置的问题么,希望能有详细的解答,最好附图解答。以下是程序代码:
一:主程序
#include <reg52.h>
#include <stdio.h>
#include<LCD1602.h>
#include<Ds1302.h>
#include<AT24c02.h>
#include<ADC0832.h>
#define uint unsigned int
#define uchar unsigned char
//键盘
sbit k0=P1^0;
sbit k1=P1^1;
sbit k2=P1^2;
sbit k3=P1^3;
//变量
bit flg=0;
//数组
uchar M_time[]={"Time"}; //时间
uchar M_Detect[]={"Detect"}; //检测
uchar M_Storage[]={"Storage"}; //存储
uchar stor[4];
//以定义函数
void initial_lcd1602(void);
void delays1(uint n)
{
while(n--);
}
/***************子程序************************/
void chang_h(void)
{
int g;
if(k0==0)
{for(g=0;g<20;){delays1(100);g++;}
if(k0==0)
{wr_data[4]=readtimeR[4]+1;
if(wr_data[4]>0x23)wr_data[4]=0x00;
}
}
if(k1==0)
{for(g=0;g<20;){delays1(100);g++;}
if(k1==0)
{wr_data[4]=readtimeR[4]-1;
if(readtimeR[4]==0x00)wr_data[4]=0x00;
}
}
DS1302_init();
showdata();
Display_List_Char(1,0,lcd_time);
}
/***************************************/
void chang_m(void)
{
int g;
if(k0==0)
{for(g=0;g<20;){delays1(100);g++;}
if(k0==0)
{wr_data[5]=readtimeR[5]+1;
if(wr_data[5]>0x23)wr_data[5]=0x00;
}
}
if(k1==0)
{for(g=0;g<20;){delays1(100);g++;}
if(k1==0)
{wr_data[5]=readtimeR[5]-1;
if(readtimeR[5]==0x00)wr_data[5]=0x00;
}
}
DS1302_init();
showdata();
Display_List_Char(1,0,lcd_time);
}
/*************************************/
void chang_s(void)
{
int g;
if(k0==0)
{for(g=0;g<20;){delays1(100);g++;}
if(k0==0)
{wr_data[6]=readtimeR[6]+1;
if(wr_data[6]>0x23)wr_data[6]=0x00;
}
}
if(k1==0)
{for(g=0;g<20;){delays1(100);g++;}
if(k1==0)
{wr_data[6]=readtimeR[6]-1;
if(readtimeR[6]==0x00)wr_data[6]=0x00;
}
}
DS1302_init();
showdata();
Display_List_Char(1,0,lcd_time);
}
/**************************************************/
//主函数
/**************************************************/
void main()
{
uchar i,dd;
uint g;
uchar show[4];
unsigned int data_temp=0;
initial_lcd1602();
DS1302_init();
delays1(100);
Display_List_Char(0,0,LCD_Code2);
for(g=0;g<100;){delays1(100);g++;}
while(1)
{
if(k0==0|k1==0|k2==0|k3==0)
{
write_lcd_command(0x01); //清屏
for(g=0;g<100;){delays1(100);g++;}
Display_List_Char(0,0,M_time);
Display_List_Char(0,8,M_Detect);
Display_List_Char(1,0,M_Storage);
for(g=0;g<10;){delays1(100);g++;}
/**********************时间**************************/
if(k0==0) //时间
{
write_lcd_command(0x01); //清屏
do
{ if(k3==0) flg=1;
showdata();
Display_List_Char(0,0,lcd_dat+3);
Display_List_Char(1,0,lcd_time);
/************************调时间**************************/
if(k2==0)
{
do
{
Display_One_Char(1,10,'H');
if(k3==0) flg=1;
chang_h();
for(g=0;g<100;){delays1(100);g++;}
if(k2==0)
{do
{
Display_One_Char(1,10,'M');
if(k3==0) flg=1;
chang_m();
for(g=0;g<100;){delays1(100);g++;}
if(k2==0)
{do
{
Display_One_Char(1,10,'S');
if(k3==0) flg=1;
chang_s();
}while(flg==0);
}
}while(flg==0);
}
}while(flg==0);flg=0;
write_lcd_command(0x01);
}
for(g=0;g<500;){delays1(100);g++;}
} while(flg==0);flg=0;
}
/*************检测*******************/
if(k1==0)
{
write_lcd_command(0x01);
do
{
if(k3==0) flg=1;
data_temp=ADconv();
stor[0]=data_temp;
xs_int(196*data_temp,1);
}while(flg==0);flg=0;
}
/***************存储****************/
if(k2==0)
{
write_lcd_command(0x01); //清屏
do
{
if(k3==0) flg=1;
for(i=0;i<3;)
{
// i2c_write(0x00+i,0x63+i/*要存的数据*/);
i2c_write(0x00+i,stor[0]/*要存的数据*/);
i++;
}
_nop_();
i=0;
for(i=0;i<3;)
{
dd=i2c_read(0x00+i);/*读地址数据*/
show[i]=dd;
i++;
}
Display_List_Char(1,0,show);
}while(flg==0);flg=0;
for(g=0;g<500;){delays1(100);g++;}
}
/***************************************/
}
}
}
二:液晶显示程序
#include<reg52.h>
#include <stdio.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define LCDPORT P0
sbit RS=P2^6; //RS数据命令选择端,高电平数据,低电平命令
sbit RW=P2^7; //RW读写选择端,高电平读操作,低电平写操作
sbit EN=P2^0; //EN使能控制端,E高电平跳变为低电平时LCD执行命令
uchar LCD_Code2[] ="Welcome:";
uchar LCD_Code[] ="0123456789ABCDEF-.";
/******************************LCD1602驱动程序*************************************/
void lcd_delay(uchar delaytime)
{
while(delaytime)delaytime--;
}
void write_lcd_command(uchar write_command)
{
lcd_delay(40);
RS=0;
RW=0;
LCDPORT=write_command;
EN=1;
EN=0;
}
void write_lcd_data(uchar write_data)
{
lcd_delay(40);
RS=1;
RW=0;
LCDPORT=write_data;
EN=1;
EN=0;
}
void Display_One_Char( uchar x,uchar y,uchar dat) //x表示行,y表示列
{
switch(x)
{
case 0:
write_lcd_command(0x80+y);
break;
case 1:
write_lcd_command(0xc0+y);
break;
}
write_lcd_data(dat);
}
void Display_List_Char(uchar x,uchar y,uchar *str)
{
switch(x)
{
case 0:
write_lcd_command(0x80+y);
break;
case 1:
write_lcd_command(0xc0+y);
break;
}
while (*str!='\0')
{
write_lcd_data(*str);
str++;
}
}
void xs_int(unsigned int shuju,bit t) //显示一个数字
{unsigned char huancun[6]={0};
unsigned char biaozhi=0,i;
if (shuju < 10) biaozhi = 1;
else if(shuju < 100) biaozhi = 2;
else if(shuju < 1000) biaozhi = 3;
else if(shuju < 10000) biaozhi = 4;
else if(shuju < 65535) biaozhi = 5;
switch(biaozhi)
{case 5:huancun[5] = shuju/10000;
case 4:huancun[3] = shuju%10000/1000;
case 3:huancun[2] = shuju%1000/100;
case 2:huancun[1] = shuju%100/10;
case 1:huancun[0] = shuju%10;
break;
default:break;
}
for(i=6;i>1;i--)
{if(i==5)Display_One_Char(1,10,'.');
else Display_One_Char(t,15-i,0x30+huancun[i-1]); }
Display_One_Char(t,15,'V');
}
void initial_lcd1602(void) //初始化LCD1602
{
uchar i;
EN=0;
for(i=200;i>0;i--)
lcd_delay(248);
write_lcd_command(0x38); //0x38命令,双行显示,显示5x7的点阵字符
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x38); //再写一次0x38命令,双行显示,显示5x7的点阵字符
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x0c); //无光标,不闪烁
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x06); //光标右移,文字不移动
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x01); //清屏
for(i=4;i>0;i--)
lcd_delay(248);
}
三:存储程序
#include<reg52.h>
#include <stdio.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define LCDPORT P0
sbit RS=P2^6; //RS数据命令选择端,高电平数据,低电平命令
sbit RW=P2^7; //RW读写选择端,高电平读操作,低电平写操作
sbit EN=P2^0; //EN使能控制端,E高电平跳变为低电平时LCD执行命令
uchar LCD_Code2[] ="Welcome:";
uchar LCD_Code[] ="0123456789ABCDEF-.";
/******************************LCD1602驱动程序*************************************/
void lcd_delay(uchar delaytime)
{
while(delaytime)delaytime--;
}
void write_lcd_command(uchar write_command)
{
lcd_delay(40);
RS=0;
RW=0;
LCDPORT=write_command;
EN=1;
EN=0;
}
void write_lcd_data(uchar write_data)
{
lcd_delay(40);
RS=1;
RW=0;
LCDPORT=write_data;
EN=1;
EN=0;
}
void Display_One_Char( uchar x,uchar y,uchar dat) //x表示行,y表示列
{
switch(x)
{
case 0:
write_lcd_command(0x80+y);
break;
case 1:
write_lcd_command(0xc0+y);
break;
}
write_lcd_data(dat);
}
void Display_List_Char(uchar x,uchar y,uchar *str)
{
switch(x)
{
case 0:
write_lcd_command(0x80+y);
break;
case 1:
write_lcd_command(0xc0+y);
break;
}
while (*str!='\0')
{
write_lcd_data(*str);
str++;
}
}
void xs_int(unsigned int shuju,bit t) //显示一个数字
{unsigned char huancun[6]={0};
unsigned char biaozhi=0,i;
if (shuju < 10) biaozhi = 1;
else if(shuju < 100) biaozhi = 2;
else if(shuju < 1000) biaozhi = 3;
else if(shuju < 10000) biaozhi = 4;
else if(shuju < 65535) biaozhi = 5;
switch(biaozhi)
{case 5:huancun[5] = shuju/10000;
case 4:huancun[3] = shuju%10000/1000;
case 3:huancun[2] = shuju%1000/100;
case 2:huancun[1] = shuju%100/10;
case 1:huancun[0] = shuju%10;
break;
default:break;
}
for(i=6;i>1;i--)
{if(i==5)Display_One_Char(1,10,'.');
else Display_One_Char(t,15-i,0x30+huancun[i-1]); }
Display_One_Char(t,15,'V');
}
void initial_lcd1602(void) //初始化LCD1602
{
uchar i;
EN=0;
for(i=200;i>0;i--)
lcd_delay(248);
write_lcd_command(0x38); //0x38命令,双行显示,显示5x7的点阵字符
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x38); //再写一次0x38命令,双行显示,显示5x7的点阵字符
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x0c); //无光标,不闪烁
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x06); //光标右移,文字不移动
for(i=4;i>0;i--)
lcd_delay(248);
write_lcd_command(0x01); //清屏
for(i=4;i>0;i--)
lcd_delay(248);
}
四:AD转换程序
#include"reg52.h"
#include<intrins.h>
//******************adc0832****************************//
sbit CS=P3^1; //使能。
sbit CLK=P3^2;//时钟
sbit Do=P3^3; // 数据输出
sbit Di=P3^3;//数据输入
unsigned char CH=0x02;
//通道的选择:0x02就是单通道0;0x03就是单通道1;
//0x00就是双通道ch0=“+”; ch0=“-”
//0x01就是双通道ch0=“-”; ch0=“+”
//*****************************************************//
unsigned char ADconv(void)
{unsigned char i;
unsigned int data_f=0,data_c=0;
Di=1;
CS=1;
_nop_();
CS=0;
Di=1; ;//芯片使能之前的初始化。第一个下降沿
CLK=1;
_nop_();
_nop_();
/****************************************/
CLK=0; // 确定通道模式、第2个下降沿
_nop_();
_nop_();
CLK=1;
Di=(bit)(0x02&CH); //设定通道初始化
_nop_();
CLK=0;
_nop_();
_nop_();
CLK=1;
Di=(bit)(0x01&CH); //设定通道初始化 .第3个下降沿
_nop_();
_nop_();
CLK=0; //AD转化的初始化完成。
Di=1;
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
CLK=1;
for(i=8;i>0;i--)//得到一个正常排序的8位数据
{
data_f|=Do;
data_f<<=1;
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
}
for(i=8;i>0;i--)//得到一个反序排列的8位数据
{
data_c<<=1;
data_c|=Do;
_nop_();
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
}
CLK=0;
_nop_();
_nop_();
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
_nop_();
CLK=1;
_nop_();
CS=1;
_nop_();
_nop_();
return data_f;
}
五:时钟程序
#include <reg52.h>
#include <stdio.h>
sbit DS1302_CLK = P3^5;
sbit DS1302_IO = P3^6;
sbit DS1302_RST = P3^7;
uchar lcd_dat[]={" 2009-09-26 6"};
uchar lcd_time[]={"21:50:33"};
uchar wr_data[8]={0x09,0x09,0x26,0x06,0x22,0x59,0x50};
uchar readtimeR[8];
void delays(uint n)
{
while(n--);
}
/*****************************************************************************
函数功能:写DS1302一个字节子程序
入口参数:
出口参数:
*****************************************************************************/
void sendbyte(uchar a)
{
uchar i,temp;
temp=a;
for(i=8;i>0;i--)
{
if(temp&0x01) //先发低位
DS1302_IO=1;
else
DS1302_IO=0;
temp=temp>>1;
DS1302_CLK=1;
delays(5);
DS1302_CLK=0;
delays(5);
}
}
/*****************************************************************************
函数功能:读DS1302一个字节子程序
入口参数:
出口参数:
*****************************************************************************/
uchar readbyte(void)
{
uchar i,dat=0;
for(i=8;i>0;i--)
{
DS1302_IO=1;
dat>>=1;
if(DS1302_IO)
dat|=0x80;
DS1302_CLK=1;
delays(5);
DS1302_CLK=0;
}
return dat;
}
/*uchar readbyte(void)
{
uchar i;
uchar ucdat=0;
for(i=8;i>0;i--)
{
DS1302_IO=1;
ucdat>>=1;
if(DS1302_IO)ucdat|=0x80;
DS1302_CLK=1;
delays(2);
DS1302_CLK=0;
}
return(ucdat);
}*/
/*****************************************************************************
函数功能:写DS1302地址子程序
入口参数:add
入口数据:dat
*****************************************************************************/
void write_DS1302(uchar address,uchar dat)
{
DS1302_RST=0;
delays(10);
DS1302_CLK=0;
delays(10);
DS1302_RST=1;
delays(5);
sendbyte(address);
delays(5);
sendbyte(dat);
DS1302_RST=0;
DS1302_CLK=0;
}
/*****************************************************************************
函数功能:读DS1302地址子程序
入口参数:add
出口参数:readtimeR[]
*****************************************************************************/
uchar read_DS1302(uchar address)
{
uchar timer;
DS1302_RST=0;
delays(2);
DS1302_CLK=0;
delays(2);
DS1302_RST=1;
sendbyte(address);
timer=readbyte();
DS1302_RST=0;
DS1302_CLK=0;
return timer;
}
/*uchar read_DS1302(uchar addr)
{
uchar timedata;
DS1302_RST=0;
delays(2);
DS1302_CLK=0;
delays(2);
DS1302_RST=1;
sendbyte(addr);
timedata=readbyte();
DS1302_CLK=1;
delays(2);
DS1302_RST=0;
return(timedata);
} */
/*****************************************************************************
函数功能:初始化DS1302子程序
入口参数:wr_data[](全局变量)
出口参数:
*****************************************************************************/
void DS1302_init()
{
write_DS1302(0xbe,0x00);
write_DS1302(0x8e,0x00); //关闭保护,若写0x80,则开启保护
write_DS1302(0x8c,wr_data[0]); //年
write_DS1302(0x88,wr_data[1]); //月
write_DS1302(0x86,wr_data[2]); //日
write_DS1302(0x8A,wr_data[3]); //星期
write_DS1302(0x84,wr_data[4]); //时
write_DS1302(0x82,wr_data[5]); //分
write_DS1302(0x80,wr_data[6]); //秒
write_DS1302(0x8e,0x80);
}
/*****************************************************************************
函数功能:读DS1302时间子程序
入口参数:
出口参数:全局变量(year,mouth,data,day,hour,minute,second)
*****************************************************************************/
void read_time(void)
{
readtimeR[0]=read_DS1302(0x8d); //年
readtimeR[1]=read_DS1302(0x89); //月
readtimeR[2]=read_DS1302(0x87); //日
readtimeR[3]=read_DS1302(0x8b); //周
readtimeR[4]=read_DS1302(0x85); //时
readtimeR[5]=read_DS1302(0x83); //分
readtimeR[6]=read_DS1302(0x81); //秒
}
void showdata()
{
read_time();
lcd_dat[3]=(readtimeR[0]>>4)+0x30;
lcd_dat[4]=(readtimeR[0]&0x0f)+0x30;
lcd_dat[6]=(readtimeR[1]>>4)+0x30;
lcd_dat[7]=(readtimeR[1]&0x0f)+0x30;
lcd_dat[9]=(readtimeR[2]>>4)+0x30;
lcd_dat[10]=(readtimeR[2]&0x0f)+0x30;
lcd_dat[14]=(readtimeR[3]&0x0f)+0x30;
lcd_time[0]=(readtimeR[4]>>4)+0x30;
lcd_time[1]=(readtimeR[4]&0x0f)+0x30;
lcd_time[3]=(readtimeR[5]>>4)+0x30;
lcd_time[4]=(readtimeR[5]&0x0f)+0x30;
lcd_time[6]=(readtimeR[6]>>4)+0x30;
lcd_time[7]=(readtimeR[6]&0x0f)+0x30;
}
我想百度了一下,他说几个子程序要放到同一个子目录下才行,而后面的未定义警告是由于前面的几个报错造成的,我想求解具体的解决办法。 |
|