AVR单片机_实验2:数码管显示实验

曾巧文 发布于:2012-4-29 16:50 标签: 实验 单片机 AVR

1 实验目的

通过实验,掌握如何通过74HC595扩展IO口,掌握如何运用动态扫描的方法驱动多位数码管;掌握外部中断的使用方法。

2 实验内容

1、完成74HC595芯片驱动函数,通过串转并芯片实现GPIO的扩展。

2、实现4位数码管的动态扫描显示。

3、通过外部中断对按键次数计数,并通过数码管显示;

3 实验预习要求

仔细阅读74HC595芯片的数据手册,了解相关的时序。参考教材P183、P186和P221三个实例部分。

  1. 实验步骤

1、启动ICCAVR,创建一个工程文件,理解74HC595芯片的驱动程序思想,完成74HC595的驱动程序编写,使4位数码管亮起来。

2、在第一步的基础上添加相应代码,实现4位数码管的动态扫描显示,即4位数码管能显示不同的数字,如1234。选择【Project】->【Rebuild All】编译工程,通过PROGISP程序下载程序到单片机,观察实验现象。

3、按键INT1(在原理图中为SW8)连接到了单片机的PD3引脚上,将其配置为外部中断1(INT1),通过中断的方法实现对按键计数,并通过数码管显示;

注:实验中要使用的管脚有:PD4、PD5、PD6、PD7、PB0、PB1、PA0,各管脚连接请参照原理图。

注:使用ICC的application builder来自动生成初始化代码和中断函数的定义;

AVR单片机|AVR单片机_实验2:数码管显示实验


1 实验目的

通过实验,掌握如何通过74HC595扩展GPIO,驱动8段数码管,从芯片数据手册中抽取有用的信息。

2 实验内容

1、完成74HC595芯片驱动函数,通过串转并芯片实现GPIO的扩展。

2、实现4位数码管的动态扫描显示。

3 完成74Hc595的驱动函数,写实验代码(测试方法,PD4、PD5、PD6、PD7输出低电平,然后通过74HC595输出0xA4,观察实验现象

 

//ICC-AVR application builder : 2010-4-6 下午 10:28:10
// Target : M16
// Crystal: 7.3728Mhz

#include <iom16v.h>
#include <macros.h>

//定义字符表 		   														
unsigned char led_7[14]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
		 	  			 0x80,0x90,0xff,0x7f,0xc6,0x00};
						 
unsigned char Disp_data[4]={0x01,0x02,0x03,0x04};
						 
#define CLR_SHCLK()  		PORTB&=~(1<<1)		  //移位时钟 SCLK
#define SET_SHCLK()  		PORTB|=(1<<1)		  //移位时钟 SCLK,上升沿

#define CLR_STCLK()  		PORTB&=~(1<<0)		  //锁存时钟 RCLK
#define SET_STCLK()  		PORTB|=(1<<0)		  //拉高锁存时钟,上升沿

#define CLR_DS()			PORTA&=~(1<<0)		  //清零
#define SET_DS()			PORTA|=(1<<0)		  //置位


void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x01;
 PORTB = 0x00;
 DDRB  = 0x03;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0xF8;//置PORTD[7..3]为输出状态
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}


void delayMs(int counter)
{
   int i;
   while(counter--)
   {
       for(i=0; i<(187*7); i++)
	   {}
   }

}
/************************************************************
*功  能:74hc595发送字节函数
*说  明:Byte 为要发送的字节
************************************************************/
void HC595_send_byte(unsigned char SndData)
{
    char i;
    for(i=0;i<8;i++)
    {  
        if(SndData&(1<<(7-i)))
        {
            SET_DS();
        }
        else
        {
            CLR_DS();
        }
		CLR_SHCLK();		  //移位时钟 SCLK
        SET_SHCLK();		  //移位时钟 SCLK,上升沿
    }
	CLR_STCLK();			  
	SET_STCLK();			  //拉高锁存时钟,上升沿
}

int main(void)
{
    unsigned char i;
    init_devices();
    
	while(1)
	{
	   for(i=0; i<4; i++)
	   {
	   	  
	       HC595_send_byte(led_7[Disp_data[i]]);	//调用Disp_data[4]显示1.2.3.4	  
		   PORTD &= ~(1<<(7-i));//置PORTD[7..4]为0,让第几个个数码管点亮,从PORTD7开始ps:X & 0 == 0
		   delayMs(1);
		   PORTD |= 0xf0; //置PORTD[7..4]为1
		      
	   }
	
	}
    return 0;

} 

4     实现四位数码管的动态扫描显示;通过动态扫描的方式让四位数码管分别显示"1234"。写出动态扫描函数的实验代码:

  

//ICC-AVR application builder : 2010-4-6 下午 10:28:10
// Target : M16
// Crystal: 7.3728Mhz

#include <iom16v.h>
#include <macros.h>

//定义字符表 		   														
unsigned char led_7[14]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
		 	  			 0x80,0x90,0xff,0x7f,0xc6,0x00};
						 
unsigned char Disp_data[4]={0x01,0x02,0x03,0x04};
						 
#define CLR_SHCLK()  		PORTB&=~(1<<1)		  //移位时钟 SCLK
#define SET_SHCLK()  		PORTB|=(1<<1)		  //移位时钟 SCLK,上升沿

#define CLR_STCLK()  		PORTB&=~(1<<0)		  //锁存时钟 RCLK
#define SET_STCLK()  		PORTB|=(1<<0)		  //拉高锁存时钟,上升沿

#define CLR_DS()			PORTA&=~(1<<0)		  //清零
#define SET_DS()			PORTA|=(1<<0)		  //置位


void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x01;
 PORTB = 0x00;
 DDRB  = 0x03;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0xF8;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}


void delayMs(int counter)
{
   int i;
   while(counter--)
   {
       for(i=0; i<(187*7); i++)
	   {}
   }

}
/************************************************************
*功  能:74hc595发送字节函数
*说  明:Byte 为要发送的字节
************************************************************/
void HC595_send_byte(unsigned char SndData)
{
    char i;
    for(i=0;i<8;i++)
    {  
        if(SndData&(1<<(7-i)))
        {
            SET_DS();
        }
        else
        {
            CLR_DS();
        }
		CLR_SHCLK();		  //移位时钟 SCLK
        SET_SHCLK();		  //移位时钟 SCLK,上升沿
    }
	CLR_STCLK();			  
	SET_STCLK();			  //拉高锁存时钟,上升沿
}

int main(void)
{
    unsigned char i;
    init_devices();
    
	while(1)
	{
	   for(i=0; i<4; i++)
	   {
	   	  
	       HC595_send_byte(led_7[Disp_data[i]]);		  
		   PORTD &= ~(1<<(7-i));
		   delayMs(1);	  //?
		   PORTD |= 0xf0; 
		      
	   }
	
	}
    return 0;

}

 

5、判断按键SW8(INT1)是否按下,并对按键次数计数,显示在数码管之上;(单片机刚启动后,数码管显示为全0,当第一次按下SW8后,数码管显示0001,当第二次按下SW8后,数码管显示0002)

  

//ICC-AVR application builder : 2010-4-6 下午 10:28:10
// Target : M16
// Crystal: 7.3728Mhz

#include <iom16v.h>
#include <macros.h>

//定义字符表 		   														
unsigned char led_7[14]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
		 	  			 0x80,0x90,0xff,0x7f,0xc6,0x00};
						 
unsigned char Disp_data[4]={1,2,3,4};
						 
#define CLR_SHCLK()  		PORTB&=~(1<<1)		  //移位时钟 SCLK
#define SET_SHCLK()  		PORTB|=(1<<1)		  //移位时钟 SCLK,上升沿

#define CLR_STCLK()  		PORTB&=~(1<<0)		  //锁存时钟 RCLK
#define SET_STCLK()  		PORTB|=(1<<0)		  //拉高锁存时钟,上升沿

#define CLR_DS()			PORTA&=~(1<<0)		  //清零
#define SET_DS()			PORTA|=(1<<0)		  //置位


void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x01;
 PORTB = 0x08;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x08;
 PORTD = 0x00;
 DDRD  = 0xf0;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}


void delayMs(int counter)
{
   int i;
   while(counter--)
   {
       for(i=0; i<(187*7); i++)
	   {}
   }

}
/************************************************************
*功  能:74hc595发送字节函数
*说  明:Byte 为要发送的字节
************************************************************/
void HC595_send_byte(unsigned char SndData)
{
    char i;
    for(i=0;i<8;i++)
    {  
        if(SndData&(1<<(7-i)))
        {
            SET_DS();
        }
        else
        {
            CLR_DS();
        }
		CLR_SHCLK();		  //移位时钟 SCLK
        SET_SHCLK();		  //移位时钟 SCLK,上升沿
    }
	CLR_STCLK();			  
	SET_STCLK();			  //拉高锁存时钟,上升沿
}

int main(void)
{
    unsigned char i, j,data = 0;
    init_devices();
    
	while(1)
	{
	       if(!(PIND & (1 << 3)))
		   {
		       delayMs(100);
			   while(!(PIND & (1 << 3)));
			   data++;
		   }
		   HC595_send_byte(led_7[data%10]); 
		   PORTD = ~(1<<(4));
		   delayMs(1);
		   HC595_send_byte(led_7[data/10%10]);
		   PORTD = ~(1<<(5));
		   delayMs(1);
		   HC595_send_byte(led_7[data/100%10]);
		   PORTD = ~(1<<(6));
		   delayMs(1);
		   HC595_send_byte(led_7[data/1000]);
		   PORTD = ~(1<<(7));
		   delayMs(1);
		   /*
	       Disp_data[0] = data%10;
		   Disp_data[1] = data/10%10;
		   Disp_data[2] = data/100%10;
		   Disp_data[3] = data/1000;*/
		  /*  for(i=4;i<8;i++)
		   {
		     PORTD &= ~(1<<(7-i));
	         HC595_send_byte(led_7[Disp_data[i-4]]);  
		    
		     delayMs(100);
		   }*/
		    PORTD |= 0xf0;
	}
    return 0;

}

版权所有:《曾巧文博客-关注互联网IT技术,记录生活点滴》 => 《AVR单片机_实验2:数码管显示实验
本文地址://qiaowen.net/post-1184.html
除非注明,文章均为 《曾巧文博客-关注互联网IT技术,记录生活点滴》 原创,欢迎转载!转载请注明本文地址,谢谢。

有 4535 人浏览,获得评论 0 条

发表评论:

Powered by emlog 粤ICP备12040901号

>>本作品采用-知识共享署名-非商业-禁止演绎-协议-进行许可 |站点地图 | | | | 开放分类目录 |