原创 AVR学习日志(五十一)—学习使用外部扩展端口

2010-11-8 15:14 2683 6 6 分类: MCU/ 嵌入式

        
       


        又是周一了,又该上班了,懒猫也该继续自己的学习之路,今天学习使用外部扩展端口—8255A,这个芯片懒猫还是在学微机原理时认识它的,也许现在单片机的I/O口多了,也许是现在串行的芯片多了,所以这个芯片现在好像用的不太多,但作为学习之用,懒猫觉得还是值得作一次试验。关于这次的硬件电路如下:


5b30bfe4-ffc8-4682-b618-d6e44e72f5a7.JPG


图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];   //送段码


         _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一次中断。当然时钟计时时没有去掉计数数值重装时间,与加指令耗费的时间,所以时钟不是太精确。如果想更精确可以查看一下反汇编,把这些损耗的时间去掉。


 


 


 


 


 


再喊一下口号,鼓励一下自己:


 


每天进步一点点,开心多一点^_^


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /1 下一条