刚刚学习单片机的小白,遇到困难了,求大神

2019-07-15 16:29发布

中学单片机一周左右,很多问题都靠翻书解决,这回实在不知道那错了,求大神指导程序目的是测量脉宽,并在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);    /*显示开及光标设置*/
}
/*------------------------------------------------
溢出函数
------------------------------------------------*/
static 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();//显示
       
       
        }

}



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
7条回答
dabing89
2019-07-16 06:36
#define _LCD1602_C
#include"config.h"
#include"Lcd1602.h"

void LcdWaitReady()
{
        uint8 sta;

        do
        {
                LCD1602_DB = 0XFF;
                LCD1602_RS = 0;
                LCD1602_RW = 1;
                LCD1602_EN = 0;
                LCD1602_EN = 1;
                sta = LCD1602_DB;
                LCD1602_EN = 0;

        }while(sta & 0x80);
}

void LcdWriteCmd(uint8 cmd)
{
        LcdWaitReady();
        LCD1602_RS = 0;
        LCD1602_RW = 0;
        LCD1602_DB = cmd;
        LCD1602_EN = 0;
        LCD1602_EN = 1;
        LCD1602_EN = 0;
}

void LcdWriteDat(uint8 dat)
{
        LcdWaitReady();
        LCD1602_RS = 1;
        LCD1602_RW = 0;
        LCD1602_DB = dat;
        LCD1602_EN = 0;
        LCD1602_EN = 1;
        LCD1602_EN = 0;
}

void LcdSetCursor(uint8 r,uint8 c)
{
        uint8 DDRAM[2] = {0X80,0XC0};
        LcdWriteCmd(DDRAM[r] | c);       
}

void LcdShowStr(uint8 r,uint8 c,uint8 *str)
{
        uint8 i;

        LcdSetCursor(r,c);
        for(i = 0; i < 16 && *(str + i); i++)
        {
                LcdWriteDat(*(str + i));
        }
}

void LcdInit()
{
        LcdWriteCmd(0x38);
        LcdWriteCmd(0x06);
        LcdWriteCmd(0x0c);
        LcdWriteCmd(0x01);
}

void LcdOpenCursor()
{
        LcdWriteCmd(0x0f);
}

void LcdCloseCursor()
{
        LcdWriteCmd(0x0c);
}

void LcdClearScreen()
{
        LcdWriteCmd(0x01);
}



一周热门 更多>