Atmega128学习笔记第八站---扩展拔码开关

作者: 立行天下1
上传时间为: 2015-04-30 08:48 AM
2015-04-30
阅读:

    不知不觉我们已经走过了七站了,今天我们开始我们的第八站:Atmega128单片机扩展拔码开关的使用。

 在我们学习Atmega128单片机控制拔码开关之前,首先给大家普及下拔码开关的基础知识。

何为拔码开关?

拨码开关(也叫DIP开关,拨动开关,超频开关,地址开关,拨拉开关,数码开关,指拨开关)是一款用来操作控制的地址开关,采用的是0/1的二进制编码原理。通俗的说也就是一款能用手拨动的微型的开关,所以也通常叫指拨开关的也很多。拔码开关是一种有通、断两种稳定状态的开关,可以看做是一种特殊的按键,但是使用方法和按键是类似的,区别就是,不会自动恢复到未接通时候的状态。

一般拔码开关2~8个做成一组,用来设置地址码,给大家展示一种拔码开关,如图1:

                    图1. 4位拔码开关

      从上图1可以看到这个拔码开关,每一个键对应的背面上下各有两个引脚,拨至ON一侧,这下面两个引脚接通;反之则断开。这四个键是独立的,相互没有关联。此类元件多用于二进制编码。可以设接通为1;断开为0,则有:
  0000
  0001
  0010
  ……
  1110
  1111
  一共是16种编码

     之所以给大家讲Atmega128单片机控制拔码开关,是因为我们在工作中,某一个项目工程可能会用到很多的Atmega128单片机或者其他单片机,为了区分他们,就需要给他们编号,也就是给地址码,这个地址码可以写在程序代码中,但写在程序代码中的地址码不可以修改,在使用过程中就不方便,于是有人就想到了一种可以用手随时改变地址码的方法,也就是拔码开关的应用。

     本次实验使用一个8位的拔码开关来给Atmega128单片机设置地址码,然后用数码管将这个地址码显示出来。我们知道8位拔码开关可以设“0000~0xFF”共256个地址码,好了现在开始设计电路,电路图如下图2:

                    图2. Atmega128单片机扩展拔码开关电路图

     8位拔码开关连接到Atmega128单片机的PA端口,4位共阴极数码管的数据端连接在Atmega128单片机的PE端口上,控制引脚连接在PF0~PF3上。

     我们来构思下程序代码的思路:

     此程序包含以下几大点:

1、既然用到了数码管,就需要有数码管显示的字符编码,并且有数码管显示的函数,这个原理和代码我们在之前已经学习过了,我们通过一个子函数的形式被主函数调用来实现。

2、我们需要一个函数来读取拔码开关当前的地址码,然后把读取的地址码转换成十进制数字,为显示函数做好基础。

3、再通过一个显示的函数来显示这个地址码,并通过数码管显示。

     整理好思路,我们就来编代码吧:

#include<iom128v.h>

const unsigned char Dsy_index[]={0x08;0x04;0x02;0x01;0x80;0x40;0x20;0x10};

unsigned char Dsy_buf[]={16,16,16};

const unsigned char Dsy_code_cn[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};

unsigned char Key_code;

void delay_ms(uint ms)

{

uint i,j;

for( i=0;i<ms;i++)

for(j=0;j<1141;j++);

}

void Port_init(void)

{

DDRA=0x00;

PORTA=oxFF;

DDRE=0xFF;

PORTE=0xFF;

DDRF=0xFF;

PORTF=0xFF

}

unsigned char Key_scan()

{

if(PINA!=Key_code)

{

delay_ms(10);

if(PINA!=Key_code)

{

Key_code=PINA;

}

}

return Key_code;

}

void Num_dsy(unsigned char num)

{

unsigned char i,j;

Dsy_buf[0]=num/100;

Dsy_buf[1]=num/10;

Dsy_buf[2]=num;

for(i=0;i<3;i++)

{

PORTE=Dsy_code_cn[Dsy_buf]; PORTF=~Dsy_index[3-i]; delay_ms(10); PORTF=0xFF; }}

void main(void){ Port_init(); PORTC=0xEF; while(1) { Num_dsy(Key_scan());

}}

     针对函数给大家基本解读一下:

const unsigned char Dsy_index[]={0x08;0x04;0x02;0x01;0x80;0x40;0x20;0x10};

unsigned char Dsy_buf[]={16,16,16};

const unsigned char Dsy_code_cn[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00}; unsigned char Key_code;

     函数在最初对 Dsy_index[],Dsy_buf[],Dsy_code_cn[] 和Key_code进行了声明,Dsy_index[]是用来放数码管位选信号的,Dsy_buf[]是一个code 空间的缓冲区,可以用来暂时存放数码管显示字形编码,可以被后面程序调用。Dsy_code_cn[]这个就是数码管显示的字形编码,之前我们已经学习过了。Key_code用来存放我们设定的拔码开关的值,为程序中转换为10进制数准备。 

void delay_ms(uint ms)

{

uint i,j;

for( i=0;i<ms;i++)

for(j=0;j<1141;j++);

}

     毫无疑问,这个子函数就是延时子函数,用在程序中需要的延时,在我们这个程序中主要就是之前学习的延时消抖。

void Port_init(void)

{

DDRA=0x00;

PORTA=oxFF;

DDRE=0xFF;

PORTE=0xFF;

DDRF=0xFF;

PORTF=0xFF

}

      这个是Atmega128单片机IO端口初始化子函数,在我们这个实例中,使用PA端口来获取拔码开关的值,所以PA口设置为输入,PE引脚和PF引脚分别用来控制显示数字和位选,所以设置为输出。

unsigned char Key_scan()

{

if(PINA!=Key_code)

{

delay_ms(10);

if(PINA!=Key_code)

{

Key_code=PINA;

}

}

return Key_code;

}

     此子函数是读取拔码开关子函数,最初先消抖,然后再把读取PINA的电平,也就是拔码开关的电平,获得拔码开关的0/1二进制值。

void Num_dsy(unsigned char num)

{

unsigned char i,j;

Dsy_buf[0]=num/100;

Dsy_buf[1]=num/10;

Dsy_buf[2]=num;

for(i=0;i<3;i++)

{

PORTE=Dsy_code_cn[Dsy_buf];

PORTF=~Dsy_index[3-i];

delay_ms(10);

PORTF=0xFF;

}

}

     此函数是获取的拔码开关的0/1二进制数转换为10进制数,转换的数值暂时放在Dsy_buf[]进行缓存。

     大家实验一下,随机设置一个拔码开关的数值,观察数码管是否正确的显示数字出来?

     这个实例从另外一个方面跟我们日后要学习的DA转换很是想象,所以学好这个实例对我们日后的学习大有作用哦,学友们,你学会了吗?   

     本次的文章就到这,我们下期再见,感谢大家的观看,谢谢。

全部评论 ()
条评论
写评论

创建讨论帖子

登录 后参与评论
系统提示