数码之家

 找回密码
 立即注册
搜索
查看: 1895|回复: 13

[C51] 诺基亚5110屏幕显示会影响51定时器0的中断

[复制链接]
发表于 2019-9-14 17:32:44 来自手机浏览器 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 叶秋雨丶 于 2019-9-14 19:26 编辑

帮忙看一下是为什么,显示的时候中断会暂停,是因为spi的原因么?现在显示是在定时器1的中断里,直接在主程序里调用5110显示是不影响定时器0的。
显示程序在定时器1中断里显示的时候定时器0会暂停。


#include "nokia_5110.h"
#include "stdio.h"

//***********************************
#define                delay_time        25767


/********************************************************************/

sbit LED0=P4^4;                                //单片机工作指示灯
sbit BL=P4^0;                                //屏幕背景灯
sbit Input1=P0^1;                          //霍尔信号输入
sbit Input2=P0^2;
sbit Input3=P0^3;                          
sbit Input4=P3^4;                       
sbit Input5=P3^3;
sbit Input6=P3^2;
sbit Out1=P2^7;                                  //报警输出
sbit Out2=P2^6;          
sbit Out3=P2^5;
sbit Out4=P0^4;                               
sbit Out5=P0^5;                                         
sbit Out6=P0^6;
sbit Key1=P4^5;          
sbit Key2=P4^1;
sbit Key3=P4^6;
sbit Key4=P0^7;

unsigned char Display[4];
unsigned int Speed=0;
unsigned int Time=0;
unsigned int a=0;
unsigned char Alarm1=0;
unsigned char Alarm2=0;
unsigned char Alarm3=0;
unsigned int H1=0;
unsigned int H2=0;
unsigned int H3=0;
unsigned int A1=0;
unsigned int A2=0;
unsigned int A3=0;
unsigned int T1=0;
unsigned int T2=0;
unsigned int T3=0;
unsigned int X1=0;
unsigned int X2=0;
unsigned int X3=0;                  
unsigned int Key=0;
unsigned int Num=0;

void GetKey(void)
{
if(Key1==0||Key2==0||Key3==0||Key4==0)                                  //判断是否有按键按下
        {
                        switch(Key)
                        {
                                case 0:if(Key1==0)
                                                {          
                                                        Key=1;
                                                        break;
                                                }
                                                if(Key2==0)
                                                {Key=2;break;}
                                                if(Key3==0)
                                                {Key=3;break;}
                                                if(Key4==0)
                                                {Key=4;break;}
                                case 1:if(Key1==0)
                                           {Num++;}
                                           else
                                           {Num=0;Key=0;}
                                           break;
                                case 2:if(Key2==0)
                                           {Num++;}
                                              else
                                           {Num=0;Key=0;}
                                           break;
                                case 3:if(Key3==0)
                                           {Num++;}
                                           else
                                           {Num=0;Key=0;}
                                           break;
                            case 4:if(Key4==0)
                                           {Num++;}
                                           else
                                           {Num=0;Key=0;}
                                           break;
                        }
               
        }
        else
        {Key=0;Num=0;}       
}

void Timer0() interrupt 1                        //定时器0
{
T1++;T2++;T3++;
Input2=0;
if(Input1==0)                                                  //霍尔1信号检测               
        {
                switch(A1)                                               
                {
                        case 0:        A1++;break;
                        case 1:        A1++;break;
                        case 2:        if(H1==0)
                                        X1=0;
                                        H1=H1+T1;
                                        T1=0;
                                        X1++;
                                        break;
                }       
        }
        else
        {
                A1=0;
        }
Input2=1;

/*if(Input2==0)                                                  //霍尔2信号检测               
        {
                switch(A2)
                {
                        case 0:        A2++;break;
                        case 1:        A2++;break;
                        case 2:        H2=T2;
                                        X2++;
                                        if(X2==19)
                                        X2=0;
                }       
        }
        else
        {
                A2=0;
        }

if(Input1==0)                                                  //霍尔3信号检测               
        {
                switch(A1)
                {
                        case 0:        A1++;break;
                        case 1:        A1++;break;
                        case 2:        H1=T1;
                                        X1++;
                                        if(X1==19)
                                        X1=0;
                }       
        }
        else
        {
                A1=0;
        } */
}

void Timer1() interrupt 3                                 //定时器1
{
        TH1=(65536-18432)/256;
        TL1=(65536-18432)%256;
        Time++;
        GetKey();                                                         //按键读取
        switch(Time)
        {
                case 1: //LCD_write_english_string(0,1,"C301:");                //菜单刷新
                                //LCD_write_english_string(0,2,"C302:");
                                //LCD_write_english_string(0,3,"C303:");
                                break;                               
                case 13:break;                                                                                //调试参数显示
                /*case 14:
                                sprintf(Display,"%4u",A1);                                               
                                LCD_write_english_string(54,0,Display);
                               
                                break;                               
                /*case 15:sprintf(Display,"%4u",X1);                                               
                                LCD_write_english_string(0,0,Display);
                                sprintf(Display,"%4u",H1);                                               
                                LCD_write_english_string(30,0,Display);
                                if(X1==0)                                                                        //转速1计算显示
                                {Alarm1=1;}
                                Speed=240000*X1/H1;
                                if(Speed<380)
                                {Alarm1=1;}
                                sprintf(Display,"%4u",Speed);                                               
                                LCD_write_english_string(30,1,Display);
                                H1=0;
                                break;                                       
/*                case 16:if(X2==0)                                                                        //转速2计算显示
                                {Alarm2=1;}
                                Speed=240000*X2/H2;
                                if(Speed<380)
                                {Alarm2=1;}
                                sprintf(Display,"%4u",Speed);                                               
                                LCD_write_english_string(30,2,Display);
                                X2=0;
                                break;                               
                case 17:if(X3==0)                                                                        //转速3计算显示
                                {Alarm3=1;}
                                Speed=240000*X3/H3;
                                if(Speed<380)
                                {Alarm3=1;}
                                sprintf(Display,"%4u",Speed);                                               
                                LCD_write_english_string(30,2,Display);
                                X3=0;
                                break;       
                                */
                case 20:if(Input4==1)
                                if(Alarm1==1||Alarm2==1||Alarm3==1)
                                Out4=1;
                                break;       
                case 21:break;               
                case 25:Time=0;LED0=~LED0;break;                                       
        }               
}
/******************************************************************************/
void main(void)
{
        LCD_init(); //初始化液晶   
        LCD_clear();
        TL0=TH0=256-230;
        TH1=(65536-18432)/256;
        TL1=(65536-18432)%256;
        P4SW=0x70;                        //P4.4   P4.5当做普通IO口来用
        P0M1=0x00;                        //P0.4 P0.5 P0.6设置为推挽输出
        P0M0=0x70;
        P2M1=0x00;        //P2.7 P2.6        P2.5设置为推挽输出
        P2M0=0xE0;
        P4M1=0x00;        //P4.0设置为推挽输出
        P4M0=0x01;
        TMOD=0x12;        //定时器1工作在16位          定时器0工作在8位
        EA=1;                //全局中断打开
        ET0=1;                //定时器0打开
        TR0=1;                //定时器开关打开
        ET1=1;
        TR1=1;
        while(1)  
        {
                BL=1;
                LCD_write_english_string(0,1,"C301:");
        }          
}


#include "nokia_5110.h"
#include "english_6x8_pixel.h"


/*-----------------------------------------------------------------------
LCD_init          : 3310LCD初始化

编写日期          :2004-8-10
最后修改日期      :2004-8-10
-----------------------------------------------------------------------*/

void delay_1us(void)                 //1us延时函数
  {
   unsigned int i;
  for(i=0;i<1000;i++);
  }

  void delay_1ms(void)                 //1ms延时函数
  {
   unsigned int i;
   for (i=0;i<1140;i++);
  }
  
void delay_nms(unsigned int n)       //N ms延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
  }


void LCD_init(void)
  {
            // 产生一个让LCD复位的低电平脉冲
   LCD_RST = 0;
    delay_1us();

   LCD_RST = 1;
   
                // 关闭LCD
   LCD_CE = 0;
    delay_1us();
                // 使能LCD
   LCD_CE = 1;
    delay_1us();

    LCD_write_byte(0x21, 0);        // 使用扩展命令设置LCD模式
    LCD_write_byte(0xc0, 0);        // 设置偏置电压
    LCD_write_byte(0x06, 0);        // 温度校正
    LCD_write_byte(0x13, 0);        // 1:48
    LCD_write_byte(0x20, 0);        // 使用基本命令
    LCD_clear();                                // 清屏
    LCD_write_byte(0x0c, 0);        // 设定显示模式,正常显示
           LCD_CE = 0;                                           // 关闭LCD
  }

/*-----------------------------------------------------------------------
LCD_clear         : LCD清屏函数

编写日期          :2004-8-10
最后修改日期      :2004-8-10
-----------------------------------------------------------------------*/
void LCD_clear(void)
  {
    unsigned int i;

    LCD_write_byte(0x0c, 0);                        
    LCD_write_byte(0x80, 0);                        

    for (i=0; i<504; i++)
      LCD_write_byte(0, 1);                        
  }

/*-----------------------------------------------------------------------
LCD_set_XY        : 设置LCD坐标函数

输入参数:X       :0-83
          Y       :0-5

编写日期          :2004-8-10
最后修改日期      :2004-8-10
-----------------------------------------------------------------------*/
void LCD_set_XY(unsigned char X, unsigned char Y)
  {
    LCD_write_byte(0x40 | Y, 0);                // column
    LCD_write_byte(0x80 | X, 0);                  // row
  }

/*-----------------------------------------------------------------------
LCD_write_char    : 显示英文字符

输入参数:c       :显示的字符;

编写日期          :2004-8-10
最后修改日期      :2004-8-10
-----------------------------------------------------------------------*/
void LCD_write_char(unsigned char c)
  {
    unsigned char line;

    c -= 32;

    for (line=0; line<6; line++)
      LCD_write_byte(font6x8[c][line], 1);
  }

/*-----------------------------------------------------------------------
LCD_write_english_String  : 英文字符串显示函数

输入参数:*s      :英文字符串指针;
          X、Y    : 显示字符串的位置,x 0-83 ,y 0-5

编写日期          :2004-8-10
最后修改日期      :2004-8-10                 
-----------------------------------------------------------------------*/
void LCD_write_english_string(unsigned char X,unsigned char Y,char *s)
  {
    LCD_set_XY(X,Y);
    while (*s)
      {
         LCD_write_char(*s);
         s++;
      }
  }
/*-----------------------------------------------------------------------
LCD_write_byte    : 使用SPI接口写数据到LCD

输入参数:data    :写入的数据;
          command :写数据/命令选择;

编写日期          :2004-8-10
最后修改日期      :2004-8-13
-----------------------------------------------------------------------*/
void LCD_write_byte(unsigned char dat, unsigned char command)
  {
    unsigned char i;
    //PORTB &= ~LCD_CE ;                        // 使能LCD
    LCD_CE = 0;
   
    if (command == 0)
     // PORTB &= ~LCD_DC ;                // 传送命令
     LCD_DC = 0;
    else
     // PORTB |= LCD_DC ;                        // 传送数据
     LCD_DC = 1;
                for(i=0;i<8;i++)
                {
                        if(dat&0x80)
                                SDIN = 1;
                        else
                                SDIN = 0;
                        SCLK = 0;
                        dat = dat << 1;
                        SCLK = 1;
                }
   // SPDR = data;                        // 传送数据到SPI寄存器

    //while ((SPSR & 0x80) == 0);         // 等待数据传送完毕
        
    //PORTB |= LCD_CE ;                        // 关闭LCD
     LCD_CE = 1;
  }

打赏

参与人数 1家元 +30 收起 理由
家睦 + 30

查看全部打赏

发表于 2019-9-14 17:47:11 | 显示全部楼层
理论上不会出现这种情况啊。。。
回复 支持 反对

使用道具 举报

发表于 2019-9-14 18:56:37 | 显示全部楼层
用的是什么单片机,这里好像看不出有什么跟中断有关的代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-14 19:08:55 来自手机浏览器 | 显示全部楼层
xing122005 发表于 2019-9-14 18:56
用的是什么单片机,这里好像看不出有什么跟中断有关的代码

stc的12c5a60s2
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-14 19:29:40 | 显示全部楼层
怎么回事啊。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2019-9-14 23:10:41 | 显示全部楼层
中断里面写屏幕 找死
回复 支持 反对

使用道具 举报

发表于 2019-9-14 23:12:55 | 显示全部楼层
写屏任务巨耗时 占着中断,别的中断怎么进来?
不是定时器0暂停,是没进中断重装

打赏

参与人数 1家元 +10 收起 理由
杨雪飞 + 10 熱心助人

查看全部打赏

回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-15 06:07:21 来自手机浏览器 | 显示全部楼层
2545889167 发表于 2019-9-14 23:12
写屏任务巨耗时 占着中断,别的中断怎么进来?
不是定时器0暂停,是没进中断重装
...

屏幕在定时器1里,定时器0不是可以中断定时器1么
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-15 06:08:19 来自手机浏览器 | 显示全部楼层
2545889167 发表于 2019-9-14 23:12
写屏任务巨耗时 占着中断,别的中断怎么进来?
不是定时器0暂停,是没进中断重装
...

我现在把写屏幕放到了每1s的最后20ms里了,中断停了影响我测的转速值。
回复 支持 反对

使用道具 举报

发表于 2019-9-16 23:39:17 | 显示全部楼层


是不是这样的理解呢。。。。。。单任务的程序,同时一时刻做不了多件事情的。。。。。。。。。
回复 支持 反对

使用道具 举报

发表于 2019-9-17 14:35:11 | 显示全部楼层
哈哈,用双单片机吧,一块专门负责刷屏。
回复 支持 反对

使用道具 举报

发表于 2019-9-17 22:35:56 | 显示全部楼层

定时中断函数的执行时间比定时中断的时间还要长,想想都可怕,是什么样的人才可以写出这样的程序。
回复 支持 反对

使用道具 举报

发表于 2019-9-18 10:11:51 | 显示全部楼层
本帖最后由 netbeetle 于 2019-9-18 10:13 编辑

你把显示放在TIM1的中断处理函数里面,中断处理函数不处理完是不会释放控制权,所以你的的TIM0中断是不能正常产生的,都要等TIM1中断处理完才可以。所以不要把太长的程序放在中断函数里面。你一定要这么搞,就设定下中断优先级,把TIM0的中断优先级设成高于TIM1的,这样只要TIM0发生中断,不管TIM1的中断处理完毕没有,都会去优先处理TIIM1的中断。
回复 支持 反对

使用道具 举报

发表于 2019-9-23 08:27:12 | 显示全部楼层
中断服务子程序不要太长,检测状态设置标志位即可,然后在主程序里面处理。
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-16 20:00 , Processed in 0.858001 second(s), 16 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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