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日

悬赏问题

  • ¥15 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥15 抖音看过的视频,缓存在哪个文件