单片机内部程序宏举可以通过算法(规律计算或数组),定时生成一个数字量发送到DAC0832,使其输出相应模拟量,即可。
例如锯齿波是从0~3V,将0~3V分为若干个点(分辨率),定时输出每个点的数字量。
D_APORT EQU 8000H 0832 口地址ORG 0000H
AJMP START
ORG 0040H
START:
MOV SP,#60H
MOV
A,#00H
MOV DPTR,#4000H 锯齿波缓冲区伏哪首址
NEXT:
MOVX @DPTR,A
填锯齿波数据
INC DPTR
INC A
JZNEXT1
写完256个数据后退出
AJMP NEXT
NEXT1:
MOV A,#00H
MOV
R0,#00H
MOV DPTR,#4100H 三角波缓冲区首址
NEXT2:
MOVX @DPTR,A
填三角波数据(上升部分)
INC DPTR
ADD A,#02H
INC R0
CJNE
R0,#80H,NEXT2
SUBB A,#02H
CLR C
NEXT3:
MOVX
@DPTR,A 填三角波数据(下升部分)
INC DPTR
SUBB A,#02H
INC
R0
CJNE R0,#00H,NEXT3写完256个数据后退出
--------------SIN
WAVE------------------
MOV R0,#10H
MOV R1,#00H
MOV
DPTR,#STEP 步长缺岩码的浮点ASCII起始地址
READ:
MOV A,R1
MOVC
A,@A+DPTR
MOV @R0,A
INC R1
INC R0
CJNE
R1,#0AH,READ 将程序区的数据移到内部RAM区
MOV R0,#10H 十进制浮点数的首址
MOV
R1,#30H 三字节浮点数的首址(步长)
LCALL %FDTB3
带符号十进制数ASCII码浮点数
转换成三字节浮点数
MOV R2,#00H
MOV R3,#80H
电压的最大值
MOV R0,#18H 三字节浮点数的首址(最大电压)
LCALL %WTF31
双字节无符号数转换成
三字节浮点数
MOV R3,#00H STEP LENGTH
MOV
DPTR,#4200H 正弦波数据枣派表首址
CALCSIN:
PUSH 3
PUSH DPH
PUSH
DPL
MOV R2,#00H
MOV R0,#38H FLOAT STEP ADDRESS
LCALL %WTF31 双字节无符号数转换成
三字节浮点数
MOV R0,#30H
MOV
R1,#38H
LCALL %FMUL3 三字节浮点数乘法子程序
MOV 40H,R4 MUL
ADDRESS
MOV 41H,R2
MOV 42H,R3
MOV R0,#40H
MOV R1,#48H SIN VALUE ADDRESS
LCALL %FSIN3
三字节浮点数正弦子程序
MOV R0,#18H
MOV R1,#48H
LCALL
%FMUL3 三字节浮点数乘法子程序
MOV 38H,R4 MUL ADDRESS
MOV
39H,R2
MOV 3AH,R3
MOV R0,#38H
LCALL %FTW3
三字节浮点数转换成
双字节无符号数
POP DPL
POP DPH
MOV
A,#80H
ADD A,R3
JNZ SIN90判断峰值
MOV
A,0FFH
SIN90:
MOVX @DPTR,A 把计算值填表
MOV A,DPL
ORL A,#80H 计算sin(a+180)
MOV DPL,A
MOV A,#80H
CLR C
SUBB A,R3
MOVX @DPTR,A 把计算值填表
MOV
A,DPL
ANL A,#7FH
MOV DPL,A
INC DPTR
POP
3
INC R3
CJNE R3,#80H,CALCSIN
判断计算完毕
波形显示程序
WAVE:
MOV R1,#00H
WAVE1:
MOV
DPTR,#4000H 显示锯齿波(256次)
LCALL D_A
DJNZ
R1,WAVE1
WAVE2:
MOV DPTR,#4100H 显示三角波(256次)
LCALL
D_A
DJNZ R1,WAVE2
WAVE3:
MOV DPTR,#4200H
显示正弦波(256次)
LCALL D_A
DJNZ R1,WAVE3
SJMP WAVE
循环显示
D_A:
MOV R0,#00H 置计数器
LOOP:
MOVX
A,@DPTR 查波形表
PUSH DPL
PUSH DPH
MOV
DPTR,#D_APORT
MOVX @DPTR,A 启动 D/A
POP DPH
POP
DPL
INC DPTR改变表格地址
INC R0
CJNE
R0,#00H,LOOP判断是否显示完
RET
步长的十进制ASCII码浮点数
STEP DB
30H,2EH,30H,32H,34H,35H,34H,34H,2CH'0.024544,'
END
//晶振频率12M,所以定时器脉冲频率为1M=1000000#define F 12// 晶振竖姿丛频率
#define ONE_SECOND (F*1000000/12)// 机器周期频率
#define IT0_Cost10 // 定时器0中断平均花费时间10us,这是大概数据,自己余樱可以仔细计算,影响不大只是为了提高精度,所以无法不可能输出1KHz锯齿波,最高只能输出大约390Hz
#define SAWF 100// 输出锯齿波频率,建议输出不高于100Hz
#define oTH0 (65536-ONE_SECOND/SAWF/256 + IT0_Cost) / 256
#define oTL0 (65536-ONE_SECOND/SAWF/256 + IT0_Cost) % 256
void main()
{
TMOD=0X01
TH0=oTH0
TL0=oTL0
ET0=1
TR0=1
EA=1
while(1){}
}
void timer0(void) interrupt 1
{
static unsigned char vout,ff
TH0=oTH0
TL0=oTL0
P2=vout // P2接DAC,输出100Hz
vout++
if(vout==255) vout=0
/* 注册启释部分替换上面三行即输出1Hz
ff++
if(ff == 100)
{
P2=vout // P2接DAC,输出1Hz
vout++
if(vout==255) vout=0
*/
}
*/
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)