本文主要是介绍STC89C52制作可程控低频信号发生器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
STC89C52制作可程控低频信号发生器
- 准备工作
- 操作流程
- 关于PCF8591
- 实现构思
- 相关代码
- 定时器相关代码
- 串口控制频率和LCD显示函数
- 相关功能现象
- 总结
准备工作
由于51单片机本身并不自带DAC的功能,因此需要借助外置模块实现DAC的功能,在选型上,看重仅需要两只引脚驱动的一款DA/AD模块,PCF8591模块,带有一路DA输出且内部自带晶振,可以配合STC89C52RC的定时器实现小频率的信号发生器。
操作流程
有了一定构思之后就需要确认操作流程!
关于PCF8591
PCF8591是一个8位分辨率的DA/AD模块,并且使用IIC通信,可以很方便的使用51单片机模拟IIC通信,使用过程中需要注意的一个点就是PCF8591的手册中有说明,IIC速率最大不超过100K,因此需要搭配合适的延时。
实现构思
结合手册和DA的实现我们可以发现,所谓的DA其实就是,数字量转换为模拟电压,其中又构成线性比例关系,而我们使用的PCF8591模块的基准电压源接到了,供电电源上,因此存在一下关系:
X:2^8 = N:VCC:X为写入PCF8591的数据,N为输出电压
可以通过这个计算我们可以通过编程实现N跟随X的变化而变化!,而实现一个正弦波,我们该怎么操作?正弦波参数有 : 频率,周期,就够了,幅度我们不用考虑,PCF最大输出不会超过VREF的电压,例如实现一个10HZ的正弦波:
freq = 10 ,T = 1/10 = 0.1S=100000us 那么一个周期内不断的向PCF发送电压数字量是不是可以实现呢!这个时候我们可以借助一些软件直接生成正弦波所需相关数据:如下图64个数据,则意味一个周期内需要向64此数据,这个时候我们可以借助定时器实现!!
相关代码
定时器相关代码
因为串口用到定时器1作为波特率发生器,串口数据中的数据帧头用到定时器0作为超时判断,只能用STC89C52RC的额外的定时器2,实现定时发送相关数据到PCF8591!
u16 timer2val = 287; //配置定时器初始值 :频率得出周期,周期内64个点,得出每个点之间的时间就是定时器中断时间
u8 TL2BUFF;
u8 TH2BUFF;
/************************
* 定时器2初始化函数
* T2工作在16位自动重装 开定时器中断
*************************/
void Timer2_Init(void) //10毫秒@11.0592MHz
{T2MOD = 0; //初始化模式寄存器T2CON = 0; //初始化控制寄存器TL2BUFF = (65535-timer2val)%256; //设置定时初始值TH2BUFF = (65535-timer2val)/256; //设置定时初始值TL2 = TL2BUFF; //设置定时初始值TH2 = TH2BUFF; //设置定时初始值RCAP2L = TL2BUFF; //设置定时重载值RCAP2H = TH2BUFF; //设置定时重载值TR2 = 1; //定时器2开始计时ET2 = 1; //使能定时器2中断
}
/************************
* 定时器2中断服务函数
* T0工作在方式1.开定时器中断
*************************/
void Timer2_Isr(void) interrupt 5
{TF2 = 0;timer2flag = 1;
}
串口控制频率和LCD显示函数
发送相关对应的判断指令即可控制输出不同频率的正弦波:原理通过改变定时器2的初值实现周期的改变从而实现频率的改变!!因为STC89C52RC定时器2只有16位自动重装模式,所以不能在主函数循环前开启初始化!
void Uart_service(u8 *buf)
{u8 recv_move_index;if(recv_flag){recv_flag = 0; //清除接受标志位start_timer = 0;//关掉软件计时器Send_Str(buf);//处理数据while((recv_cnt >= 5) && (recv_move_index <= recv_cnt)){if((buf[recv_move_index+0]) == 0x55 && (buf[recv_move_index+1]) == 0xAA && (buf[recv_move_index+2]) == 0x55){if((buf[recv_move_index+3] == 0x01) && (buf[recv_move_index+4] == 0x02)){timer2val = 287; //配置定时器初始值 :频率得出周期,周期内32个点,得出每个点之间的时间就是定时器中断时间Timer2_Init();Send_Byte_uart(0x10);LcdShowStr(3,1,"Freq:");LcdShowStr(9,0,"50HZ");}if((buf[recv_move_index+3] == 0x02) && (buf[recv_move_index+4] == 0x01)){timer2val = 1435; //配置定时器初始值 :频率得出周期,周期内32个点,得出每个点之间的时间就是定时器中断时间Timer2_Init();Send_Byte_uart(0x50);LcdShowStr(3,1,"Freq:");LcdShowStr(9,0,"10HZ");}break;}recv_move_index++;}clr_recvbuffer(buf);//清除缓冲BUFrecv_cnt = 0;}
}
相关功能现象
串口控制实现改变便频率且LCD1602显示频率
总结
在平时的小型实验中,用不上专用的信号发生器,用这么个小模块实现小频率的正弦波用来学习还是很不错的,其实也还可作为方波发生器或者三角波,原理都跟上面说的类似,博文中仅贴出相关功能代码,需要源代码的可以留言邮箱获取哦,长期发布电子相关文章,喜欢的点个关注吧~~
这篇关于STC89C52制作可程控低频信号发生器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!