[求助] 温度控制直流电机转速程序求帮助

AngeloChou   2013-5-16 18:26 楼主
近几天借了本《单片机C语言程序设计实训100例》在熟练单片机的C语言操作,进一步加深对单片机及C语言编程的了解。
然后我用keil和Proteus练习仿真,然后按照书本的练习仿真的时候发现 LCD1602只是亮而不会进行温度采集以及转速控制,我在网上查过相应的资料也咨询过同学,都不知道问题究竟出在哪里,能不能请问一下,是不是这个程序有问题?问题在哪个方面?怎样改比较全面?
仿真图

#include
#include

#define uchar unsigned char
#define uint unsigned int
#define DelayNop() {_nop_(); _nop_(); _nop_(); _nop_();}
/**
四个温度的宏
**/
#define TEMP_1  10
#define TEMP_2  15
#define TEMP_3  25
#define TEMP_4  30

sbit DQ = P3^3;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
sbit MA = P1^0;                                            
sbit MB = P1^1;                                  
sbit PWM1 = P1^2;

uchar code temp_Title[] = "Here is Current";
uchar curr_temp_buf[] = "temp:           ";

uchar code temperature_char[8] =
                                        {0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00};
uchar code df_Table[] =
                                        {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9};
uchar CurrentT = 0;
uchar Signed_temp = 0;
uchar Temp_Value[] = {0x00, 0x00};
uchar Back_temp_Value[] = {0xFF, 0xFF};
uchar Display_Digit[] = {0, 0, 0, 0};
bit DS18B20_IS_OK = 1;
uint tCount = 0;

void delayXus(int x)//延迟程序1(ms)
{
        uchar i;
        while(x--)
        {
                for(i = 0; i < 120; i++);
        }
}

bit LCD_Busy_Check()//LCD忙检查
{
        bit Result;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_EN = 1;
        DelayNop();
        Result = (bit) (P0 & 0x80);
        LCD_EN = 0;
        return Result;
}

void write_LCD_Cmd(uchar cmd)//向LCD写指令
{
        while(LCD_Busy_Check());
        LCD_RS = 0;
        LCD_RW = 0;
        LCD_EN = 0;
        _nop_();_nop_();
        P0 = cmd;
        DelayNop();
        LCD_EN = 1;
        DelayNop();
        LCD_EN = 0;
}

void write_LCD_Data(uchar dat)//向LCD写数据
{
        while(LCD_Busy_Check());
        LCD_RS = 1;
        LCD_RW = 0;
        LCD_EN = 0;
        P0 = dat;
        DelayNop();
        LCD_EN = 1;
        DealyNop();
        LCD_EN = 0;
}

void LCD_init()        //LCD初始化
{
        delayXus(2);
        write_LCD_Cmd(0x01);//
        delayXus(2);
        write_LCD_Cmd(0x38);//显示开,光标关
        delayXus(2);
        write_LCD_Cmd(0x0c);//字符进入模式:屏幕不动,字符后移
        delayXus(2);
        write_LCD_Cmd(0x06);//清屏
        delayXus(2);       
}

void set_LCD_Pos(uchar pos)//设置显示位置
{
         write_LCD_Cmd(pos | 0x80);
}


void write_New_LCD_char()
{
        uchar i;
        write_LCD_Cmd(0x40);
        for(i = 0; i < 8; i++)
        {
                write_LCD_Data(temperature_char);//写入温度符号
        }
}

void delay_(uint x)//延迟程序2
{
        while(--x);
}

uchar read_byte()//读一字节
{                                               
        uchar i, dat = 0;
        DQ = 1;_nop_();
        for(i = 0; i < 8; i++)
        {
                DQ = 0;
                dat >>= 1;
                DQ = 1;
                _nop_();_nop_();
                if(DQ)
                dat |= 0x80;
                delay_(30);
                DQ = 1;
        }

        return dat;
}

uchar write_byte(uchar dat)//写一字节
{
        uchar i;
        for(i = 0; i < 8; i++)
        {
                DQ = 0;
                DQ = dat & 0x01;
                delay_(5);
                DQ = 1;
                dat >>= 1;               
        }
}

uchar DS18B20_init()        //DS18B20初始化
{
        uchar status;
        DQ = 1; delay_(8);
        DQ = 0; delay_(90);
        DQ = 1; delay_(8);
        status = DQ;
        delay_(100);
        DQ = 1;
       
        return status;//初始化成功返回0
}

void read_temp()//读温度值
{
        if(DS18B20_init() == 1)   //DS18B20出故障
        {
                DS18B20_IS_OK = 0;       
        }else
        {
                write_byte(0xCC);
                write_byte(0x44);
                DS18B20_init();
                write_byte(0xCC);
                write_byte(0xBE);
                Temp_Value[0] = write_byte(0);//        温度低8位
                Temp_Value[1] = write_byte(0);//        温度高8位
                DS18B20_IS_OK = 1;
        }
}

void display_temp()
{
        uchar i;
        uchar t = 150;//延时值
        uchar flag = 0;//负数标识  
        //如果为负数取反加1,并设置负数标识
        if((Temp_Value[1] & 0xF8) == 0xF8)
        {
                Temp_Value[1] = ~Temp_Value[1];
                Temp_Value[0] = ~Temp_Value[0] + 1;
                if(Temp_Value[0] == 0x00)
                Temp_Value[1]++;
                flag = 1;
        }
        Display_Digit[0] = df_Table[Temp_Value[0] & 0x0F];
        CurrentT = ((Temp_Value[0] & 0xF0) >> 4) | ((Temp_Value[1] & 0x07) << 4);
        Signed_temp = !flag ? CurrentT : - CurrentT;
        Display_Digit[3] = CurrentT / 100;
        Display_Digit[2] = CurrentT % 100 /10;
        Display_Digit[1] = CurrentT % 10;
        //刷新LCD缓冲
        curr_temp_buf[11] = Display_Digit[0] + '0';
        curr_temp_buf[10] = '.';
        curr_temp_buf[9] = Display_Digit[1] + '0';
        curr_temp_buf[8] = Display_Digit[2] + '0';
        curr_temp_buf[7] = Display_Digit[3] + '0';
        //高位为0不显示
        if(Display_Digit[3] == 0) curr_temp_buf[7] = ' ';
        //高位为0且次高位为0不显示
        if(Display_Digit[2] == 0 && Display_Digit[3] == 0)
        {
                curr_temp_buf[8] = ' ';
        }
        if(flag)
        {
                if(curr_temp_buf[8] == ' ')
                {
                        curr_temp_buf[8] == '-';       
                }else if(curr_temp_buf[7] == ' ')
                {
                        curr_temp_buf[7] == '-';       
                }else
                {
                        curr_temp_buf[6] == '-';
                }
        }
        //在第一行显示标题
        set_LCD_Pos(0x00);
        for(i = 0; i < 16; i++)
        {
                write_LCD_Data(temp_Title);
        }       
        //在第二行显示实际温度
        set_LCD_Pos(0x40);
        for(i = 0; i < 16; i++)
        {
                write_LCD_Data(curr_temp_buf);
        }
        //显示温度符号℃
        set_LCD_Pos(0x4D);
        write_LCD_Data(0x00);
        set_LCD_Pos(0x4E);
        write_LCD_Data('C');          
}

void T0_int()interrupt 1
{
        TH0 = -50000 / 256;
        TL0 = -50000 % 256;
        read_temp();//读取温度
        if(!DS18B20_IS_OK) return; //读错时退出
        //读取正常且温度发生变化则刷新显示
        if(Temp_Value[0] != Back_temp_Value[0] || Temp_Value[1] != Back_temp_Value[1])
        {
                Back_temp_Value[0] = Temp_Value[0];       
                Back_temp_Value[1] = Temp_Value[1];
                display_temp();       
        }
        //>=TEMP_4℃ 或 <=TEMP_1℃ ,电动全速转动,占空比为100%
        if(Signed_temp >= TEMP_4)  Signed_temp = TEMP_4;
        if(Signed_temp <= TEMP_1)  Signed_temp = TEMP_1;
        //>= TEMP_3 加速正转  TEMP_4全速正转
        if(Signed_temp >= TEMP_3)
        {
                MA = 1; MB = 0;                //正转
                if(Signed_temp == TEMP_3)         //占空比:0%
                {
                        PWM1 = 0;
                        delayXus(30);
                        return;
                }else
                if(Signed_temp == TEMP_4)        //占空比:100%
                {
                        PWM1 = 1;
                        delayXus(30);
                        return;
                }
                PWM1 = 1;                                        //占空比:0~100%
                delayXus(Signed_temp - TEMP_3);
                PWM1 = 0;
                delayXus(TEMP_4 - Signed_temp);

        }else
        if(Signed_temp <= TEMP_2)//<= TEMP_2 加速反转 TEMP_1 全速反转
        {
                MA = 0; MB = 1;          //反转
                if(Signed_temp == TEMP_2)         //占空比:0%
                {
                        PWM1 = 0;
                        delayXus(10);
                        return;
                }else
                if(Signed_temp == TEMP_1)        //占空比:100%
                {
                        PWM1 = 1;
                        delayXus(10);
                        return;
                }
                PWM1 = 1;                                        //占空比:0~100%
                delayXus(TEMP_2 - Signed_temp);
                PWM1 = 0;
                delayXus(Signed_temp - TEMP_1);
        }else//由运动→停止
        {
                MA = 0;
                MB = 0;
        }
}

void main()
{
        LCD_init();
        read_temp();
        delay_(50000);
        delay_(50000);
        TMOD = 0x01;
        TH0 = -50000 / 256;
        TL0 = -50000 % 256;
        IE = 0x82;
        TR0 = 1;
        while(1);
}

回复评论 (5)

LCD只是亮是怎么回事?显字吗?
开始的时候最好别做系统设计,一步一步的来,先分块调,每一块调好了再组合到一起比较好。有问题也比较容易找
既然keil和Proteus都有,你可以仿真看看啊,单步运行看看每一步是不是和预想的一样。
点赞  2013-5-16 21:15

回复 沙发 jishuaihu 的帖子

我就是仿真看的 LCD亮就是只是背光亮  没有字符显示...
我分成温度采集模块和电机驱动模块两块来着 在温度采集模块的时候  字符写不进去 温度也采集不了 但是我看着各个写指令写数据的函数功能都有 就有点懵了

我们上学期学的单片机 学校里讲的比较浅 有些兼容性的问题不是很懂  想自己多接触接触  顺便提高单片机的应用能力
点赞  2013-5-16 21:47
1602.rar (111.45 KB)
(下载次数: 31, 2013-5-17 21:22 上传)

没时间帮你看程序了,这个里面有可以用的1602的程序,你参考一下吧,控制部分的自己仿真一下
用protues和keil联调,仿真的时候单步运行,很容易找出问题所在的!
点赞  2013-5-17 21:22

回复 4楼 jishuaihu 的帖子

谢谢你了 虽然是1302 但是原理生的也差不多 我再改改 试着调试调试
点赞  2013-5-19 19:52
你现在调出来没?楼主
点赞  2015-1-4 16:06
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复