综合实验——165、595、计数器秒表

实验描述:

利用计数器中断做秒表程序,再利用165芯片读取当前的按键状态,然后利用595芯片将当前时间显示到八位数码管上 。并且随时响应用户的按键行为。

代码优点:可防止用户按键时间过长而误判。

代码缺点:暂停与开始功能彻底阻断了所有中断。使得秒表在暂停的时候无法响应任何中断。

#include  < iom8v.h >
#include 
< macros.h >

/*******************************
* PC0  --------   M595_SER     *
* PC1 --------    M595_SRCLK   *
* PC2  --------   M595_RCLK    *
* PC3  ---------  M165_PL      *
* PC4 ----------  M165_CP       *
* PC5 ----------  M165_Q7      *
* PD0~3 --------  G1~4         *
* K1~K2 --------  M165_D0 ~ D1 *
* a~h ----------- M595_Q0 ~ Q7 *
******************************
*/


#define  M165_CP_LOW (PORTC &= ~BIT(PC4))
#define  M165_CP_HIGH (PORTC |= BIT(PC4))
#define  M165_PL_LOW (PORTC &= ~BIT(PC3))
#define  M165_PL_HIGH (PORTC |= BIT(PC3))
#define  M165_Q7 ((PINC & BIT(PC5)) ? BIT(0) : 0x00)
#define  M595_SER_HIGH (PORTC |= BIT(PC0))
#define  M595_SER_LOW (PORTC &= ~BIT(PC0))
#define  M595_SRCLK_HIGH (PORTC |= BIT(PC1))
#define  M595_SRCLK_LOW (PORTC &= ~BIT(PC1))
#define  M595_RCLK_HIGH (PORTC |= BIT(PC2))
#define  M595_RCLK_LOW (PORTC &= ~BIT(PC2))
#define  LED_BIT_SELECT PORTD
#define  KEY1_UP(n) ((n & BIT(0)) ? 0x01 : 0x00)
#define  KEY1_DOWN(n) ((n & BIT(0)) ? 0x00 : 0x01)
#define  KEY2_UP(n) ((n & BIT(1)) ? 0x01 : 0x00)
#define  KEY2_DOWN(n) ((n & BIT(1)) ? 0x00: 0x01)

UINT16 LED_TEXT[
24 =   {0x3F0x060x5B0x4F0x660x6D0x7D0x07,
0x7F0x6F0x770x7C0x390x5E0x790x71,
0x730x380x760x3E0x500x080x400x00}
;

// 8位数码管的24种状态。0-9分别代表了十个数字的代码

#pragma  interrupt_handler timer0_ovf_isr:iv_TIM0_OVF

UINT16 g_Time_Count;            
// 时间数

void  Count_Increase( void )         // 时间增加函数
{
    g_Time_Count
++;
    
if(g_Time_Count > 9999)
    
{
        g_Time_Count 
= 0;
    }

}

void  Count_Clear( void )             // 时间清空函数
{
    timer0_init();            
//计数器复位
    g_Time_Count = 0;        //时间清零
}


void  Pause_Or_Start( void )         // 暂停或者继续
{
    
static UINT8 state = 0;
    state 
= !state;
    
if (state)
    
{
        CLI();
    }

    
else
    
{
        SEI();
    }

}


void  timer0_ovf_isr( void )
{
    
static UINT16 wCount = 0;
    TCNT0 
= 0x83//reload counter value
    if(wCount >= 1000
    
{
        wCount 
= 0;
        Count_Increase();
    }

    wCount
++;
}


void  Device_Init( void )
{
    Port_Init();
    
    
    
//stop errant interrupts until set up
    CLI(); //disable all interrupts
    timer0_init();
    
    MCUCR 
= 0x00;
    GICR  
= 0x00;
    TIMSK 
= 0x01//timer interrupt sources
    SEI(); //re-enable interrupts
    
//all peripherals are now initialized
    
}

void  Port_Init( void )
{
    DDRD 
= 0xFF;
    DDRC 
= ~BIT(PC5);
    PORTD 
= 0xFF;
    PORTC 
= 0xFF;
}

void  Delay_MS(UINT16 wTimer)
{
    UINT16 i 
= 0,j = 0;
    
for (i = 0;i < wTimer;i++)
    
{
        
for (j = 0;j < 200;j++)
        
{;}
    }

}


void  Show_Led(UINT16 wNum)             // 将一个四位数显示到四个八位数码管上
{
    UINT8 chBit;
    
for(chBit = 0x08; chBit > 0; chBit >>= 1)        //从个位开始显示
    {
        
//        LED_BIT_DATA = ~LED_TEXT[wNum % 10];
        Write_Data_To_595(~LED_TEXT[wNum % 10]);        //将数字代码写入595芯片
        Show_M595_Data();                    //595芯片输出代码
        LED_BIT_SELECT = chBit;                //选择相应的位
        wNum /= 10;
        
if(wNum == 0)
        
{
            
return;
        }

    }

}


void  M165_Update_Data( void )         // 给芯片一个上升沿以更新595芯片存储的内容
{
    M165_PL_LOW;
    M165_PL_HIGH;
}


UINT8 Read_A_Byte_From_165(
void )     // 从165芯片中读取一个字节的内容
{
    UINT8 chCount 
= 0;
    UINT8 chResult 
= 0;
    M165_PL_HIGH;                    
//拉高PL端
    for(chCount = 0; chCount < 8++chCount)        //依次读取八位数
    {
        chResult 
<<= 1;
        chResult 
|= M165_Q7;
        M165_CP_LOW;            
//给出上升沿以使165移位
        NOP();
        M165_CP_HIGH;
    }

    
return chResult;
}


void  Write_Data_To_595(UINT8 chData)     // 向595芯片中写入值
{
    UINT8 chCount 
= 0;
    
for(chCount = 0; chCount < 8; chCount++)    //计数控制
    {
        M595_SRCLK_LOW;            
//拉低SRCLK端
        if((chData & BIT(7 - chCount)) != 0x00)        //根据当前位的状态将SER端拉高或拉低
        {
            M595_SER_HIGH;
        }

        
else
        
{
            M595_SER_LOW;
        }

        M595_SRCLK_HIGH;            
//给出上升沿
    }

}


void  Show_M595_Data( void )     // 在RCLK上给上升沿以输出595芯片内容
{
    M595_RCLK_LOW;
    NOP();
    M595_RCLK_HIGH;
}


void  timer0_init( void )         // 计数器初始化
{    
    TCCR0 
= 0x00//stop
    TCNT0 = 0x83//set count
    TCCR0 = 0x03//start timer
}


void  main()
{
    UINT8 chKey_State;                
//当前的所有按键状态
    UINT8 chKey_State_Pre = 0xFF;    //上次读取的按键状态
    g_Time_Count = 0;                //时间置零
    Device_Init();
    
while(1)
    
{
        M165_Update_Data();            
//165芯片更新数据
        chKey_State = Read_A_Byte_From_165();    //从165芯片中读取数据
        if (KEY1_UP(chKey_State_Pre) && KEY1_DOWN(chKey_State))    //如果KEY1刚被按下
        {
            Pause_Or_Start();        
//执行继续、暂停功能
        }

        
else if(KEY2_UP(chKey_State_Pre) && KEY2_DOWN(chKey_State))    //如果KEY2刚被按下
        {
            Count_Clear();            
//执行清零功能
        }

        chKey_State_Pre 
= chKey_State;
        Show_Led(g_Time_Count);        
//将当前时间显示到数码管
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值