您的位置:首页 > 其它

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

2008-03-24 16:22 330 查看
实验描述:

利用计数器中断做秒表程序,再利用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] = ...{0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,


0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71,


0x73, 0x38, 0x76, 0x3E, 0x50, 0x08, 0x40, 0x00};




//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); //将当前时间显示到数码管


}


}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: