中学
单片机一周左右,很多问题都靠翻书解决,这回实在不知道那错了,求大神指导程序目的是测量脉宽,并在1602上显示出来
程序如下
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS = P2 ^ 4; //定义端口
sbit RW = P2 ^ 5;
sbit EN = P2 ^ 6;
sbit sr = P3 ^ 1; //输入端口3.1
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0
unsigned char T1count=0;
uchar data disdata[5];
unsigned long a;
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while (--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while (t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort = 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
// while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
//while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort = Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x, unsigned char y, unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
while (*s)
{
LCD_Write_Data(*s);
s++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x, unsigned char y, unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data(Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
/*------------------------------------------------
溢出函数
------------------------------------------------*/
sta
tic void time1_int(void) interrupt 3 using 0 //溢出后计算
{
TH1 = 0X00; //溢出一次 ti自加1
TL1 = 0X00;
T1count++;
}
/*------------------------------------------------
定时器初始化函数
------------------------------------------------*/
void pulse_init(void) //不知道干什么用的 定时器状态
{
TMOD = 0x90;
TH1 = 0X00;
TL1 = 0X00;
ET1 = 1;
EA = 1;
}
/*------------------------------------------------
脉宽测量函数
------------------------------------------------*/
unsigned char celiang()
{
//该开始定义unsigned int,结果超出了范围,因为int的最大是65536
pulse_init();
TR0 = 0; //先关闭
while (sr);//等待int1降低
//计数一个完整的高电平
while (!sr);//等待int1升高
TR1 = 1;
while (sr);//等待int1降低
TR1 = 0;//停止计数
a = T1count*65536+256*TH1+TL1;
return(a);
}
/*------------------------------------------------
读取速度
------------------------------------------------*/
/*read_temp()
{
unsigned long a;//该开始定义unsigned int,结果超出了范围,因为int的最大是65536
celiang()
a = T1count*65536+256*TH1+TL1;
//tvalue = tvalue*(0.625);//温度值扩大10倍,精确到1位小数
//return(a);
}
/*------------------------------------------------
速度显示函数
------------------------------------------------*/
void vsdisp()
{
uchar flagdat;
disdata[0] = a / 1000 + 0x30;//百位数
disdata[1] = a % 1000 / 100 + 0x30;//十位数
disdata[2] = a % 100 / 10 + 0x30;//个位数
disdata[3] = a % 10 + 0x30;//小数位
if (disdata[0] == 0x30)
{
disdata[0] = 0x20;//如果百位为0,不显示
if (disdata[1] == 0x30)
{
disdata[1] = 0x20;//如果百位为0,十位为0也不显示
}
}
LCD_Write_Com(0xc8);
LCD_Write_Data(flagdat);//显示符号位
LCD_Write_Com(0xc9);
LCD_Write_Data(disdata[0]);//显示百位
LCD_Write_Com(0xca);
LCD_Write_Data(disdata[1]);//显示十位
LCD_Write_Com(0xcb);
LCD_Write_Data(disdata[2]);//显示个位
LCD_Write_Com(0xcc);
LCD_Write_Data(0x2e);//显示小数点
LCD_Write_Com(0xcd);
LCD_Write_Data(disdata[3]);//显示小数位
LCD_Write_Com(0xcf);
LCD_Write_Data('C');
}
/*
主函数
*/
void main()
{
while (1)
{
LCD_Init;
DelayMs(5);
celiang();//读取参数
vsdisp();//显示
}
}
一周热门 更多>