////
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz
#include "reg51.h"
#include "intrins.h"
#define FOSC18432000L
#define BAUD9600
typedef unsigned char BYTE
typedef unsigned int WORD
#define URMD0 //0:使用定时器2作为波特率发生器
//1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器
//2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器
sfr T2H = 0xd6 //定时器2高8位
sfr T2L = 0xd7 //定时器2低8位
sfr AUXR = 0x8e //辅助寄存器
sfr ADC_CONTR = 0xBC //ADC控制寄存器
sfr ADC_RES = 0xBD //ADC高8位结果
sfr ADC_LOW2= 0xBE //ADC低2位结果
sfr P1ASF = 0x9D //P1口第2功能控制寄存器
#define ADC_POWER 0x80//ADC电源控制位
#define ADC_FLAG0x10//ADC完成标志
#define ADC_START 0x08//ADC起始控制位
#define ADC_SPEEDLL 0x00//540个时钟
#define ADC_SPEEDL 0x20//360个时钟
#define ADC_SPEEDH 0x40//180个时钟
#define ADC_SPEEDHH 0x60//90个时钟
void InitUart()
void InitADC()
void SendData(BYTE dat)
BYTE GetADCResult(BYTE ch)
void Delay(WORD n)
void ShowResult(BYTE ch)
void main()
{
InitUart()//初始化串口
InitADC() //初始化ADC
while (1)
{
ShowResult(0) //显示通道0
ShowResult(1) //显示通道1
ShowResult(2) //显示通道2
ShowResult(3) //显示通道3
ShowResult(4) //显示通道4
ShowResult(5) //显示通道5
ShowResult(6) //显示通道6
ShowResult(7) //显示通道7
}
}
/*----------------------------
发送ADC结果到PC
----------------------------*/
void ShowResult(BYTE ch)
{
SendData(ch) //显示通道号
SendData(GetADCResult(ch))//显示ADC高8位结果
//SendData(ADC_LOW2) //显示低2位结果
}
/*----------------------------
读取ADC结果
----------------------------*/
BYTE GetADCResult(BYTE ch)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START
_nop_() //等待4个NOP
_nop_()
_nop_()
_nop_()
while (!(ADC_CONTR &ADC_FLAG))//等待ADC转换完成
ADC_CONTR &= ~ADC_FLAG//Close ADC
return ADC_RES//返回ADC结果
}
/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
SCON = 0x5a //设置串口为8位可变波特率
#if URMD == 0
T2L = 0xd8//设置波特率重装值
T2H = 0xff//115200 bps(65536-18432000/4/115200)
AUXR = 0x14 //T2为1T模式, 并启动定时器2
AUXR |= 0x01 //选择定时器2为串口1的波特率发生器
#elif URMD == 1
AUXR = 0x40 //定时器1为1T模式
TMOD = 0x00 //定时器1为模式0(16位自动重载)
TL1 = 0xd8//设置波特率重装值
TH1 = 0xff//115200 bps(65536-18432000/4/115200)
TR1 = 1 //定时器1开始启动
#else
TMOD = 0x20 //设置定时器1为8位自动重装载模式
AUXR = 0x40 //定时器1为1T模式
TH1 = TL1 = 0xfb //115200 bps(256 - 18432000/32/115200)
TR1 = 1
#endif
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P1ASF = 0xff //设置P1口为AD口
ADC_RES = 0 //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL
Delay(2) //ADC上电并延时
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
while (!TI) //等待前一个数据发送完成
TI = 0//清除发送标志
SBUF = dat//发送当前数据
}
/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
WORD x
while (n--)
{
x = 5000
while (x--)
}
}
正好做过,就给你吧!*************************************
* *
* 主程序和中断程序入口 *
* *
*************************************
ORG 0000H
LJMPSTART
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
DJNZR2,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(最大5.00v)
MOV R2,#0FFH 每路显示时间控制 4MS*255
DISLOOP2: LCALL DISP 调四位显示程序
LCALL KEYWORK1
DJNZR2,DISLOOP2
INC R0显示下一路
INC 77H 通道显示数加一
DJNZR3,DISLOOP1
RET
DISP11: MOV A,77H
SUBBA,#01H
MOV 77H,A
ADD A,#70H
MOV R0,A
DISLOOP11: LCALL TUNBCD显示数据转为三位BCD码存入7AH、79H、78H(最大5.00v)
MOV R2,#0FFH 每路显示时间控制 4MS*25
DISLOOP22: LCALL DISP 调四位显示程序
LCALL KEYWORK2
DJNZR2,DISLOOP22
INC 77H 通道显示数加一
RET
*************************************
* 显示数据转为三位BCD码程序 *
*************************************
显示数据转为三位BCD码存入76H、75H、74H(最大值5.00v)
TUNBCD: MOV A,@R0 255/51=5.00V运算
MOV B,#51
DIV AB
MOV 76H,A 个位数放入76H
MOV A,B 余数大于19H,F0为1,乘法溢出,结果加5
CLR F0
SUBBA,#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
SUBBA,#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输出,列扫描在P3.0-P3.3
PLAY: MOV P1,#0FFH
MOV A,R5
ANL P3,A
MOVA,@R1
MOVDPTR,#TAB
MOVC A,@A+DPTR
MOVP1,A
JB P3.2,PLAY1 小数点处理
CLRP1.7 小数点显示(显示格式为XX.XX)
PLAY1: LCALL DL1MS
INCR1
MOVA,P3
JNBACC.3,ENDOUT
RL A
MOVR5,A
MOVP3,#0FFH
AJMP PLAY
ENDOUT: MOVP3,#0FFH
MOVP1,#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: DJNZR4,LOOP11
MOV R4,#0FFH
LOOP22: DJNZR4,LOOP22
RET
*************************************
*? 电压测量(A/D)子程序 *
*************************************
一次测量数据4个,依次放入70H-73H单元中
TEST: CLR A 模数转换子程序
MOV P2,A
MOV R0,#70H转换值存放首址
MOV R7,#04H转换4次控制
LCALL TESTART 启动测试
WAIT: JB P3.7,MOVD 等A/D转换结束信号
AJMP WAIT
TESTART:SETBP2.3 测试启动
NOP
NOP
CLR P2.3
SETBP2.4
NOP
NOP
CLR P2.4
NOP
NOP
NOP
NOP
RET
MOVD: SETBP2.5 取A/D转换数据
MOV A,P0
MOV @R0,A
CLR P2.5
INC R0
MOV A,P2 通道地址加1
INC A
MOV P2,A
CJNEA,#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
LJMPWAIT
*************************************
*? 按键检测子程序 *
*************************************
KEYWORK1: JNB P3.5,KEY1
KEYOUT: RET
KEY1: LCALL DISP 延时消抖
JB P3.5,KEYOUT
WAIT11: JNB P3.5,WAIT12
CPL 00H
MOV R2,#01H
MOV R3,#01H
RET
WAIT12: LCALL DISP 键释放等待时显示用
AJMPWAIT11
KEYWORK2: JNB P3.5,KEY1
JNB P3.6,KEY2
RET
KEY2: LCALL DISP 延时消抖用
JB P3.6,KEYOUT
WAIT22: JNB P3.6,WAIT21
INC 77H
MOV A,77H
CJNEA,#04H,KEYOUT11
KEYOUT11: JC KEYOUT1
MOV 77H,#00H
KEYOUT1:RET
WAIT21: LCALL DISP 键释放等待时显示用
AJMPWAIT22
END
附录3:
单片机C源程序清单
/*********************************************************************/
//四路电压表C程序
//使用keil C51 ver7.09
/*********************************************************************/
/*使用AT89C52单片机,12MHZ晶振,P0口读入AD值,P2口作AD控制,用共阳LED数码管
P1口输出段码,P3口扫描,最高位指示通道(0-7)。*/
#include "reg52.h"//52系列单片机定义文件
#include "intrins.h" //调用_nop_()延时函数用
#define ad_con P2 //AD控制口
#define addata P0 //AD数据计入读入口
#define DisdataP1//显示数据段码输出口
#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=0i<ti++)
for(j=0j<120j++)
}
//
//
/***********显示扫描子函数**********/
scan()
{
uchar k,n
int h
dis[3]=0x00//通道初值为0
for(n=0n<4n++) //每次显示4个数据
{
dis[2]=ad_data[n]/51 //测得值转换为三位BCD码,最大为5.00V
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=0h<500h++) //每个通道值显示时间控制(约1秒)
{
for(k=0k<4k++) //四位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=0m<4m++)
{
ALE=1_nop_()_nop_()ALE=0//转换通道地址锁存
START=1_nop_()_nop_()START=0//开始转换命令
_nop_()_nop_()_nop_()_nop_()//延时4微秒
while(EOC==0) //等待转换结束
OE=1ad_data[m]=addataOE=0s++ad_con=s//取AD值,地址加1
}
ad_con=0x00 //控制复位
}
//
//
/**************主函数****************/
main()
{
P0=0xff //初始化端口
P2=0x00
P1=0xff
P3=0xff
while(1)
{
scan() //依次显示4个通道值一次
test() //测量转换一次
}
}
//
//
//*********************结束**************************//
#include<stc89.h>#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0x00}
uchar led[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0x00,0xFF}
sbit adrd=P3^7
sbit adwr=P3^6
sbit dula=P2^6
sbit wela=P2^7
uchar date1=0
uchar date2=50
uchar date3=100
uchar date4=150
uchar date5=200
uchar date6=255
uchar a,sz
void init()
void delay(uint z)
uchar adchushihua()
void shumaguan(uint shu)
void processing()
void main()
{
init()
while(1)
{
sz=adchushihua()
for(a=10a>0a--)
{
shumaguan(sz)
processing()
}
}
}
void init()
{
P0=0x7f
}
void delay(uint z)
{
uint x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
uchar adchushihua()
{
uchar shuzhi
adwr=1
_nop_()
adwr=0
_nop_()
adwr=1
P1=0xff
adrd=1
_nop_()
adrd=0
_nop_()
shuzhi=P1
adrd=1
return shuzhi
}
void shumaguan(uint shu)
{
uchar bai,shi,ge
bai=shu/100
shi=shu%100/10
ge=shu%10
dula=1
P0=table[bai]
dula=0
P0=0xff
wela=1
P0=0x7e
wela=0
delay(5)
dula=1
P0=table[shi]
dula=0
P0=0xff
wela=1
P0=0x7d
wela=0
delay(5)
dula=1
P0=table[ge]
dula=0
P0=0xff
wela=1
P0=0x7b
wela=0
delay(5)
}
void processing()
{
if((sz>=date1)&&(sz<=date2))
{
P1=0xfe
}
else if((sz>=date2)&&(sz<=date3))
{
P1=0xfd
}
else if((sz>=date3)&&(sz<=date4))
{
P1=0xfb
}
else if((sz>=date4)&&(sz<=date5))
{
P1=0xf7
}
else if((sz>=date5)&&(sz<date6))
{
P1=0xef
}
else if(sz==date6)
{
P1=~P1
delay(20)
}
}
这个是我刚刚写的 根据你的需要 反正闲来无事 我写的比较笼统 需要你自己根据 自己的实际情况来判断确定 我只是利用AD简单的处理 成数码管显示的数字 你要是 转换成电压 那就把里面的变量 修改一下 我写的那个控制LED灯亮就不要动了 只是修改一下他前面定义的数字就可以 最后那个是我自己加上去的有点趣味性 希望对你有帮助
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)