找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1696|回复: 1
收起左侧

单片机+74hc164驱动数码管显示 乱码

[复制链接]
ID:5501 发表于 2021-4-23 16:52 | 显示全部楼层 |阅读模式
请交下师傅们 我写的这个代码164发送函数 放到主函数了就不能正常显示了  但是在中断函数里是可以正常显示秒表的 谢谢

单片机源程序如下:
/*
STC12C5406AD  12M CRYSTAL

Relay                P22
Display1        P25
Display2        P24
DATA_164        P23
CLK_164                P21
MR_164                P20
K1                P32
K2    P33
K3                P34
LED_Flash        P37
*/

#include "STC12C5630AD.H"
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int
        

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

sbit MR_164                        = P2^0;                        //Pin9
sbit CLK_164                = P2^1;                 //Pin8 clk
sbit DATA_164                = P2^3;

sbit Relay                        = P2^2;                 //relay
sbit GRID1                        = P2^4;
sbit GRID2                        = P2^5;

sbit Key_start  = P3^2;
sbit Key_Set          = P3^3;
sbit Key_Down          = P3^4;

sbit LED_Flash        = P3^7;
bit led_flag;
/*******************************************************************/

const unsigned char code  Led_data[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xfb};

unsigned int nCnt;
unsigned char sec=24,Cnt[2]={0xff,0xff};

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

/*****************************************************************/
void delayms (uint ms)
{
        unsigned int i;
        while( ms -- )
        {
                for (i = 0; i < 600; i ++);//600 1T   125 12T
        }
}



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

/*****************************************************************/
void IO_Mode_Setup (void)
{

        P2M1 = 0x00;        //0000 0000
        P2M0 = 0x00;
        P3M1 = 0x00;        //0000 0000
        P3M0 = 0x00;
        
}

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

/*****************************************************************/
void Timer0_init(void)
{
         AUXR &= 0x7f;//12t   
         TMOD &= 0xf0;
         TMOD |= 0x01;//mode 1  16bit
         TH0 = 0xf8;
         TL0 = 0x30;
         TR0 = 1;
         TF0 = 0;
}
/******************************************************************

/*****************************************************************/
void PORT_init(void)
{
;
}


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

/*****************************************************************/
void SendByteData_164(unsigned char temp)
{
        unsigned char i;
               
        for (i = 0; i < 8; i++ )
        {
                if (temp & 0x80 ){//′ó¸ßλ¿aê¼·¢Ëí
                                DATA_164 = 1;
                }
                else{
                                DATA_164 = 0;
                }                          
                        CLK_164 = 0;        
                        CLK_164 = 1;
                  temp = temp << 1;
         }
        CLK_164  = 0;        //êí·Å×üÏß
        DATA_164 = 0;
}




void  Timer0_isr (void) interrupt 1
{
        static unsigned int t=0;
        TH0 = 0xf8;  //12 2ms
        TL0 = 0x30;
        
        led_flag = ~led_flag;
        GRID1 = 1;
        GRID2 = 1;
        
  if(sec < 10){
                Cnt[0] = sec%10;
                Cnt[1] = 10;
        }else if(sec < 100){
                Cnt[1] = sec/10;
                Cnt[0] = sec%10;
        }else{
                sec = 0;
        }
        
                SendByteData_164(Led_data[Cnt[led_flag]]);
                if(led_flag )
                {
                        GRID1 = 0;
                }else {
                                        GRID2 = 0;
                }

        if(t++ >= 500)//2ms*500=1000ms
        {               
                sec++;
                LED_Flash = !LED_Flash;
                t = 0;        
                if(sec >= 100)
                {
                        sec = 0;
                }
        }
               
}

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

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

void main (void)
{
        
        IO_Mode_Setup ();
        Timer0_init();
        SendByteData_164(Led_data[0]);
        MR_164 = 1;  //164 pin9 master resert
//  GRID1 = 0;         //¿aÆôλ1
//        GRID2 = 0;
        Relay = 0;        //S8550 11Ø±Õ 0 ¿aÆô
        P3 &= 0x80;
        LED_Flash = 0;        
        ET0 = 1;
        EA = 1;
        
        while(1)
        {

//                SendByteData_164(Led_data[Cnt[led_flag]]);
//这个函数放到这里 秒表就显示两个8.8. 不能正常显示走动走时了 但是放到中断函数里是正常显示秒表的
               
               
        }//end while(1)               

}//end main()













回复

使用道具 举报

ID:332214 发表于 2021-4-23 17:40 | 显示全部楼层
放在主函数里 是因为被定时器中断抢占了 Cnt[led_flag], 这个变量在改变。
这就相当于 两个线程共用一个变量,一个线程在赋值,另一个在取值,这中间不加个互斥锁,会报错的。
但单片机的中断和系统上的线程还是有差异的,中断执行时,主函数程序是暂停的。
解决办法:就是在主程序调用这个变量的时候 不被定时器中断打断去改变这个值。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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