单片机C语言编写共阳0~999,最好解释详细点!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机C语言编写共阳0~999,最好解释详细点!相关的知识,希望对你有一定的参考价值。

参考技术A /***数显秒表,范围0~999***/
/***源程序默认硬件环境:52单片机,12MHz晶振,3位共阳数码管,P0 口段选,P10~P12 高电平位选(NPN三极管驱动),P12为最高位数码管***/
#include"reg52.h" //包含52头文件
#define TRUE 1 //定义布尔量'1':真
#define FALSE 0 //定义布尔量'0':假
#define uchar unsigned char //定义 无符号字符型数据 简称
#define uint unsigned int //定义 无符号整型数据 简称
#define th0 0xfc
#define tl0 0x18 //1ms at 12MHz(定时器工作模式1 状态)
#define SEG_Num 3 //数码管位数
#define SEG_Data P0 //数码管段驱动接口
#define SEG_En P1 //数码管位驱动接口
#define SEG_AllOff (SEG_En&=0xf8) //关闭所有数码管(位驱动)
#define DisTimeAt1msCount 5 //单'位'数码管显示时间,数码管刷新频率f=1/(N×t),其中 N为数码管位数, t为单'位'数码管显示时间
#define T1sAt1msCount 1000 //1秒 计数值(在定时器为1ms 情况下计数)
#define TimesEnd 1000 //显示内容范围 0~999
uchar code SEG_B_List[10]=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90; //共阳数码管代码表"0-9"
uint Sec;
uchar bdata Flag=1;
sbit DisplayFlag=Flag^0; //显示标志位
sbit TimesUpFlag=Flag^1; //时间更新标志位
void Timer0() interrupt 1 //定时器0中断函数

static uchar t1ms; //定义静态变量 t1ms 定时计数寄存空间
static uint t1ms_sec;
TL0=tl0;
TH0=th0; //重赋 1ms 定时初值
t1ms=++t1ms%DisTimeAt1msCount; //先计数值加1,后对计数范围进行限制0~(DisTimeAt1msCount-1)
if(!t1ms) DisplayFlag=TRUE; //若定时计数值归0,则表示计数值曾到达 单'位'显示时间(DisTimeAt1msCount),显示标志 置位
t1ms_sec=++t1ms_sec%T1sAt1msCount; //在 T1sAt1msCount(1000) 范围内加1
if(!t1ms_sec) TimesUpFlag=TRUE; //若 归0,则1s 时间到,时间更新标志位 置位

void SystemInit() //系统初始化函数

TMOD=0x01; //关闭定时器1,开启定时器0,且工作在模式1(16位定时器)
TH0=th0;
TL0=tl0; //装定时初值(1ms at 12MHz)
TR0=1; //启动计时
ET0=1; //允许定时器0中断
EA=1; //开启系统中断功能


float Pow_Self(float x,uint y)//自编简易 x 的 y 次方函数,y只能是 非负整数

float sum;
if(x==0 && y==0) return; //0 的 0 次方无意义
else if(x==0) sum=0; //可有可无,y!=0的情况已经包含x=0,不加不影响结果,但影响运算速度
else if(y==0) sum=1; //除上述情况外,任何数的 0 次方均为 1
else if(y==1) sum=x; //任何数的 1 次方 均为 本身
else if(y>1) sum=Pow_Self(x,--y)*x; //递归调用,降幂
return sum; //返回计算结果

void TimesUpdata() //时间更新 函数

if(TimesUpFlag) //若 时间更新标志 为真

Sec=++Sec%TimesEnd; //Sec (秒)在 TimesEnd (0~999) 范围内加1
TimesUpFlag=FALSE; //清 时间更新标志位


void Display(uint dis_num) //显示函数,显示内容为 无符号整型数据 dis_num

static uchar dis_loca; //定义静态变量 显示位置
if(DisplayFlag) //若显示标志位为真(单'位'显示时间结束),则执行以下任务

DisplayFlag=FALSE; //清显示标志位
dis_loca=++dis_loca%SEG_Num; //先对 显示位置 加1,后对变量范围进行限制 0~(SEG_Num-1)
SEG_AllOff; //关闭所有数码管显示(位驱动)
SEG_Data=SEG_B_List[(dis_num/(uint)(Pow_Self(10,dis_loca)))%10]; //将显示内容(dis_num) 本次需显示的位(dis_loca)上的数值转成代码,并送到数据端口
SEG_En|=1<<dis_loca; //开启本次需要显示的位驱动


void main() //主函数

SystemInit(); //调用 系统初始化函数
while(1) //循环系统

TimesUpdata(); //调用 时间更新函数
Display(Sec); //调用 显示函数 显示内容为 Sec

参考技术B #include <reg52.h>
#define u8 unsigned char
#define u16 unsigned int

#define LED_DATA P0

u8 code LED[10]=0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 ; //0~9对应码段

sbit COM0 = P1^0;
sbit COM1 = P1^1;
sbit COM2 = P1^2;
void Display(u16 Num) //eg. Num = 123

//将每位的数值取出
u16 bai,shi,ge;
bai = Num/100; // 1
shi = Num/10%10; // 2
ge = Num%10; // 3

//第一个数码管显示qian其他数码管灭
P1 = 0x04;
P0 = LED[qian];
delay(); //时间自己调,当1,2,3快速切换,眼睛看不出他们是分别亮就行

/第二个数码管显示bai 其他数码管灭
P1 = 0x02;
P0 = LED[bai];
delay();

//第三个数码管显示ge其他数码管灭
P1 = 0x01;
P0 = LED[ge];
delay();



可能有小错误,但是主体思路正确,大概就是这个意思,主函数调用就行了Display()就行了
祝你成功,谢谢
参考技术C /********************************************************
* 显示在p0口,位控制在p1口低位对应 *
* 开机000,逐个加,到999后又 *
* 从000开始 *
*******************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code LED[10]=0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 ; //0~9对应码段
void delay(uint a) //延时

while(a)

uchar i,j;
for(i=0;i<300;i++)
for(j=0;j<300;j++)



void dis()//显示子程序

uint m;
P0=0XFF;//清屏
P0=LED[m%100%10]; //显示低位
P1=0XFE;
delay(10);
m++; //改变数值
if(m>999) //判断m是否大于999
m=0;
P0=0XFF; //清屏,消除“鬼影”
P0=LED[m/10%10]; //显示十位
P1=0XFD;
delay(10);
m++; //改变数值
if(m>999)
m=0;
P0=LED[m/100]; //显示百位
P1=0XFB;
delay(10);
m++; //改变数值
if(m>999)
m=0;

main()

dis();


主程序中就只有一个dis()显示程序,程序都是成块成块的,让我们初学者更加容易的理解和阅读,没有计算时间,如果显示过快,调整i,j数值;

51单片机 3个IO口 + TM1638+24个独立按键扫描(非自锁按键)+驱动8位共阳数码管显示+Proteus仿真

51单片机 3个IO口 + TM1638+24个独立按键扫描(非自锁按键)+驱动8位共阳数码管显示+Proteus仿真


在上一版的基础上进行优化,原来是需要物理自锁按键来显示按键值的,在代码上做了优化,实现点动物理按键即可实现自锁,其实是本质上是利用了TM1638数据锁存的特性实现的,代码上的简单处理就可以了,所以只是小小的一点改动。

主程序代码

/*******************************************************************************
3线IO口控制8位共阳数码管
共阳数码管数据转换
tab[]数组对应共阴断码表,0x3f → 0;0x40 → ‘-’;0x00  → 什么都不显示
*/

以上是关于单片机C语言编写共阳0~999,最好解释详细点!的主要内容,如果未能解决你的问题,请参考以下文章

51单片机定时器累加计数(000-999)+4位数码管(循环显示)+Proteus仿真

51单片机 3个IO口 + TM1638+24个独立按键扫描+驱动8位共阳数码管显示+Proteus仿真

51单片机 3个IO口 + TM1638+24个独立按键扫描(非自锁按键)+驱动8位共阳数码管显示+Proteus仿真

单片机控制74hc595驱动4个单数码管计数显示

C语言编写串口通信程序在裸机下运行

pid控制的C语言编程