求C语言的程序。关于动态双位数码管
发布网友
发布时间:2022-04-19 10:04
我来回答
共4个回答
热心网友
时间:2023-05-31 00:38
自己改下头文件,然后把温度采集的部分不要就行了
#include<reg51.h>
#include<intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define S_RST DS_RST=1
#define C_RST DS_RST=0
#define S_CLK DS_CLK=1
#define C_CLK DS_CLK=0
#define Write_Disable RW_DS1302(0x8e,0x80) //写保护
#define Write_Enable RW_DS1302(0x8e,0x00) //允许写入
sbit SET = P1^5; //设置按键
sbit ADD = P1^4; //调整加
sbit DEC = P1^6; //调整减
#define RdefineT1 TH1=0;TL1=0;TR1=0;a=0; //初始化超时检测
//#define Delay2us() _nop_();_nop_(); //延时2us,每nop 1us
//#define Delay8us() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
#define ReDetectTime 20 //设置重复检测次次数,超出次数则超时
//ds18b20命令
#define SkipROM 0xCC
#define MatchROM 0x55
#define ReadROM 0x33
#define SearchROM 0xF0
#define AlarmSearch 0xEC
#define Convert 0x44 //启动温度转换
#define WriteScr 0x4E
#define ReadScr 0xBE
#define CopyScr 0x48
#define RecallEE 0xB8
#define ReadPower 0xB4
#define md collect_time[0]&0x0f
#define mg (collect_time[0]&0x70)/16
#define fd collect_time[1]&0x0f
#define fg (collect_time[1]&0x70)/16
#define sd collect_time[2]&0x0f
#define sg (collect_time[2]&0x30)/16
sbit DS_RST = P1^2; //DS复位端
sbit DS_CLK = P1^0; //SCLK端
sbit DS_IO = P1^1; //IO端
sbit DS18B20 = P1^3; //温度传感器接口
bit keyboard,flash,STA=1;
uchar choose,a;
uchar collect_time[3]=;//定义变量秒分时
uchar collect_temperature[2] = ;
uchar num[10] = ;
//七段数码管显示的段码
uchar display[8] = ;
void delay(uint i)
{
uint k;
while(i--)
{
for(k=0;k<120;k++)
}
}
void Dat_Int(void)//数据初始化
{
P0=0xff;
P1=0xff;
P2=0xff;
choose=0;
flash=1;
}
void Time01_Int(void)
{
TMOD = 0x12; //定时器0为8位自动重载定时采样,定时器1为16位超时检测处理
TCON = 0x00;
TH0 = 0x60;
TL0 = 0x60;
TR0 = 1;
IE = 0x0a; //允许定时器0、1中断
IP = 0x00;
}
/********************************************************
* *
* DS18B20温度传感器程序段 *
* *
********************************************************/
/***********11微秒延时函数**********/
//
void delayus(uint t)
{
for(;t>0;t--);
}
/***********18B20复位函数**********/
void ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DS18B20 = 1;_nop_();_nop_();
DS18B20 = 0;
delayus(50); // 550us
DS18B20 = 1;
delayus(6); // 66us
presence=DS18B20; // presence=0继续下一步
}
delayus(45); //延时500us
presence = ~DS18B20;
}
DS18B20 = 1;
}
/**********18B20写命令函数*********/
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
{
uchar i;
for (i=8; i>0; i--) //
{
DS18B20 = 1;_nop_();_nop_();
DS18B20 = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DS18B20 = val&0x01; //最低位移出
delayus(6); //66us
val=val/2; //右移一位
}
DS18B20 = 1;
delayus(1);
}
//
/*********18B20读1个字节函数********/
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
DS18B20 = 1;_nop_();_nop_();
value>>=1;
DS18B20 = 0; //
_nop_();_nop_();_nop_();_nop_(); //4us
DS18B20 = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DS18B20)value|=0x80;
delayus(6); //66us
}
DS18B20 = 1;
return(value);
}
//
/***********读出温度函数**********/
//
void Ds18b20_ReadEE(void)
{
ow_reset();
write_byte(SkipROM); // Skip ROM
write_byte(Convert); // 发转换命令
ow_reset(); //总线复位
write_byte(SkipROM); // 发Skip ROM命令
write_byte(ReadScr); // 发读命令
collect_temperature[0]=read_byte(); //温度低8位
collect_temperature[1]=read_byte(); //温度高8位
}
/********************************************************
* *
* DS1302时钟芯片程序段 *
* *
********************************************************/
void DS1302_InputByte(uchar byte) //往DS1302写入1Byte数据
{
uchar i;
uchar temp;
temp = byte;
for(i=8; i>0; i--)
{
DS_IO = temp&0x01;
S_CLK;
C_CLK;
temp = temp >> 1;
}
}
uchar DS1302_OutputByte(void) //从DS1302读取1Byte数据
{
uchar i;
uchar temp=0;
for(i=0; i<8;i++)
{
C_CLK;
if(DS_IO!=0) temp|=(1<<i);
S_CLK;
}
return(temp);
}
void RW_DS1302(uchar reg, uchar byte)//向DS1302寄存器写数据
{
C_RST;
C_CLK;
S_RST;
DS1302_InputByte(reg);
DS1302_InputByte(byte);
S_CLK;
C_RST;
}
uchar Read_DS1302(uchar reg)//从DS1302寄存器读数据
{
uchar byte;
C_RST;
C_CLK;
S_RST;
DS1302_InputByte(reg);
byte = DS1302_OutputByte();
S_CLK;
C_RST;
return(byte);
}
void GetTime_DS1302(uchar *ucCurtime) //读取DS1302当前时间
{
ucCurtime[0] = Read_DS1302(0x81);//格式为: 秒 分 时
ucCurtime[1] = Read_DS1302(0x83);
ucCurtime[2] = Read_DS1302(0x85);
}
void Set_Time(uchar *receive) //写时间
{
Write_Enable; //控制命令,允许写操作
RW_DS1302(0x80,receive[0]);
RW_DS1302(0x82,receive[1]);
RW_DS1302(0x84,receive[2]);
Write_Disable; // 控制命令,写保护
}
/********************************************************
* *
* 数码管显示程序段 *
* *
********************************************************/
void deal(void)//送显前的数据处理
{uint timer2;
uint lstemp;
timer2++;
if(STA)
if(flash)//用于闪动效果的控制的
{
display[0] = num[sg];
display[1] = num[sd];
display[2] = num[fg];
display[3] = num[fd];
display[4] = num[mg];
display[5] = num[md];
}
else
{switch(choose)
{
case 1:display[0]=0;break;
case 2:display[1]=0;break;
case 3:display[2]=0;break;
case 4:display[3]=0;break;
case 5:display[4]=0;break;
case 6:display[5]=0;break;
}
}
if(timer2==3000)//间断性获取温度
{
timer2=0;
if(STA)
{TR0=0;
Ds18b20_ReadEE();
TR0=1;
}
}
if(collect_temperature[1]>127)
{
collect_temperature[0]=255-collect_temperature[0];
collect_temperature[1]=255-collect_temperature[1];
}
lstemp=((collect_temperature[0])>>4)|((collect_temperature[1])<<4);
display[6] = num[(uchar)((lstemp)/10)];
display[7] = num[(uchar)((lstemp)%10)];
}
/********************************************************
* *
* 按键控制程序段 *
* *
********************************************************/
void Scan(void)
{
if(SET==0&&keyboard==1) //检测设置键有无按下,并进行相应操作
{
if(SET==0&&keyboard==1)
{ RdefineT1; //超时检测初始化
choose++;
while(SET==0);
if(choose==7)
{TR0=0;
Set_Time(collect_time);
TR0=1;
STA=1; //设置完毕,重新开始采集时间
choose=0;
}
}
}
if(choose) //只有在时间调整时,加减按键才有作用
{
if(ADD==0&&keyboard==1) //检测加调整键有无按下,并进行相应操作
{
if(ADD==0&&keyboard==1)
{ RdefineT1; //超时检测初始化a=0
TR0=0;
switch (choose)
{
case 1 :if(sg==2)
collect_time[2] = collect_time[2]&0x0f;
else
break;
case 2 :if((sg<2)&&(sd==9))
collect_time[2] &= 0x30;
if((sg>=2)&&(sd==3))
collect_time[2] &= 0x30;
else
break;
case 3: if(fg==5)
collect_time[1] &= 0x0f;
else
break;
case 4: if(fd==9)
collect_time[1] &= 0xf0;
else
break;
case 5: if(mg==5)
collect_time[0] &= 0x0f;
else
break;
case 6: if(md==9)
collect_time[0] &= 0xf0;
else
break;
}
TR0=1;
while(ADD==0);
}
}
if(DEC==0&&keyboard==1) //检测减调整键有无按下,并进行相应操作
{
if(DEC==0&&keyboard==1)
{ RdefineT1; //超时检测初始化
TR0=0;
switch (choose)
{
case 1 :if(sg==0)
collect_time[2]=0x20;
else collect_time[2]-=16;
break;
case 2 :if(sg<2&&sd==0)
collect_time[2] |= 0x09;
if(sg==2&&sd==0)
collect_time[2] |= 0x03;
else collect_time[2]-=1;
break;
case 3 :if(fg==0)
collect_time[1] |= 0x50;
else collect_time[1]-=16;
break;
case 4 :if(fd==0)
collect_time[1] |= 0x09;
else collect_time[1]-=1;
break;
case 5 :if(mg==0)
collect_time[0] |= 0x50;
else collect_time[0]-=16;
break;
case 6 :if(md==0)
collect_time[0] |= 0x09;
else collect_time[0]-=1;
break;
}
TR0=1;
while(DEC==0);
}
}
}
if(choose!=0) //在设置模式下停止采集时间
else
}
/********************************************************
* *
* AT89S51主程序段 *
* *
********************************************************/
void main(void)
{
Time01_Int();
Dat_Int();
EA = 1; //开中断
ow_reset(); // 开机先转换一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
delay(100);
Set_Time(collect_time);
delay(10);
while(1)
{
Scan();
deal();
}//while循环的结束
}//main函数的结束
void Time0_seve() interrupt 1 //定时器0中断服务程序
{
uint timer;
uchar i,ktemp;
if((P1&0x70)<0x70) //防抖控制用
keyboard=1;
else keyboard=0;
timer++;
if(timer==800)//控制数码管的闪动效果
{
if(choose !=0)
flash=~flash;
else flash = 1;
timer=0;
}
TR0=0;
ktemp=P0;
if(P0==0xfe)i=1;
else if(P0==0xfd)i=2;
else if(P0==0xfb)i=3;
else if(P0==0xf7)i=4;
else if(P0==0xef)i=5;
else if(P0==0xdf)i=6;
else if(P0==0xbf)i=7;
else if(P0==0x7f)i=0;
else i=1;
ktemp=ktemp*2+1;
if(ktemp==0xff)ktemp=0xfe;
P0=ktemp;
P2=display[i];
TR0=1;
}
void Time1_seve() interrupt 3 //定时器1中断服务程序
{
TR1=0;TH1=0;TL1=0;
a++;
if(a>4*ReDetectTime)
{
choose=0;
a=0;
Set_Time(collect_time);
STA=1; //超过按键等待时间,自动写入并开始采集时间
}
}
热心网友
时间:2023-05-31 00:39
/*
这个程序我编了一个上午,希望能对你有用。
运行时按下INT0开始计时,再按下INT1得到速度
由于我只有公阳极数码管,(因为要调试)P2为片选端因为我加了三极管,所以也是低电平有效,你是共阴极,片选端可以直接连P2上,
你自己把数字取反再调试看看
速度的单位是厘米每秒,定义的L是1米,由于用浮点数表示速度在显示部分会麻烦一点,所以就偷了下懒用的整数表示的,由于最终速度
显示到数码管上要加一个小数点,所以实际上程序中的V是以毫米每秒为单位,显示到数码管上缩小了10倍
*/
#include <reg52.h>
code unsigned char tab[]=
;
//共阳数码管 0-9 共阴极你要取反
unsigned char Dis_Baiwei=0xc0;//定义百位
unsigned char Dis_Shiwei=0xc0;//定义十位
unsigned char Dis_Gewei=0xc0; //定义个位
unsigned char Dis_ShiFwei=0xc0; //定义十分位
unsigned char second,msecond;
unsigned long L=100000; //1米,以0.01mm为单位
unsigned int v; //速度
unsigned int t; //时间以0.01秒为单位
void CLR(void);
void delay(unsigned int cnt)
{
while(--cnt);
}
main()
{
EX0=1;//外部中断0设置
IT0=1;//边沿触发
EX1=1;//外部中断1设置
IT1=1;
TMOD |=0x01;//定时器设置 10ms in 12M crystal
TH0=0xd8;
TL0=0xf0;
ET0=1; //打开中断
TR0=0;
EA=1;
second=0;
msecond=0;
while(1)
{
P0=Dis_Baiwei;//显示第一位
P2=0xf7;
delay(300);//短暂延时
P0=Dis_Shiwei; //显示第二位
P2=0xfb;
delay(300);
P0=Dis_Gewei;//显示第三位
P2=0xfd;
delay(300);//短暂延时
P0=Dis_ShiFwei; //显示第四位
P2=0xfe;
delay(300);
}
}
/********************************/
/* 定时中断 */
/********************************/
void tim(void) interrupt 1 using 1
{
TH0=0xd8;//重新赋值
TL0=0xf0;
msecond++;
if (msecond==100)
{
msecond=0;
second++;//秒加1
if(second==200)
second=0;
}
Dis_Baiwei=tab[second/10];//十位显示值处理
Dis_Shiwei=tab[second%10]&0x7f; //个位显示处理,如果是共阴极就是0X80
Dis_Gewei=tab[msecond/10];//十位显示值处理
Dis_ShiFwei=tab[msecond%10]; //个位显示处理
}
void ISR_INT0(void) interrupt 0 using 1
{
TH0=0xd8;//重新赋值
TL0=0xf0;
second=0; //利用外部中断清零
msecond=0;
Dis_Baiwei=0xc0;
Dis_Shiwei=0xc0;
Dis_Gewei=0xc0;
Dis_ShiFwei=0xc0;
TR0=1;
}
void ISR_INT1(void) interrupt 2 using 1
{
TR0=0; //利用外部中断关闭定时器0
t=second*100+msecond;//0.01秒为单位
if(t>10) //最大速度为999.9
v=L/t;
else
v=9999;
Dis_Baiwei=tab[(v/1000)];//百位显示值处理
Dis_Shiwei=tab[((v%1000)/100)];//十位显示值处理
Dis_Gewei=tab[((v%100)/10)]&0x7f; //个位及小数点显示处理如果是共阴极就是0X80
Dis_ShiFwei=tab[(v%10)];//十分位显示值处理
}
热心网友
时间:2023-05-31 00:39
#include<reg52.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
#include "absacc.h"
#define uchar unsigned char
//#define uchar unsigned int
sbit POR=P3^6;
sbit CS=P3^2;
sbit INTR=P3^3;
sbit RED=P3^7;
sbit fengming=P2^0;
volatile unsigned char Value_ADC0804;
volatile double Disp_Data;
volatile double Disp;
//数码管定义
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x6f,0x90};
uchar code DSY_IDX[]={0xdf,0xbf,0x7f};
//待显示各温度数位
uchar Temperature[]={0,0,0};
/*****************************************************
函数功能:延时1ms
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delay(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
delay1ms();
}
//显示函数
/*void Show_Temperature()
{
uchar i, DSY_IDX[]={0x01,0x02,0x04};
for (i=0;i<3;i++)
{
P0 = DSY_IDX[i];
P2 = DSY_CODE[Temperature[i]];
delay(2);
P0 = 0xf0;
// delay(5);
}
} */
void main(void) //主函数
{
uchar temp,i;
while(1)
{
RED=1;
POR=1;
INTR=1;
POR=0;
CS=0;
POR=1;
while(INTR==1);
RED=0;
Value_ADC0804=P1; //读取数据
RED=1;
CS=1;
Disp_Data=(double)((Value_ADC0804*5.07)/255);
temp=(Disp_Data/5.7)*100;
Temperature[0]=temp/100; //百位
Temperature[1]=temp%100/10; //十位
Temperature[2]=temp%10; //个位
//delay(5);
// Show_Temperature();
for(i=0;i<3;i++)
{
P2=DSY_IDX[i];
P0=~DSY_CODE[Temperature[i]];
//P0=0x3f;
delay(3);
P2=0xff;
delay(5);
}
//P0=0Xff;
// P2 = 0;
// P0 = 0xf6;
// }
if(temp>24)
{
fengming=1; delay(100);
fengming=0; delay(100);
fengming=1; delay(100);
}
}
}
热心网友
时间:2023-05-31 00:40
方法方法方法方法方法方法发
用C语言编程 怎么用单片机使2位数码管动态显示00---99? P1口接1个二...
include<stdlib.h> unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98};unsigned char buffer[6];bit flag;unsigned int n;unsigned char j =0;void delay(int ms){ int i;while(ms--)for(i=0;i<200;i++);} handle(unsigned int n){ unsigned ...
OA系统是什么意思?
OA系统(Office Automation,简称OA)是将计算机、通信等现代化技术运用到传统办公方式,进而形成的一种新型办公方式。办公自动化利用现代化设备和信息化技术,代替办公人员传统的部分手动或重复性业务活动,优质而高效地处理办公事务和业务信息...
求用单片机驱动数码二级管的C语言程序,要求二级管显示00~99_百度知 ...
两位数码管显示00~99,无需采用数码管扫描,通常采用静态显示。给你提供一个两位数码管00~99循环加法计数的CC语言程序。程序中,采用了软件延时的方法,每半秒自动加1。include<reg52.h> unsigned char count=0;unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0...
求51单片机控制2个数码管的程序
两只数码管段码分别由P0,P2输出控制,P0是十位,P2是个位。P3.2,P3.4分别接两只按键,P32.清0,P3.4计数。以上程序来自《单片机C语言程序设计实训100例——基于8051+Proteus仿真》include <reg52.h> define uchar unsigned char define uint unsigned int uchar DSY_CODE[]= { 0x3f,0x06,0x...
怎么在数码管里面显示双字节十六进制数,比如0xAC5D,用C语言编写
输出数据(a & 0x00F0);延时一段时间;3.选通第3个数码管;输出数据(a & 0x0F00);延时一段时间;4.选通第4个数码管;输出数据(a & 0xF000);延时一段时间;然后再从第1步开始,如此循环。其中输出数据的时候,还要注意转换成数码管的七段码。
求C51 的两个数码管显示0~99的C语言程序,越简单越好。希望是有for循环...
看这个例子,两个数码管,从0到99,时间0.1S include <reg52.h> define uchar unsigned char define uint unsigned int sbit K1 = P3^7;uchar i,Second_Counts,Key_Flag_Idx;bit Key_State;uchar DSY_CODE[]= { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };void DelayMS...
求两个按键控制数码管数字加减C语言程序
void main (void){ unsigned char num=0;KEY_ADD=1; //按键输入端口电平置高 KEY_DEC=1;while (1) //主循环 { if(!KEY_ADD) //如果检测到低电平,说明按键按下 { DelayMs(10); //延时去抖,一般10-20ms if(!KEY_ADD) //再次确认按键是否按下,没有按下则退出 { while(!
数码管俩位显示0到99加中断程序
这本质是数码管的动态显示,所谓的动态显示是指数码管一位一位的轮流显示.每次只让一个数码管亮,还有就是要能分清楚共阴极与共阳极的区别.include<reg52.h> define uint unsigned int define uchar unsigned char//宏定义 uchar code table[]= { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x...
帮忙编个51单片机两个数码管的C语言编程(第一个显示4,第二个显示6...
delays(10); while(1) { shi=1; //关闭十位显示 ge=0; //打开个位显示 P0=0xa4; //让个位显示3 delays(5); P0=0xff; //显示清0 ge=1; //关闭个位显示 shi=0; //打开十位显示 P0=0xf9; //让十位显示2 delays(5); P0=0xff; //显示清0; }} ...
两位一体数码管0到99的c语言编程
;wei1=1;wei2=0;P2=Data[0];Delay(5000);} } } void Delay(unsigned int t){ while(--t);} 用的共阴极数码管,p2口接数码管数据输入端,p3.0和p3.1接使能端 我用proteus仿真了一下,个位总是闪,很是郁闷,不知是何原因,但你可以参考一下,找到原因了可以告诉我一声,谢谢!
利用单片机实现两位数码管显示功能。
DATEQU 30H SCANLEDEQU 32H FSDATEQU 33H ORG 0000H LJMP MAIN ORG 000BH LJMP T0ISR ORG 0030H MAIN:MOV SP,#5FH MOV TMOD,#01H MOV TH0,#0F4H MOV TL0,#048H MOV P2,#00H MOV SCANLED,#0 MOV 30H,#5 MOV 31H,#0 MOV FSDAT,#50 SETB EA SETB ET0 SETB TR0 LOOP:JB ...