8253可编程定时/计数器片内含3个独立的16位计数器,计数器均为递减计数,各计数器的工作方式与初值由软件设置.本例运行时,按下8255 PC端口接键K1可启动8253定时器0,定时器0工作于方式5,程序给8253提供随机的定时初值,定时到达后GATE0触发INT0中断,中断程序输出提示音,并重置定时器
Proteus运行截图:
Atmel Studio6.2编译通过载图:
程序清单:
/*
* GccApplication22.c
*
* Created: 2014-11-26 19:42:19
* Author: Administrator
*/
#define F_CPU 2000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdint.h>
#define PA_8255 *(uint8_t *)0xFFB0
#define PB_8255 *(uint8_t *)0xFFB1
#define PC_8255 *(uint8_t *)0xFFB2
#define COM_8255 *(uint8_t *)0xFFB3
#define TC0_8253 (uint8_t *)0xFF70
#define COM_8253 (uint8_t *)0xFF73
#define TC0_G1() PORTB |= _BV(PB6)
#define TC0_G0() PORTB &=~_BV(PB6)
#define BEEP() PORTB^=_BV(PB0)
const uint8_t SEG_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
uint8_t Disp_Buffer[8] = {0,0,0,0,0,0,0,0};
uint8_t Pre_Key_State = 0x00;
volatile uint16_t TC0_Count = 510;
void Sounder()
{
uint8_t i;
for(i=0;i<100;i++)
{
BEEP();_delay_us(180);
}
}
void Set_8253_TC0()
{
TC0_G0();
* COM_8253 = 0x3A;
TC0_Count = rand() %600;
*(uint16_t*)TC0_8253 = (uint8_t)TC0_Count;
*TC0_8253=(uint8_t)(TC0_Count>>8);
TC0_G1();
}
void Key_Process()
{
uint8_t Key_State;
Key_State = PC_8255;
if(Key_State == Pre_Key_State)return;
Pre_Key_State = Key_State;
switch(Key_State)
{
case(uint8_t)~_BV(0):Set_8253_TC0();
sei();
break;
default:break;
}
}
int main()
{
uint8_t i; uint16_t cnt;
DDRA = 0xFF;DDRB = 0xFF;
DDRD = ~(_BV(PD2)|_BV(PD3));
srand(87);
MCUCR |= 0x82;
COM_8255 = 0B10001001;
GICR = 0x40;
while(1)
{
cnt = TC0_Count;
for(i=0;i<8;i++)
{
Disp_Buffer = cnt % 10;
cnt /= 10;
PB_8255 = _BV(7-i);
PA_8255 = (uint8_t)SEG_CODE[Disp_Buffer];
_delay_ms(2);
Key_Process();
}
}
}
ISR(INT0_vect)
{
Sounder();
Set_8253_TC0();
}
|