打印

51单片机控制点阵字符亮5s,中断是怎么执行的

[复制链接]
466|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zoufeng0720|  楼主 | 2020-3-16 22:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>                //调用头文件
#include<intrins.h>     //包含有左移 右移 延时nop
typedef unsigned int u16;//数据类型声明定义
typedef unsigned char u8;
sbit SRCLK=P3^6;                   //   接P3-6口 74HC595 移位寄存器时钟输入 上升沿有效
sbit RCLK=P3^5;                   //         接P3-5口  数据 存储送入锁存器     上升沿有效
sbit SER=P3^4;                   //   接P3-4口   串行数据输入 一个字节
u8 code LEDduan[][8]={{0x00,0x00,0x3e,0x41,0x41,0x41,0x3e,0x00}, //0
{0x00,0x00,0x00,0x00,0x21,0x7f,0x01,0x00}, //1
{0x00,0x00,0x27,0x45,0x45,0x45,0x39,0x00}, //2
{0x00,0x00,0x22,0x49,0x49,0x49,0x36,0x00}, //3
{0x00,0x00,0x0c,0x14,0x24,0x7f,0x04,0x00}, //4
{0x00,0x00,0x72,0x51,0x51,0x51,0x4e,0x00}, //5
{0x00,0x00,0x3e,0x49,0x49,0x49,0x26,0x00}, //6
{0x00,0x00,0x40,0x40,0x40,0x4f,0x70,0x00}, //7
{0x00,0x00,0x36,0x49,0x49,0x49,0x36,0x00}, //8
{0x00,0x00,0x32,0x49,0x49,0x49,0x3e,0x00}, //9
{0x00,0x00,0x7F,0x48,0x48,0x30,0x00,0x00}, //P
{0x00,0x00,0x7F,0x48,0x4C,0x73,0x00,0x00}, //R
{0x00,0x00,0x7F,0x49,0x49,0x49,0x00,0x00}, //E
{0x00,0x00,0x3E,0x41,0x41,0x62,0x00,0x00}, //C
{0x00,0x00,0x7F,0x08,0x08,0x7F,0x00,0x00}, //H
{0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00}, //I
{0x00,0x7F,0x10,0x08,0x04,0x7F,0x00,0x00}, //N
{0x00,0x12,0x14,0x78,0x14,0x12,0x00,0x00},  //大
{0x00,0x08,0x12,0x01,0xFF,0x00,0x10,0x08},   //小
{0x7F,0x41,0x5D,0x55,0x5D,0x41,0x7F,0x00},  //回

{0x7C,0x48,0x48,0xFF,0x48,0x48,0x7C,0x00}};  //中
u8 LEDwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
void delay(u16 i)//定义延时函数
{
while(i--);
}
void HC595Send(u8 dat) //定义HC595函数,dat是形式参数          dat表示要输入数据
{
        u8 i ;
        SRCLK=0;           //移位时钟清零
        RCLK=0;                   //锁存输出清零
        for(i=0;i<8;i++)         //循环8次,从高位到低位 逐位输出8位SER数据
        {
          SER=dat>>7;                    
          /* 将dat右移7位 赋值给SER  dat数据不变 ; 例如 1001 1011  经过右移7位后
                                后7位全部移走 只剩之前最高位的1 ,1赋值给SER的最低位;
                                                        若下次循环,再赋值给SER的次最低位
                                               
                                            SER输出的值
                                                        1
                                                        0
   输入串行dat数据                        0
        1001 1011  →→→→→→                1
                                                        1
                                                        0
                                                        1
                                                        1
                                               

                                                  */
          dat<<=1;                          //dat左移1位,最高位移走 最低位补0;例如dat的值1001 1011左移一位以后 dat的值是0011 0110  这是为下次移次低高位做准备  下次移0011 0110 最高位的0
          SRCLK=1;                          //输出移位时钟信号,HC595锁存器从低到高移动一位锁存
          _nop_();                      // 延时一个周期
          _nop_();
          SRCLK=0;                           //移位寄存器拉低,为下次移位存储拉高准备
        }
        RCLK=1;                             //锁存已经全部移好的数据
}
void peizhi()
{
   TMOD|=0X01;        // TMOD或运算 选择为定时器0模式,工作方式1,仅用TR0打开起动
   TH0=0XFC;
   TL0=0X18;        //寄存器初始值  初始值+定时时间(1000)1MS=两个字节最大值FFFF(65535)+1           加1才能溢出,发出中断请求
   ET0=1;//打开定时器中断0
   EA=1;//打开总中断
   TR0=1;//打开定时器
}
static u16 m;
static u16 k;

void   main()
{
        peizhi();
        while(1)
                {
                u8 i;
                    for(i=0;i<8;i++)
                   {
                HC595Send(LEDduan[k][i]);
                P0=LEDwei[i];
                        delay(100);  
                         HC595Send(0x0);
               
           }
           }
           }
          
             

void Time0() interrupt 1
{
   TH0=0XFC;  //给是定时器初始值,下次定时就是按照这个初值
   TL0=0X18;
   m++;        //每中断一次,i就加一次,这样加1000次,达到1s
  if(m==5000)
{
    m=0;          //
        k++;
        if(k==21)
        {
         k=0 ;
        }         
         }
       
}

使用特权

评论回复
评论
zoufeng0720 2020-3-16 22:49 回复TA
二楼 提问,请问1 定时器 是一开始就计数对吧,程序是什么时候进入中断的? 第一次溢出吗?每溢出一次,中断一次m加一次? 问题2 主程序暂停进入中断,暂停时LED应该只显示某一行某列的LED,由于中断时间很短 肉眼发现不了?? 

相关帖子

沙发
叶春勇| | 2020-3-17 09:45 | 只看该作者
定时器 是一开始就计数对吧,程序是什么时候进入中断的? 第一次溢出吗?每溢出一次,中断一次m加一次?
答:当定时器由初值(TH0=0XFC;TL0=0X18; )加到0xffff后溢出。如果(ET0=1;//打开定时器中断0    EA=1;//打开总中断  TR0=1;//打开定时器)各种使能都设置好,有的单片机还要设置分频。进入定时器溢出中断。
问:第一次溢出吗?
答:只要各种使能都设置好,会在下一次溢出产生中断,不知是不是你的第一次。
问:每溢出一次,中断一次m加一次?
答:引     m++;        //每中断一次,i就加一次,这样加1000次,达到1s
根据你的注释,i加一次,是何意思。按你代码的意思,应该是要加一次。

问:主程序暂停进入中断,暂停时LED应该只显示某一行某列的LED,由于中断时间很短 肉眼发现不了??
中断处理时间很短,人眼有暂留效应。如果按照以前的电视机30hz,25hz刷新率。
例如你的LED取刷新率为25Hz,那么你每40ms要刷一次。每一次刷8组LED,每5ms要给HC595刷一次数据。而中断的执行时间很短。具体时间要看c编译后的汇编代码,查下执行时间。stc单片机有了改良,时间更短。


使用特权

评论回复
板凳
zoufeng0720|  楼主 | 2020-3-18 21:24 | 只看该作者
叶春勇 发表于 2020-3-17 09:45
定时器 是一开始就计数对吧,程序是什么时候进入中断的? 第一次溢出吗?每溢出一次,中断一次m加一次?
答 ...

谢谢了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

11

帖子

0

粉丝