本帖最后由 QuaX_Chow 于 2024-8-21 22:12 编辑
声明及本系列注意事项优先阅读:🔗
工程源码及仿真文件入口在文末,如果没显示就是还在审核
任务要求:使用C51实现四按键控制MAX517分别产生方波、三角波、锯齿波和正弦波,波形通过Proteus内的示波器显示,在P2.0~P2.3接四个按键开关,分别对应与四种波形;时钟信号由,一开始无按键按下时无输出
想要实现以上功能,我们需要将任务拆分为以下几个部分:
- MAX517通信
- 中断按键判断
1.Proteus部分
波形显示使用的是虚拟仪器模式中的“OSCILLOSCOPE”四通道示波器:
搭建好的仿真电路如下:
如果在仿真时不小心把波形显示窗口关掉了,只需在仿真状态下点击菜单栏里的“调试”-“Digital Oscilloscope”,即可显示示波器界面
2.代码部分
(1)MAX517通信
在我们驱动MAX517之前,我们首先需要理清这颗芯片的时序
驱动MAX517需要使用两线串行接口,兼容IIC
见下图:
一条时钟线,一条数据线。声明如下:
sbit SCL = P1^0;//MAX517串行时钟
sbit SDA = P1^1;//MAX517串行数据
开始状态标志为时钟线高、数据线下降沿。结束状态标志为时钟线高、数据线上升沿。
在编程时我们就需要根据芯片时序,使用GPIO进行模拟。
以SC为示例编写函数:
void start(void)//起始条件子程序
{
SDA= 1;
SCL = 1;
_nop_();
SDA =0;
_nop_();
}
完整的传输过程如下图:
控制MAX517模拟输出需要根据上图步骤编写一个有着完整的:启动-发送地址-应答-命令-应答-数据-应答-结束,流程的函数:
void DACOut (uchar ch)//串行D/A转换子程序
{
start();//发送启动信号
send(0x58);//发送地址字节
ack();
send(0x00);//发送命令字节
ack();
send(ch);//发送数据字节
ack();
stop();//结束一次转换
}
如果我们需要输出一个指定的电压,就只需要 DACOut(需要的值);
公式如下:
但是我们需要输出的是波形,而非稳定的电平,所以我们需要一直改变输出模拟量的值ch。
以输出正弦波为例,创建数组存储ch的值,使用在输出时仅需将元素递增:
uchar sindata[64]=
{ 0x80,0x8c,0x98,0xa5,0xb0,0xbc,0xc7,0xd1,
0xda,0xe2,0xea,0xf0,0xf6,0xfa,0xfd,0xff,
0xff,0xff,0xfd,0xfa,0xf6,0xf0,0xea,0xe3,
0xda,0xd1,0xc7,0xbc,0xb1,0xa5,0x99,0x8c,
0x80,0x73,0x67,0x5b,0x4f,0x43,0x39,0x2e,
0x25,0x1d,0x15,0xf,0x9,0x5,0x2,0x0,0x0,
0x0,0x2,0x5,0x9,0xe,0x15,0x1c,0x25,0x2e,
0x38,0x43,0x4e,0x5a,0x66,0x73};
方波、锯齿、三角波的实现思路类似,循环内递增、递减、延时即可,具体方法参见文末源码
(2)中断按键判断
要实现立刻切换输出波形的功能,我们需要使用到外部中断0,中断服务函数如下:
void intp0() interrupt 0
{
if(P2_0 == 0) key = 0;//三角波
if(P2_1 == 0) key = 1;//方波
if(P2_2 == 0) key = 2;//正弦
if(P2_3 == 0) key = 3;//锯齿波
}
四种波形输出效果如下:
任务完成
2024/8/21
源码以及仿真文件
#本文首发于EEWORLD,版权归作者所有
补充内容 (2024-8-27 14:28):
勘误:任务要求部分:“时钟信号由,一开始无按键按下时无输出”改为“一开始无按键按下时无输出”