找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2473|回复: 9
收起左侧

51单片机用定时器后数码管乱跳,麻烦各位大佬指点

[复制链接]
ID:842537 发表于 2020-12-13 14:09 | 显示全部楼层 |阅读模式
代码如下,没用定时器数码管正常显示温度,用定时器后乱跳(定时器用来调节占空比调速,做的是一个温控风扇,部分函数省略)
麻烦各位大佬指点,万分感谢

#include "reg52.h"                         
#include"temp.h"       

typedef unsigned int u16;
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit IN1=P3^0;
sbit IN2=P3^1;
sbit ENA=P3^2;


u8 DisplayData[8];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint n;
uchar time;
uint flag=100;
bit flag1s=0;

void delay(u16 i)//延时函数,i=1时,大约延时10us
{
        while(i--);       
}



void datapros(int temp) //温度读取处理         
{
           float tp;  
        if(temp< 0)                                //当温度值为负数
          {
                DisplayData[0] = 0x40;           //   第一位数码管显示负号
                //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;       
                //留两个小数点就*100,+0.5是四舍五入
          }
        else
          {                       
                DisplayData[0] = 0x00;
                tp=temp;//如果温度为正,读取的温度为其本身               
                temp=tp*0.0625*100+0.5;       
        }
        DisplayData[1] = smgduan[temp % 10000 / 1000];
        DisplayData[2] = smgduan[temp % 1000 / 100]|0x80;//显示小数点
        DisplayData[3] = smgduan[temp %  100 / 10];
        DisplayData[4] = smgduan[temp %  10 / 1];

        if(temp>1400){
        n=100;}
        else{n=50;}
       
}


/*******************************************************************************
* 函数名         :DigDisplay()
* 函数功能                 :数码管显示函数
* 输入           : 无
* 输出                  : 无
*******************************************************************************/
void DigDisplay()
{
        u8 i;
        for(i=0;i<6;i++)
        {
                switch(i)         //位选,选择点亮的数码管,
                {
                        case(0):
                                LSA=1;LSB=1;LSC=1; break;//显示第0位
                        case(1):
                                LSA=0;LSB=1;LSC=1; break;//显示第1位
                        case(2):
                                LSA=1;LSB=0;LSC=1; break;//显示第2位
                        case(3):
                                LSA=0;LSB=0;LSC=1; break;//显示第3位
                        case(4):
                                LSA=1;LSB=1;LSC=0; break;//显示第4位
                        case(5):
                                LSA=0;LSB=1;LSC=0; break;//显示第5位
                }
                P0=DisplayData[i];//发送数据
          delay(100); //间隔一段时间扫描       
                P0=0x00;//消隐
        }               
}



void interrupt_init()
{
  TMOD=0x01;
        TH0=0xfc;
        TL0=0x18;
        ET0=1;
        TR0=1;
        EA=1;
       
}
void main()//主函数
{
interrupt_init();
        while(1)
        {
                datapros(Ds18b20ReadTemp());         //数据处理函数
                DigDisplay();    //数码管显示函数

                       
        }               
}

void Timer0() interrupt 1
{
        TR0=0;
TH0=0xfc;
        TL0=0x18;
        TR0=1;
        time++;
        if(time=flag)
        {
        time=0;       
        }
        if(time<=n)
        {
        ENA=1;
        IN1=1;
                IN2=0;
        }


}

回复

使用道具 举报

ID:275826 发表于 2020-12-13 17:56 | 显示全部楼层
读温度的顺序被中断打乱了
回复

使用道具 举报

ID:258566 发表于 2020-12-13 18:01 | 显示全部楼层
void DigDisplay()
{
        u8 i;
        for (i = 0; i < 6; i++)
        {
                P0 = 0x00;        //消隐
                switch (i)        //位选,选择点亮的数码管,
                {
                        case (0):
                                LSA = 1;
                                LSB = 1;
                                LSC = 1;
                                break;        //显示第0位
                        case (1):
                                LSA = 0;
                                LSB = 1;
                                LSC = 1;
                                break;        //显示第1位
                        case (2):
                                LSA = 1;
                                LSB = 0;
                                LSC = 1;
                                break;        //显示第2位
                        case (3):
                                LSA = 0;
                                LSB = 0;
                                LSC = 1;
                                break;        //显示第3位
                        case (4):
                                LSA = 1;
                                LSB = 1;
                                LSC = 0;
                                break;        //显示第4位
                        case (5):
                                LSA = 0;
                                LSB = 1;
                                LSC = 0;
                                break;        //显示第5位
                }
                P0 = DisplayData[ i];        //发送数据
                delay(100);        //间隔一段时间扫描      
               
        }
}
回复

使用道具 举报

ID:275826 发表于 2020-12-13 19:42 | 显示全部楼层
三楼修改显示程序是没有用的
回复

使用道具 举报

ID:57657 发表于 2020-12-13 20:07 | 显示全部楼层
读温度前把中断关了,然后打开。
ET0=0;datapros(Ds18b20ReadTemp());ET0=1;
回复

使用道具 举报

ID:859752 发表于 2020-12-13 21:23 | 显示全部楼层
中断错了
回复

使用道具 举报

ID:213173 发表于 2020-12-13 22:43 | 显示全部楼层
楼主程序中断处理不当,中断干扰读取温度和数码管动态扫描,反过来温度不正常又影响占空比。给你改了,你试试。 温控.zip (63.96 KB, 下载次数: 23)
回复

使用道具 举报

ID:258566 发表于 2020-12-14 06:39 来自手机 | 显示全部楼层
显示有问题,虽然时钟速度快看不出来区别,但是逻辑应该是更改位码前把段码显示关闭。
回复

使用道具 举报

ID:65956 发表于 2020-12-14 08:25 | 显示全部楼层
给提供个建议,显示可以用定时器定时刷新,这样能保证显示不受其它函数计算等的影响,主函数才是去作温度读取与计算的事,因为定时器运行是优先于主函数里其它函数的运行
回复

使用道具 举报

ID:847958 发表于 2020-12-14 11:16 | 显示全部楼层
读温度的顺序被中断打乱了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表