瑞萨单片机之定时器中断实现数码管动态扫描(四)

一、实现原理

数码管的驱动方式很简单,图中的A B C D E F G Dp (8个段 含点)分别代表的数码管的每个段(笔画),需要显示什么就把相应的段点亮即可。

例如: 数码管为共阴数码管 显示数字 1

A 并口驱动:P0 =0x06 ; COM =0;//单片机并口 B C 段置1,位选端口置 0 即可显示1 ,数码管的位数比较多的话就只需要采用动态扫描即可,只要扫描的时间足够短,人眼几乎看不到抖动。

**B 非并口驱动:**并不是所有的单片机并口都是完整的,对于小封装的单片机一个完成的并口几乎很难找。(大一暑假的时候也是通过这种当时想确定数码管结果失败了。。。 当时还在自学单片机,自己太菜了,当然现在也很菜 哈哈哈)
想通了其实也很简单:B+C 不就是1 吗?这种拼接的方式就是有点麻烦,后面主要采用这种方式

请添加图片描述

二、具体实现

由于手里的瑞萨单片机并口不完全,我只能采用拼接的方式实现驱动。

  1. 驱动IO 宏定义
#define SEG_A  	P2.3
#define SEG_B  	P1.0
#define SEG_C  	P1.1
#define SEG_D  	P1.2
#define SEG_E  	P1.3
#define SEG_F  	P1.4
#define SEG_G  	P6.1
#define SEG_DP  P6.0

#define COM1  P4.2
#define COM2  P4.1
#define COM3  P2.1
#define COM4  P2.2
  1. 数码扫描函数,这个函数主要放定时器中断里面
void display_scan(u8 pos,u8 isPoint,u8 num)
{
 
       SEG_A=0;SEG_B=0;SEG_C=0;SEG_D=0;SEG_E=0;SEG_F=0;SEG_G=0;SEG_DP=0;
		
		switch(pos)
		{ 
		 case 1:
	  	   COM1=0;COM2=1;COM3=1;COM4=1;
   		 break;
		case 2:
	  	   COM1=1;COM2=0;COM3=1;COM4=1;
	  	break;
		case 3:
		  COM1=1;COM2=1;COM3=0;COM4=1;
	 	break;
		case 4:
		  COM1=1;COM2=1;COM3=1;COM4=0;
	 	break;
		}
		
  switch(num)
  {
   case 0:SEG_A=1;SEG_B=1;SEG_C=1;SEG_D=1;SEG_E=1;SEG_F=1;SEG_G=0;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//0
   case 1:SEG_A=0;SEG_B=1;SEG_C=1;SEG_D=0;SEG_E=0;SEG_F=0;SEG_G=0;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//1
   case 2:SEG_A=1;SEG_B=1;SEG_C=0;SEG_D=1;SEG_E=1;SEG_F=0;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//2
   case 3:SEG_A=1;SEG_B=1;SEG_C=1;SEG_D=1;SEG_E=0;SEG_F=0;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//3
   case 4:SEG_A=0;SEG_B=1;SEG_C=1;SEG_D=0;SEG_E=0;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//4
   case 5:SEG_A=1;SEG_B=0;SEG_C=1;SEG_D=1;SEG_E=0;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//5
   case 6:SEG_A=1;SEG_B=0;SEG_C=1;SEG_D=1;SEG_E=1;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//6
   case 7:SEG_A=1;SEG_B=1;SEG_C=1;SEG_D=0;SEG_E=0;SEG_F=0;SEG_G=0;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//7
   case 8:SEG_A=1;SEG_B=1;SEG_C=1;SEG_D=1;SEG_E=1;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//8
   case 9:SEG_A=1;SEG_B=1;SEG_C=1;SEG_D=1;SEG_E=0;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//9
   case 10:SEG_A=0;SEG_B=1;SEG_C=1;SEG_D=1;SEG_E=1;SEG_F=1;SEG_G=0;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//10 U
   case 11:SEG_A=1;SEG_B=0;SEG_C=0;SEG_D=0;SEG_E=1;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//11 F
   case 12:SEG_A=0;SEG_B=0;SEG_C=0;SEG_D=0;SEG_E=0;SEG_F=0;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//12 -
   case 13:SEG_A=0;SEG_B=1;SEG_C=1;SEG_D=0;SEG_E=1;SEG_F=1;SEG_G=1;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//13 H
   case 14:SEG_A=0;SEG_B=0;SEG_C=0;SEG_D=0;SEG_E=0;SEG_F=0;SEG_G=0;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//14 关显示
  // case 15:SEG_A=0;SEG_B=1;SEG_C=1;SEG_D=0;SEG_E=1;SEG_F=1;SEG_G=0;if(isPoint)SEG_DP=1;else SEG_DP=0;break;//15 
  }
		
}
  1. 设置显示内容函数,主要向显存中添加需要显示的数据
/*************************************************************************
**@函数功能: 数码管显示内容设置
**@参数:   pos--->显示的位置 
**         isPoint--->是否带点 1:带点 0:不带点
**         buffer ---->显示缓存
**         data --->需要显示的数据
**@返回值: 无
**@作者: XiaoYoung
**@版本及日期 2021/9/23
**@更新说明:
**************************************************************************/
u8 display_buffer[8];//显示缓存

void set_display_buffer(u8 pos,u8 isPoint,u8 *buffer,u8 data)
{
  switch(pos)
  {
   case 1: if(isPoint) buffer[4] =1;else buffer[4]=0; buffer[0] = data; break;
   case 2: if(isPoint) buffer[5] =1;else buffer[5]=0; buffer[1] = data; break;          
   case 3: if(isPoint) buffer[6] =1;else buffer[6]=0; buffer[2] = data; break;
   case 4: if(isPoint) buffer[7] =1;else buffer[7]=0; buffer[3] = data; break;  
  }
}
  1. 瑞萨单片机定时中断中:
__interrupt static void r_tau0_channel0_interrupt(void)
{
    /**************数码管相关*********/
       seg_pos++;
       
       if(seg_pos>4) 
       { 
         seg_pos=1;
       }       
       switch(seg_pos)
       {
         case 1:display_scan(seg_pos,display_buffer[4],display_buffer[0]);break;
         case 2:display_scan(seg_pos,display_buffer[5],display_buffer[1]);break;
         case 3:display_scan(seg_pos,display_buffer[6],display_buffer[2]);break;
         case 4:display_scan(seg_pos,display_buffer[7],display_buffer[3]);break;         
       }      
    }
}

三、例子

显示 666.6

int main(void)
{

  while(1)
  {
        set_display_buffer(1,0,display_buffer,6);
        set_display_buffer(2,0,display_buffer,6);
        set_display_buffer(3,1,display_buffer,6);
        set_display_buffer(4,0,display_buffer,6);

  }
}
   

效果图片请添加图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值