数码管进行0~9999的计数实验
程序声明KF8F系列单片机开发板演示程序标 题: 数码管进行0~9999的计数实验项 目 名: 03-Number_count_TEST
开发环境:ChipON IDE
作 者:上海芯旺微电子有限公司
功能简述: 数码管进行0~9999的计数,到达9999后,又从0开始。
硬件说明
KF8F312单片机的P1端口P10-P17连接七段数码管的a,b,c,d,e,f,g,dp。
P24-P27分别接显示位(个位,十位,百位,千位)的公共端, 该数码管为共阴
数码管,所以若要点亮数码管,首先将该位的显示公共端置低电平,然后将要显
示的那一段置高电平。如:要在个位上显示0,需将P24置低电平,P10-P15置高
电平,P16,P17置低电平。原理图如图1,图2所示。单片机的P10~P17跳上跳
线,P24~P27跳上跳线,所需跳线如图3所示。
程序设计说明
由于驱动数码管使用到了P1、P2端口,所以首先需将P1、P2端口方向设置为
输出。由于个十百千位共用了P1端口,所以只能分时显示各位,先显示第一位,
再显示第二位,依次循环,由于人眼的视觉停留,快速的切换显示位便无法察觉
到。数值计数累加先加个位,如果个位的值加到10,那么个位归零,十位加1,
以此类推。加到10000的时候将每一位清零。数码管显示流程图如图4所示,主函
数运行流程图如图5所示。 综上,该程序主要包含以下几块:
① 器件初始化子函数
② 数码管显示子函数
③ 主函数(数值累加循环显示) 综上,该程序主要包含以下几块:
① 器件初始化子函数
② 数码管显示子函数
③ 主函数(数值累加循环显示) C程序代码 #include<kf8f312.h>
/*********************宏定义******************************/
#define uchar unsigned char
#define uint unsigned int
/*********************宏定义结束**************************/
/*********************全局变量****************************/
uchar const Arr_num[] = {0X3F,
0X06,
0X5B,
0X4F,
0X66,
0X6D,
0X7D,
0X07,
0X7F,
0X6F
}; //共阴接法
uchar Unit, Decade, Hundred, Thousand; //定义个十百千位
/*********************全局变量结束************************/
/******************函数声明*******************************/
void Init_fun();
void Display();
void Delay_200us();
/******************函数声明结束***************************/
/************************
* 函数名 :init_fun
* 函数功能:初始化函数
* 入口参数:无
* 返回 :无
************************/
void Init_fun()
{
OSCCTL = 0x60; //设置为8M
/*********端口初始化***********/
TR0 = 0x08; //设置P03端口为输入
TR1 = 0x00; //设置P1端口为输出
TR2 = 0x00; //设置P2端口为输出
P0 = 0;
P1 = 0;
P2 = 0xF0; //关闭数码管位选端
}
/************************
* 函数名 :display
* 函数功能:数码管显示
* 入口参数:显示数字
* 返回 :无
************************/
void Display()
{
uint i; // 控制显示时长,确定自增的速度
for(i = 0; i < 500; i++)
{
P2 = 0XE0; //打开数码管的 个位
P1 = Arr_num;
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
P2 = 0XD0; //打开数码管的 十位
P1 = Arr_num;
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
P2 = 0XB0; //打开数码管的 百位
P1 = Arr_num;
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
P2 = 0X70; //打开数码管的 千位
P1 = Arr_num;
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
}
}
/************************
* 函数名 :Delay_200us
* 函数功能:短时间延时
* 入口参数:无
* 返回 :无
************************/
void Delay_200us()
{
uchar i = 60;
while(--i);
}
/************************
* 函数名 :main
* 函数功能:程序入口主函数
* 入口参数:无
* 返回 :无
************************/
void main()
{
Unit = Decade = Hundred = Thousand = 0;
Init_fun();
while(1)
{
Unit++; //个位加1
if(Unit == 10) //如果个位的值加到10,那么个位归零,
十位加1,以下以此类推
{
Unit = 0;
Decade++;
if(Decade == 10)
{
Decade = 0;
Hundred++;
if(Hundred == 10)
{
Hundred = 0;
Thousand++;
if(Thousand == 10)
{
Thousand = 0;
}
}
}
}
Display(); //显示函数调用
}
}
//中断函数
void int_fun() __interrupt
{
} 3.4.2 汇编程序代码
.INCLUDE "KF8F312.INC"
;;;;;;;;;;;;;;;;通用寄存器;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY_NUM1 .EQU 0X81 ;延时用的临时变量
DELAY_NUM2 .EQU 0X82 ;延时用的临时变量
PSW_TEMP .EQU 0X85 ;PSW的临时保存变量
PCH_TEMP .EQU 0X86 ;PCH的临时保存变量
UNIT .EQU 0X88 ;数码管个位
DECADE .EQU 0X89 ;数码管十位
HUNDRED .EQU 0X8A ;数码管百位
THOUSAND .EQU 0X8B ;数码管千位
DIS_DEL .EQU 0X8C ;DIS_DEL是用来延时数值的递增用的,
数值越大,那么递增的速度就越慢
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ORG 0X0000
NOP
JMP MAIN ;入口
.ORG 0X0004
JMP INTERRUPT
;*************************************************************
*****************
;* 函 数 名: DIG_DATA
;* 函数功能: 数码管显示数据编码
;* 入口参数: 无
;* 返 回: R0,数码管显示的编码值
;* 注意 : 查表函数需在程序开头定义,避免编译后表中元素存在Flash的不
同页造成查表出错
;*************************************************************
***************** 汇编程序代码 .INCLUDE "KF8F312.INC"
;;;;;;;;;;;;;;;;通用寄存器;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY_NUM1 .EQU 0X81 ;延时用的临时变量
DELAY_NUM2 .EQU 0X82 ;延时用的临时变量
PSW_TEMP .EQU 0X85 ;PSW的临时保存变量
PCH_TEMP .EQU 0X86 ;PCH的临时保存变量
UNIT .EQU 0X88 ;数码管个位
DECADE .EQU 0X89 ;数码管十位
HUNDRED .EQU 0X8A ;数码管百位
THOUSAND .EQU 0X8B ;数码管千位
DIS_DEL .EQU 0X8C ;DIS_DEL是用来延时数值的递增用的,
数值越大,那么递增的速度就越慢
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ORG 0X0000
NOP
JMP MAIN ;入口
.ORG 0X0004
JMP INTERRUPT
;*************************************************************
*****************
;* 函 数 名: DIG_DATA
;* 函数功能: 数码管显示数据编码
;* 入口参数: 无
;* 返 回: R0,数码管显示的编码值
;* 注意 : 查表函数需在程序开头定义,避免编译后表中元素存在Flash的不
同页造成查表出错
;*************************************************************
***************** DIG_DATA
ADD PCL,R2
RRET R0 ,#0X3F ;0
RRET R0 ,#0X06 ;1
RRET R0 ,#0X5B ;2
RRET R0 ,#0X4F ;3
RRET R0 ,#0X66 ;4
RRET R0 ,#0X6D ;5
RRET R0 ,#0X7D ;6
RRET R0 ,#0X07 ;7
RRET R0 ,#0X7F ;8
RRET R0 ,#0X6F ;9
RRET R0 ,#0X77 ;A
RRET R0 ,#0X7C ;B
RRET R0 ,#0X39 ;C
RRET R0 ,#0X5E ;D
RRET R0 ,#0X79 ;E
RRET R0 ,#0X71 ;F
RRET R0 ,#0X00 ;空
;;;;;;;;;;;;;;;中断部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INTERRUPT
;保护现场作用,根据实际情况进行保存,中断内部和外部都使用的资源需要保
护,常规需要保护的内容有PSW PCH R0 R1
SWAPR R1 ,PSW
MOVPSW_TEMP, R1
MOVR1 , PCH
MOVPCH_TEMP, R1
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
;中断处理
;...
;...
;...
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
;恢复现场作用
INT_END
MOVR1 , PCH_TEMP
MOVPCH, R1
SWAPR R1 , PSW_TEMP
MOV PSW, R1
IRET
;;;;;;;;;;;;;;中断部分结
束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;入口函数,主程
序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAIN
CALL INIT_ALL ;初始化寄存器
CALL INIT_RAM ;初始化RAM
LOOP
INC UNIT ;个位数字的递增
MOV R0 ,UNIT
XOR R0 ,#0X0A
JB PSW ,Z
JMP C_DIS
CLR UNIT
INC DECADE ;十位数字的递增
MOV R0 ,DECADE
XOR R0 ,#0X0A
JB PSW ,Z
JMP C_DIS
CLR DECADE
INC HUNDRED ;百位数字的递增
MOV R0 ,HUNDRED
XOR R0 ,#0X0A
JB PSW ,Z
JMP C_DIS
CLR HUNDRED
INC THOUSAND ;千位数字的递增
MOV R0 ,THOUSAND
XOR R0 ,#0X0A
JB PSW ,Z
JMP C_DIS
CLR THOUSAND
C_DIS
MOV R0,#0x33
MOV DIS_DEL,R0 ;DIS_DEL是用来延时数值的递增用的,数值越
大,那么递增的速度就越慢
CALL LED_DISPLAY ;数码管显示当前数值
DECJZ DIS_DEL
JMP $‐2 ;调整地址以当前地址减2的位置
JMP LOOP
CRET
;*************************************************************
*****************
;* 函 数 名: INIT_ALL
;* 函数功能: 初始化函数,对各种寄存器的初始化
;* 入口参数: 无
;* 返 回: 无
;************************************************************* INIT_ALL
;调入校准信息到控制寄存器
CALL #0xFFF
MOV OSCCAL0, R0 ;晶振校准0
NOP
NOP
CALL #0xFFE
MOV OSCCAL1, R0 ;晶振校准1
NOP
NOP
;选择工作频率
MOV R0 ,#0x60
MOV OSCCTL, R0 ;设置为8M
;端口初始化
;***端口初始化********
MOV R0 ,#0x08
MOV TR0, R0 ;设置P0端口为输入
MOV R0 ,#0x00
MOV TR1, R0 ;设置P1端口为输出
MOV R0 ,#0X00
MOV TR2, R0 ;设置P2端口为输出
CLR P0
CLR P1
MOV R0 ,#0XF0 ;关闭数码管位选端
MOV P2, R0
CRET
;*************************************************************
*****************
;* 函 数 名: LED_DISPLAY
;* 函数功能: 数码管显示函数,由4个8位LED灯显示
;* 入口参数: THOUSAND 千位 ,HUNDRED 百位 ,SMQ_S 十位, UNIT 个位,
每个数的范围 0~f
;* 返 回: 无
;*************************************************************
***************** LED_DISPLAY
MOV R0 , #0XE0
MOV P2 , R0 ;打开数码管的 个位
MOV R2 , UNIT
CALL DIG_DATA
MOV P1 , R0
CALL DELAY
CLR P1 ;消隐
MOV R0 ,#0XF0
MOV P2 , R0
MOV R0 ,#0XD0
MOV P2 , R0 ;打开数码管的 十位
MOV R2 , DECADE
CALL DIG_DATA
MOV P1 , R0
CALL DELAY
CLR P1 ;消隐
MOV R0 ,#0XF0
MOV P2 , R0
MOV R0 , #0XB0
MOV P2 , R0 ;打开数码管的 百位
MOV R2 , HUNDRED
CALL DIG_DATA
MOV P1 , R0
CALL DELAY
CLR P1 ;消隐
MOV R0 ,#0XF0
MOV P2 , R0
MOV R0 , #0X70
MOV P2 , R0 ;打开数码管的 千位
MOV R2 , THOUSAND
CALL DIG_DATA
MOV P1 , R0
CALL DELAY
CLR P1 ;消隐
MOV R0 ,#0XF0
MOV P2 , R0
CRET
;*************************************************************
*****************
;* 函 数 名: DELAY
;* 函数功能: 延时函数,时间为1ms
;* 入口参数: 无
;* 返 回: 无
;*************************************************************
*****************
DELAY
MOV R0,#0x12
MOV DELAY_NUM1, R0
LP0
MOV R0,#0X12
MOV DELAY_NUM2, R0
LP1
DECJZ DELAY_NUM2 ;DELAY_NUM2自减1,若为0,则跳过
JMP LP1
DECJZ DELAY_NUM1 ;DELAY_NUM1自减1,若为0,则跳过
JMP LP0
CRET ;子程序返回
;/************************************************************
******************
;* 函 数 名: init_RAM
;* 函数功能: 初始化RAM
;* 入口参数: 无
;* 返 回: 无
;*************************************************************
*****************/ INIT_RAM
CLR R2 ;传递默认RAM值
; CLR RAM SET 0BANK0
CLR PSW ,RP0
MOV R0 ,#0X80 ;起始地址0x80
MOV R1 ,#0X20 ;操作个数
CALL INIT_RAM_0
; CLR RAM SET 0BANK1
SET PSW ,RP0
MOV R0 ,#0X80 ;起始地址0x80
MOV R1 ,#0X01 ;操作个数
CALL INIT_RAM_0
; 默认工作区域设定 BANK0
CLR PSW ,RP0
; 其他变量的数值操作
CRET
;;;;;;;;;;;;;;;;;;执行默认数值装载到RAM区
INIT_RAM_0
ST ,R2
INC R0
DECJZ R1
JMPINIT_RAM_0
CRET
.end 写得好详细 顶一个 这个是不是跟隔壁的帖子重复了
页:
[1]