||
EX_INTERFACE_OP
作者:懒猫爱飞
2010-11-8
图1-1 硬件测试电路
关于8255的操作与操作外部SRAM的原理一样,只是配置改了一下而已,8255的基本操作有如下几种:
操作 |
A1 |
A0 |
CS |
RD |
WR |
说明 |
读操作 |
0 |
0 |
0 |
0 |
1 |
PA-->数据总线 |
0 |
1 |
0 |
0 |
1 |
PB-->数据总线 | |
1 |
0 |
0 |
0 |
1 |
PC-->数据总线 | |
1 |
1 |
0 |
0 |
1 |
控制字-->数据总线 | |
写操作 |
0 |
0 |
0 |
1 |
0 |
数据总线-->PA |
0 |
1 |
0 |
1 |
0 |
数据总线-->PB | |
1 |
0 |
0 |
1 |
0 |
数据总线-->PC | |
1 |
1 |
0 |
1 |
0 |
数据总线-->控制字 |
关于8255命令是怎么设置工作方式的可以研究一下8255的数据手册。上面讲的都很详细,虽然是英文的手册,不过单词都不是太难,希望你能啃啃它^_^
说一下软件部分,主要有三个文件—main.c、main.h、timer0.h。main.c中包括主程序与定时中断函数;main.h中主要是一些全局变量及一些头文件与一些宏定义;timer0.h中主要就是timer0的初始化函数。之所以弄这么多文件,主要是为了修改方便,想修改哪个函数,直接找到哪个文件就可以 了。好了,把程序贴出来;
一、 main.c
/*********************************************************************************
//文件名称:main.c
//功 能:学习使用单片机外部扩展的内存
//作 者:懒猫爱飞
//建立日期:2010.11.05
//备 注:MCU-ATmega8515 开发环境-winavr100110 Crystal-8MHz
*********************************************************************************/
//#include "main.h"
#include "timer0.h"
/*********************************************************************************
//函数名称:void dis_time(void)
//功 能:显示时间
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
**********************************************************************************/
void dis_time(void)
{
uint8_t i;
Dis_Buf[0] = hour/10; //取秒的十位,下面的类似
Dis_Buf[1] = hour%10; //取秒的个位, ...
Dis_Buf[3] = min/10;
Dis_Buf[4] = min%10;
Dis_Buf[6] = sec/10;
Dis_Buf[7] = sec%10;
for(i=0; i<8; i++)
{
*PB = _BV(i); //送位码
*PA = (uint8_t)Dis_Code[Dis_Buf[i]]; //送段码
_delay_ms(5);
*PB = 0; //消隐一下
}
}
/*********************************************************************************
//函数名称:int main(void)
//功 能:主函数
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
*********************************************************************************/
int main(void)
{
MCUCR |= 0x80; //允许访问外部接口
*COM = 0b10001001; //8255工作方式选择0,PA,PB输出,PC输入
timer0_init();
while(1)
{
dis_time();
}
return 0;
}
/*********************************************************************************
//函数名称:ISR(TIMER0_OVF_vect )
//功 能:timer0 定时中断
//入口参数:中断微量vector(7)
//出口参数:NULL
//备 注:NULL
*********************************************************************************/
ISR(TIMER0_OVF_vect)
{
Timer0_Off();
TCNT0 = 0x83;
//没有去掉重载时间及加命令耗时,所以时间不是太精确,只做实验用途
t_cunt ++;
if(t_cunt == 250)
{
t_cunt = 0; //1秒钟到,秒加1
sec++;
if(sec == 60)
{
sec = 1; //分钟加1
min++;
if(min == 60)
{
min =1;
hour++; //小时加1
if(hour == 24)
{
hour = 1;
}
}
}
}
Timer0_On();
}
二、 main.h
/******************************************************************
//文件名称:main.h
//功 能:主要包括一些头文件与一些宏定义
//作 者:懒猫爱飞
//建立日期:2010.11.05
//备 注:MCU-ATmega8515 开发环境-winavr100110 Crystal-8MHz
******************************************************************/
#ifndef _MAIN_H_
#define _MAIN_H_
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdint.h>
#include <avr/interrupt.h>
//关于8255的一些宏定义
#define PA (volatile uint8_t *)0xff00
#define PB (volatile uint8_t *)0xff01
#define PC (volatile uint8_t *)0xff02
#define COM (volatile uint8_t *)0xff03
uint16_t t_cunt = 0; //计时用
uint8_t sec = 0; //秒计数
uint8_t min = 24; //分计数
uint8_t hour = 12; //时计数初始时间12:24:00
uint8_t last_key_state = 0xff; //存储按键上次的状态
uint8_t select_flag = 0; //选择标志
//共阳数码管码表,最后一个为“-”
const uint8_t Dis_Code[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf
};
//显示缓存
uint8_t Dis_Buf[] = {1,0,10,1,1,10,0,8};
#endif
三、 timer0.h
/**********************************************************************************
//文件名称:timer0.h
//功 能:主要是timer0的一些定义与函数
//作 者:懒猫爱飞
//建立日期:2010.11.05
//备 注:MCU-ATmega8515 开发环境-winavr100110 Crystal-8MHz
**********************************************************************************/
#ifndef _TIMER0_H_
#define _TIMER0_H_
#include "main.h"
#define Timer0_On() TIMSK |= _BV(TOIE0)
#define Timer0_Off() TIMSK &= ~_BV(TOIE0)
/**********************************************************************************
//函数名称:void timer0_init(void)
//功 能:定时器0初始化函数
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
**********************************************************************************/
void timer0_init(void)
{
cli(); //先关闭所有的中断
TCCR0 |= _BV(CS02); //256分频
TCNT0 = 0x83; //定时4ms
TIMSK |= _BV(TOIE0); //开定时器0
sei(); //开中断
}
#endif
ATmega8515外部在用8M晶振,定时器0在256分频时,定时4ms精确度最高,所以这次定时设置为4ms一次中断。当然时钟计时时没有去掉计数数值重装时间,与加指令耗费的时间,所以时钟不是太精确。如果想更精确可以查看一下反汇编,把这些损耗的时间去掉。
再喊一下口号,鼓励一下自己:
每天进步一点点,开心多一点^_^