gfdncs 2023-04-13 21:13 采纳率: 50%
浏览 26
已结题

关于#51单片机#的问题:我在主程序循环里延时1秒,数码管就刷新不动了. 我在串口中断程序里延时,能减少串口输出频率,但不解决根本问题.

STC89C51单片机连接2字数码管,每秒增加1. 即01.02.03...60, 再回零循环. 这段没有问题,我知道数码管是不停的刷新形成视觉差显示数字.
但此时我想把数码管显示的数字,通过串口发送给电脑, 从COM1发送到COM2,接受正常.但是我收到的是每秒几百个01.02.03... 虽然这也是正常的. 但不是我想要的,我只想每增加一次数字,串口仅发送一次数码管等值的数据. 该怎么实现呢?

img

#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int

uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //LED0-9对应的管码

uchar data_L,data_H; //定义个位和十位数据类型 
uchar t,a; //计数
unsigned int num;  //建立全局变量

void delay(uint k) //延时0.1ms函数
{
    uint m,n;
    for(m=0;m<k;m++)
    {
        for(n=0;n<120;n++);
    }
}

void display (void) //显示函数
{
    P2=0x01;                    //d7-d0=00000001 ,p2^0=1 高电平,数码管不亮。
    P0=tab[data_H];        //十位数字显示,按照tab表的顺序取值。
    delay(1);                    //延时0.1ms
    P2=0x02;                    //d7-d0=00000010,p2^1=1 高电平,数码管不亮。
    P0=tab[data_L];        //个位数字显示,按照tab表的顺序取值。
    delay(1);                    //延时0.1ms
}

void Timer0() interrupt 1 //T0定时器,方式1 50ms 计时
{
    t++;                            //每t满50ms,自加
    TH0=0x4c;                  //TMOD初值
    TL0=0x00;                  //TMOD初值
}
void data_tim(void) //59s 计数
{
    if(t==20)                    //t自加到t=20时,累计20*50ms=1s, 
    {
        a++;                        //a自加
        t=0;                        //t=20时,累计到1s,t清零,重新开始累计1s.
        if(a==60)                //当a=60,59s计时计数
        {
            a=0;                    //a清零,重新开始累计a.
        }
    }
}

void data_in(void)     //分割数值到十位和个位
{
    data_L=a%10;            //取a除10的余数,例如25/10=25,个位数就是5.
    data_H=a/10;            //取a整除10的值,例如25/10=25,十位取整就是2.
}

void T0_init(void) //T0定时器初始化
{
    TMOD=0x01;                 //T0计时器以方式1工作
    TH0=0x4C;                    //50ms初值
    TL0=0x00;                    //50ms初值
    ET0=1;                         //允许T0计时器中断 
    TR0=1;                         //启动T0计时器
    EA=1;                         //开启总中断
}



void UartInit(void)        //串口初始化 9600bps@11.0592MHz
{
    PCON |= 0x80;        //使能波特率倍速位SMOD
    SCON = 0x50;        //8位数据,可变波特率
    TMOD &= 0x0F;        //设置定时器模式
    TMOD |= 0x20;        //设置定时器模式
    TL1 = 0xFA;            //设置定时初始值
    TH1 = 0xFA;            //设置定时重载值
    ET1 = 0;            //禁止定时器中断
    TR1 = 1;            //定时器1开始计时
}


void Uart_Send_Byte(unsigned char Byte)  //串口中断服务函数
{
    SBUF = Byte;
    while(TI==0);
    TI=0;
}

    
void main(void)
{
    a=0;                            //计数从0开始
    T0_init();                //T0计时器初始化
    UartInit();                //串口初始化
    while(1)                    //循环
    {
        data_tim();            //59s计数
        data_in();            //分割十位个位
        display();            //显示        
        Uart_Send_Byte(a); //发送字符
    }
    
}
  • 写回答

2条回答 默认 最新

  • qllaoda 2023-04-13 21:59
    关注

    在定时器中断里刷新LED

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 4月23日
  • 已采纳回答 4月15日
  • 创建了问题 4月13日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效