ZmjOS单片机裸机编程风格 > DV_LED(STC系列的4段8位数码管驱动)


这是基于STC系列4段8位数码管驱动,异步方式自动将内部数据变量显示到数码管上,代码如下:

		//以下是DV_LED.H头文件部分
		#ifndef			__DV_LED__
		#define			__DV_LED__
		/*************************************************************************************************
		一个外部的3位8段数码管
		**************************************************************************************************/
		void DV_LED_init(void);
		void DV_LED_SetValue(unsigned char *value);
		#endif

		
		//以下是DV_LED.c正文文件部分
		#include "stc15w.h"
		#include "dv_led.h"
		//外部管脚定义:
		#define		LED_D0	P14
		#define		LED_D1	P32
		#define		LED_D2	P36
		#define		LED_D3	P12
		#define		LED_D4	P11
		#define		LED_D5	P37
		#define		LED_D6	P33
		#define		LED_D7	P10
		#define		LED_S0	P13
		#define		LED_S1	P15
		#define		LED_S2	P54
		//变量定义
		static unsigned char ledId;
		static unsigned char ledCodes[2];//三个用于现实到外部的led上的寄存器值
		static unsigned char code LedIntCode[8] = { 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F };//段码,共阴数码管
		//方法定义:
		static void DV_LED_Outcode(unsigned char ledcode);
		/************************************************************************************************
		功能:初始化设备串口设备
		输入:
		输出:
		*************************************************************************************************/
		void DV_LED_init()
		{
			P1M0 = 0X4E;//设置推挽输出
			P3M0 = 0XCA;
			P5M0 = 0X3A;
			//8毫秒@11.0592MHz//3*8*42=1002ms
			AUXR &= 0x7A;		//定时器时钟12T模式
			TMOD &= 0xE0;		//设置定时器模式
			TL0 = 0x3A;		//设置定时初值
			TH0 = 0xEA;		//设置定时初值
			TF0 = 0;		//清除TF0标志
			TR0 = 1;		//定时器0开始计时
			ET0 = 1;    //使能中断
			EA = 1;
			//变量初始化
			LED_D0 = 0;
			LED_D1 = 0;
			LED_D2 = 0;
			LED_D3 = 0;
			LED_D4 = 0;
			LED_D5 = 0;
			LED_D6 = 0;
			LED_D7 = 0;
			LED_S0 = 1;
			LED_S1 = 1;
			LED_S2 = 1;
			ledId = 0;
			ledCodes[0] = LedIntCode[0];
			ledCodes[1] = LedIntCode[0];
			ledCodes[2] = LedIntCode[0] | 0X80;
		}
		/************************************************************************************************
		功能:设置当前显示的值,
		输入:
		输出:
		*************************************************************************************************/
		void DV_LED_SetValue(unsigned char *value)
		{
		  unsigned short intvalue = (value[0] << 16 | value[1]);//获得整数部分
			unsigned char v;
			if(intvalue > 100){//这时显示的三位数都是整数
				v = intvalue / 100;//整数第一位
				v = v % 10;//限定在0-9
				ledCodes[0] = LedIntCode[v];
				v = intvalue / 10;//整数第二位
				v = v % 10;//限定在0-9
				ledCodes[1] = LedIntCode[v];
				v = intvalue % 10;//整数第三位
				ledCodes[2] = LedIntCode[v] | 0x80;//加上小数点
			}else if(intvalue > 10){//显示两个整数和一个小数
				v = intvalue / 10;//整数第一位
				v = v % 10;//限定在0-9
				ledCodes[0] = LedIntCode[v];
				v = intvalue % 10;//整数第二位
				ledCodes[1] = LedIntCode[v] | 0x80;//加上小数点
				v = value[2] / 10;
				v = v % 10;
				ledCodes[2] = LedIntCode[v];
			}else{
				v = intvalue % 10;//整数第一位
				ledCodes[0] = LedIntCode[v] | 0x80;//加上小数点
				v = value[2] / 10;
				v = v % 10;
				ledCodes[1] = LedIntCode[v];
				v = value[2] % 10;
				ledCodes[2] = LedIntCode[v];
			}
		}
		/************************************************************************************************
		功能:往外部io上输出段码
		输入:
		输出:
		*************************************************************************************************/
		static void DV_LED_Outcode(unsigned char ledcode)
		{
		  LED_D0 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D1 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D2 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D3 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D4 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D5 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D6 = ledcode & 0x01;
			ledcode >>= 1;
			LED_D7 = ledcode & 0x01;
		}
		/************************************************************************************************
		功能:定时器中断服务,用于定时刷新显示屏,20ms中断一次,每次中断后直接更新现实即可
		输入:
		输出:
		*************************************************************************************************/
		void DV_LED_Timerserver() interrupt 1
		{
		  switch(ledId)
			{
				case 0:
					LED_S2 = 1;//消隐
					DV_LED_Outcode(ledCodes[ledId]);
					LED_S0 = 0;//设置设置当前显示的位码
					ledId = 2;//设置下次
					break;
				case 1:
					LED_S0 = 1;//消隐
					DV_LED_Outcode(ledCodes[ledId]);
					LED_S1 = 0;//设置设置当前显示的位码
					ledId = 1;//设置下次
					break;
				case 2:
					LED_S1 = 1;//消隐
					DV_LED_Outcode(ledCodes[ledId]);
					LED_S2 = 0;//设置设置当前显示的位码
					ledId = 3;//设置下次
					break;
				default:
					ledId = 0;
					ledCodes[0] = LedIntCode[0];
					ledCodes[1] = LedIntCode[0];
					ledCodes[2] = LedIntCode[0];
					break;
			}
		}