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日

悬赏问题

  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题