单片机 c语言编程 关于循环,实时显示的问题

单片机 c语言编程 关于循环,实时显示的问题,第1张

你上网查一下基于“时间触发”的编程思想,这样你就不会受多任务的影响了

给你了流程你看看吧

while(1)

{

if(ad转换时间到){开启ad转换};

if(数码显示时间到){显示子程序};

}

时间基可以用定时器中断,最小时间基任务中有最小的时间间隔确定

中断:

ad时间++;

数码显示时间++;

return;

还有一个编程思想就是ad转换的结果要建立一个缓冲区(说白了就是个数组或变量),每次ad转换完成后就可以给他赋值,显示时也是显示他的内容

至于你说的“只能在AD转换 循环结束后”那是肯定的,即使最好的单片机也是一条一条指令的执行,所以尽量不要在程序中出现delay的程序,相当于cpu在浪费时间

正好做过,就给你吧!

;

; 主程序和中断程序入口

;

;

ORG 0000H

LJMP START

ORG 0003H

RETI

ORG 000BH

RETI

ORG 0013H

RETI

ORG 001BH

RETI

ORG 0023H

RETI

ORG 002BH

RETI

;

;

;

; 初始化程序中的各变量

;

;

CLEARMEMIO: CLR A

MOV P2,A

MOV R0,#70H

MOV R2,#0DH

LOOPMEM: MOV @R0,A

INC R0

DJNZ R2,LOOPMEM

MOV 20H,#00H

MOV A,#0FFH

MOV P0,A

MOV P1,A

MOV P3,A

RET

;

;

;

; 主 程 序

;

;

START: LCALL CLEARMEMIO ;初始化

MAIN: LCALL TEST ;测量一次

LCALL DISPLAY ;显示数据一次

AJMP MAIN

NOP ;PC值出错处理

NOP

NOP

LJMP START

;

;

; 显 示 控 制 程 序

;

;

DISPLAY: JB 00H,DISP11 ;

MOV R3,#04H ;4路信号循环显示控制

MOV R0,#70H ;显示数据初址70H~73H

MOV 77H,#00H ;显示通道路数初值

DISLOOP1: LCALL TUNBCD ;显示数据转为三位BCD码存入76H、75H、74H(最大500v)

MOV R2,#0FFH ;每路显示时间控制 4MS255

DISLOOP2: LCALL DISP ;调四位显示程序

LCALL KEYWORK1 ;

DJNZ R2,DISLOOP2 ;

INC R0 ;显示下一路

INC 77H ;通道显示数加一

DJNZ R3,DISLOOP1

RET

;

DISP11: MOV A,77H ;

SUBB A,#01H ;

MOV 77H,A ;

ADD A,#70H ;

MOV R0,A ;

DISLOOP11: LCALL TUNBCD ;显示数据转为三位BCD码存入7AH、79H、78H(最大500v)

MOV R2,#0FFH ;每路显示时间控制 4MS25

DISLOOP22: LCALL DISP ;调四位显示程序

LCALL KEYWORK2 ;

DJNZ R2,DISLOOP22

INC 77H ;通道显示数加一

RET

;

;

; 显示数据转为三位BCD码程序

;

;显示数据转为三位BCD码存入76H、75H、74H(最大值500v)

;

TUNBCD: MOV A,@R0 ;255/51=500V运算

MOV B,#51 ;

DIV AB ;

MOV 76H,A ;个位数放入76H

MOV A,B ;余数大于19H,F0为1,乘法溢出,结果加5

CLR F0

SUBB A,#1AH

MOV F0,C

MOV A,#10 ;

MUL AB ;

MOV B,#51 ;

DIV AB

JB F0,LOOP2 ;

ADD A,#5

LOOP2: MOV 75H,A ;小数后第一位放入75H

MOV A,B

CLR F0

SUBB A,#1AH

MOV F0,C

MOV A,#10 ;

MUL AB ;

MOV B,#51 ;

DIV AB

JB F0,LOOP3 ;

ADD A,#5

LOOP3: MOV 74H,A ;小数后第二位放入74H

RET

;

;

; 显示 程 序

;

;共阳显示子程序,显示内容在74H—77H

;

DISP: MOV R1,#74H ;共阳显示子程序,显示内容在74H—77H

MOV R5,#0FEH ;数据在P1输出,列扫描在P30-P33

PLAY: MOV P1,#0FFH

MOV A,R5

ANL P3,A

MOV A,@R1

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV P1,A

JB P32,PLAY1 ;小数点处理

CLR P17 ;小数点显示(显示格式为XXXX)

PLAY1: LCALL DL1MS

INC R1

MOV A,P3

JNB ACC3,ENDOUT

RL A

MOV R5,A

MOV P3,#0FFH

AJMP PLAY

ENDOUT: MOV P3,#0FFH

MOV P1,#0FFH

RET

TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH

;

;

; 延时程序

;

;

DL10MS: MOV R6,#0D0H ;10MS延时子程序

DL1: MOV R7,#19H

DL2: DJNZ R7,DL2

DJNZ R6,DL1

RET

;

DL1MS: MOV R4,#0FFH ;513+513=1MS

LOOP11: DJNZ R4,LOOP11

MOV R4,#0FFH

LOOP22: DJNZ R4,LOOP22

RET

;

;

; 电压测量(A/D)子程序

;

; 一次测量数据4个,依次放入70H-73H单元中

;

TEST: CLR A ;模数转换子程序

MOV P2,A

MOV R0,#70H ;转换值存放首址

MOV R7,#04H ;转换4次控制

LCALL TESTART ;启动测试

WAIT: JB P37,MOVD ;等A/D转换结束信号

AJMP WAIT

;

TESTART: SETB P23 ;测试启动

NOP

NOP

CLR P23

SETB P24

NOP

NOP

CLR P24

NOP

NOP

NOP

NOP

RET

;

MOVD: SETB P25 ;取A/D转换数据

MOV A,P0

MOV @R0,A

CLR P25

INC R0

MOV A,P2 ;通道地址加1

INC A

MOV P2,A

CJNE A,#04H,TESTEND ;等8路A/D转换结束

TESTEND: JC TESTCON

CLR A ;结束恢复端口

MOV P2,A

MOV A,#0FFH

MOV P0,A

MOV P1,A

MOV P3,A

RET

;

TESTCON: LCALL TESTART

LJMP WAIT

;

;

; 按键检测子程序

;

;

KEYWORK1: JNB P35,KEY1

KEYOUT: RET

;

KEY1: LCALL DISP ;延时消抖

JB P35,KEYOUT

WAIT11: JNB P35,WAIT12

CPL 00H

MOV R2,#01H

MOV R3,#01H

RET

;

WAIT12: LCALL DISP ;键释放等待时显示用

AJMP WAIT11

;

KEYWORK2: JNB P35,KEY1

JNB P36,KEY2

RET

;

KEY2: LCALL DISP ;延时消抖用

JB P36,KEYOUT

WAIT22: JNB P36,WAIT21

INC 77H

MOV A,77H

CJNE A,#04H,KEYOUT11

KEYOUT11: JC KEYOUT1

MOV 77H,#00H

KEYOUT1: RET

;

WAIT21: LCALL DISP ;键释放等待时显示用

AJMP WAIT22

;

END

附录3:

单片机C源程序清单

//

// 四路电压表C程序

// 使用keil C51 ver709

//

/使用AT89C52单片机,12MHZ晶振,P0口读入AD值,P2口作AD控制,用共阳LED数码管

P1口输出段码,P3口扫描,最高位指示通道(0-7)。/

#include "reg52h" //52系列单片机定义文件

#include "intrinsh" //调用_nop_();延时函数用

#define ad_con P2 //AD控制口

#define addata P0 //AD数据计入读入口

#define Disdata P1 //显示数据段码输出口

#define uchar unsigned char//无符号字符(8位)

#define uint unsigned int //无符号整数(16位)

sbit ALE=P2^3; //锁存地址控制位

sbit START=P2^4; //启动一次转换位

sbit OE=P2^5; //0809输出数据控制位

sbit EOC=P3^7; //转换结束标志位

sbit DISX=Disdata^7; //LED小数点

//

//

uchar code dis_7[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};

/ 共阳七段LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" /

uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //四位列扫描控制字

uchar data ad_data[8]={0x00,0x00,0x00,0x00};//定义4个数据内存单元

uint data dis[5]={0x00,0x00,0x00,0x00,0x00}; //定义4个显示数据单元、1个数据暂存单元

//

//

/1毫秒延时子函数/

delay1ms(uint t)

{

uint i,j;

for(i=0;i<t;i++)

for(j=0;j<120;j++)

;

}

//

//

/显示扫描子函数/

scan()

{

uchar k,n;

int h;

dis[3]=0x00; //通道初值为0

for(n=0;n<4;n++) //每次显示4个数据

{

dis[2]=ad_data[n]/51; //测得值转换为三位BCD码,最大为500V

dis[4]=ad_data[n]%51; // 余数暂存

dis[4]=dis[4]10; //计算小数第一位

dis[1]=dis[4]/51; //

dis[4]=dis[4]%51; //

dis[4]=dis[4]10; //计算小数第二位

dis[0]=dis[4]/51; //

for(h=0;h<500;h++) //每个通道值显示时间控制(约1秒)

{

for(k=0;k<4;k++) //四位LED扫描控制

{

Disdata=dis_7[dis[k]];

if(k==2){DISX=0;}

P3=scan_con[k];delay1ms(1);P3=0xff;

}

}

dis[3]++; //通道值加1

}

}

//

//

/0809AD转换子函数/

test()

{

uchar m;

uchar s=0x00;

ad_con=s;

for(m=0;m<4;m++)

{

ALE=1;_nop_();_nop_();ALE=0; //转换通道地址锁存

START=1;_nop_();_nop_();START=0; //开始转换命令

_nop_();_nop_();_nop_();_nop_(); //延时4微秒

while(EOC==0); //等待转换结束

OE=1;ad_data[m]=addata;OE=0;s++;ad_con=s;//取AD值,地址加1

}

ad_con=0x00; //控制复位

}

//

//

/主函数/

main()

{

P0=0xff; //初始化端口

P2=0x00;

P1=0xff;

P3=0xff;

while(1)

{

scan(); //依次显示4个通道值一次

test(); //测量转换一次

}

}

//

//

//结束//

以上就是关于单片机 c语言编程 关于循环,实时显示的问题全部的内容,包括:单片机 c语言编程 关于循环,实时显示的问题、用汇编语言写一个51单片机adc0809的程序、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9483528.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存