標(biāo)題:
51單片機(jī)控制信號(hào)發(fā)生器源程序(正弦波、方波)Gerber文件
[打印本頁(yè)]
作者:
GaoChen_IC
時(shí)間:
2020-7-24 13:54
標(biāo)題:
51單片機(jī)控制信號(hào)發(fā)生器源程序(正弦波、方波)Gerber文件
信號(hào)發(fā)生器,有Keil程序和Gerber打板。
單片機(jī)型號(hào):STC15W4K32S4
數(shù)字編碼器EC11作為控制波形、頻率、占空比的開(kāi)關(guān)
液晶1602A作為顯示信息
1.png
(83.36 KB, 下載次數(shù): 69)
下載附件
2020-7-24 13:49 上傳
1.jpg
(943.49 KB, 下載次數(shù): 54)
下載附件
2020-7-24 13:49 上傳
Gerber文件下載(無(wú)PCB):
51單片機(jī)信號(hào)發(fā)生器機(jī).7z
(3.33 MB, 下載次數(shù): 63)
2020-7-25 03:29 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
單片機(jī)源程序如下:
Note:
2020-05-06 Update
1. Fix an error in main funciton, cause the EC11 Encoder rotate disorder.
2. Fix an error of interface display during switch frequency.
2020-05-24 Update
1. Fix precision of PWM frequency
2. Fix the information error in interface
波形發(fā)生器
作者:老劉愛(ài)搗鼓
版本:V0.3.1
單片機(jī)型號(hào):STC15W4K32S4 @24MHz
B站視頻教程:https://www.bilibili.com/video/BV12k4y197Qu
老劉愛(ài)搗鼓(全網(wǎng)同名)期待您的關(guān)注!
規(guī)格:
輸出:?jiǎn)瓮ǖ?br />
方波:1Hz~4MHz
正弦波:1Hz-10kHz
波幅:約等于VCC,5V左右
帶載能力:無(wú)帶載能力
顯示屏:LCD1602
控制:EC11編碼器
界面:
左下角顯示波形圖標(biāo)(方波/正弦波)和輸出狀態(tài)(On/OFF)
F:頻率
D:方波占空比
CD:時(shí)鐘分頻系數(shù)(For information only)
P:用于生成正弦波的PWM頻率(For information only)
Pt:用于生成正弦波的點(diǎn)數(shù)(For information only)
操作:
單擊編碼器:方波界面下,切換頻率和占空比
雙擊編碼器:開(kāi)啟或關(guān)閉波形輸出
長(zhǎng)按編碼器:切換方波界面/正弦波界面/電壓顯示界面
旋轉(zhuǎn)編碼器:調(diào)節(jié)參數(shù)
2020-05-06 更新
1. 修正main函數(shù)循環(huán)中會(huì)引起編碼器旋轉(zhuǎn)混亂的錯(cuò)誤
將main函數(shù)中while循環(huán)中的Update_Flag=0;放到前面清零,放在后面會(huì)在編碼器高速旋轉(zhuǎn)時(shí),多次觸發(fā)中斷而Update_Flag在最后被清零則無(wú)法正確更新LCD
2. 修正在切換頻率時(shí),界面的顯示錯(cuò)誤
2020-05-24 Update
1. 修正PWM頻率精度
2. 修正界面信息的顯示錯(cuò)誤
*/
#include <reg51.h>
#include <intrins.h>
#include "lcd1602.h"
#include "wave.h"
#include "settings.h"
#include "delay.h"
#include "config_stc.h"
//#include "uart.h"
//#include "stdio.h"
#ifndef uint8
#define uint8 unsigned char
#endif
#ifndef int8
#define int8 char
#endif
#ifndef uint16
#define uint16 unsigned int
#endif
#ifndef uint32
#define uint32 unsigned long int
#endif
#define TIMER_0 1 //定時(shí)器0中斷序號(hào)
#define INT_1 2 //編碼器旋轉(zhuǎn) 觸發(fā)外部中斷
#define INT_0 0 //編碼器按下 觸發(fā)外部中斷
uint8 Timer0_Count;
bit Update_Flag = 1;
void main(void)
{
//LCD Pin
P1M1 &= 0x00; //設(shè)置P1口為準(zhǔn)雙向
P1M0 &= 0x00; //設(shè)置P1口為準(zhǔn)雙向
P0M1 &= 0x00; //設(shè)置P0口為準(zhǔn)雙向
P0M0 &= 0x00; //設(shè)置P0口為準(zhǔn)雙向
//信號(hào)輸出Pin
PWM3 = 0; //設(shè)置PWM3 P4.5低電平
PWM4 = 0; //設(shè)置PWM4 P4.4低電平
P4M1 |= 0x30; //設(shè)置P4.4(PWM4_2),4.5(PWM3_2)為高阻
P4M0 &= ~0x30; //設(shè)置P4.4(PWM4_2),4.5(PWM3_2)為高阻
/* 編碼器旋轉(zhuǎn)中斷
Interrupt for Encoder Rotation */
IT1 = 0; //外部中斷1觸發(fā)方式,上升沿和下降沿
PX1 = 1; //外部中斷1高優(yōu)先級(jí)
EX1 = 1; //開(kāi)啟外部中斷1
/* 編碼器按鍵中斷
Interrupt for Encoder Click */
IT0 = 1; //外部中斷0觸發(fā)方式,下降沿
PX0 = 1; //外部中斷0高優(yōu)先級(jí)
EX0 = 1; //開(kāi)啟外部中斷0
/* 定時(shí)器0,用于更新電壓信息計(jì)時(shí)
Timer 0 for updating the information of VCC*/
TMOD &= 0xF0; //設(shè)置定時(shí)器0模式 16位自動(dòng)重載,在Keil中debug的話,請(qǐng)注意,這種設(shè)置是8051的舊13位模式
AUXR &= ~0x80; //定時(shí)器0時(shí)鐘12T模式
TL0 = 0xC0; //設(shè)置定時(shí)初值 24MHz 20ms
TH0 = 0x63; //設(shè)置定時(shí)初值 24MHz 20ms
ET0 = 1; //允許T0溢出中斷
/* 定時(shí)器1,用于生成小于50Hz的PWM
Timer 1 for generate the PWM when frequency less than 50Hz*/
TMOD &= 0x0F; //工作模式,0: 16位自動(dòng)重裝
AUXR &= ~0x40; //12T
ET1 = 1; //允許中斷
EA = 1; //開(kāi)總中斷
//UartInit();
//UartInit_interrupt();
PWM_Hz_Pre = PWM_Hz;
Wave_Shape_Pre = Wave_Shape;
Get_PWM_Duty_Limit();
if (PWM_Duty > PWM_Max_Duty)
PWM_Duty = PWM_Max_Duty;
else if (PWM_Duty < PWM_Min_Duty)
PWM_Duty = PWM_Min_Duty;
Lcd_Init();
while (1)
{
if (Update_Flag)
{
/* Update_Flag要馬上清零,如果放在Update_LCD后面,會(huì)造成假如Update_LCD的過(guò)程中再次觸發(fā)編碼器旋轉(zhuǎn)中斷的話,
在執(zhí)行完Update_LCD后,在中斷中置位的Update_Flag卻被清零了,造成LCD沒(méi)刷新,輸出和顯示的不一致。
另一種方法是在執(zhí)行Update_LCD前把中斷關(guān)掉,執(zhí)行完再打開(kāi)中斷, 但如果這里面的函數(shù)執(zhí)行時(shí)間比較長(zhǎng),會(huì)產(chǎn)生旋轉(zhuǎn)觸發(fā)不及時(shí),使用感受卡頓。
關(guān)中斷來(lái)避免重復(fù)觸發(fā)是有好處的,可以避免在函數(shù)執(zhí)行過(guò)程中多次觸發(fā)將參數(shù)修改掉,
函數(shù)執(zhí)行過(guò)程中參數(shù)被修改,可能會(huì)造成計(jì)算結(jié)果混亂,嚴(yán)重時(shí)會(huì)造成溢出,甚至單片機(jī)復(fù)位死機(jī)。 */
Update_Flag = 0;
Wave_OFF();
if (Wave_Shape_Pre != Wave_Shape)
{
Wave_Shape_Pre = Wave_Shape;
if (Wave_Shape == 0)
{
EX1 = 0; //關(guān)閉外部中斷1(編碼器旋轉(zhuǎn))
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí) (定時(shí)器0為VCC更新計(jì)時(shí))
}
else if (Wave_Shape == 1)
{
PWM_Hz = PWM_Hz_Pre;
EX1 = 1; //開(kāi)啟外部中斷1(編碼器旋轉(zhuǎn))
TR0 = 0; //關(guān)閉定時(shí)器0 (定時(shí)器0為VCC更新計(jì)時(shí))
TF0 = 0; //清除TF0標(biāo)志
}
else if (Wave_Shape == 2)
{
PWM_Hz_Pre = PWM_Hz;
}
}
if (Wave_Shape == 1) //方波
{
Set_PWMCKS_PS();
Set_PWM_Cycle();
Set_PWM_Width();
}
else if (Wave_Shape == 2) //正弦波
{
Set_Sin_Table_Times();
Set_PWMCKS_PS();
Set_PWM_Cycle();
}
Update_LCD();
//EX1 = 0;
Set_Wave_Shape();
//IE1=0;
//EX1 = 1;
}
}
}
/* 編碼器旋轉(zhuǎn)響應(yīng)函數(shù)
Encoder Rotate */
void Scan_EC11(void)
{
/* 正轉(zhuǎn)
Rotate clockwise */
if ((EC11_A != EC11_B))
{
Change_Val(1);
}
/* 反轉(zhuǎn)
Rotate anticlockwise*/
else if ((EC11_A == EC11_B))
{
Change_Val(0);
}
}
/* 編碼器旋轉(zhuǎn)中斷
Interrupt for Encoder rotation */
void INT1_interrupt(void) interrupt INT_1
{
Delay1ms();
Scan_EC11();
Update_Flag = 1;
//Delay50ms();
IE1 = 0;
}
/* 編碼器點(diǎn)擊中斷
Interrupt for Encoder click */
void INT0_interrupt(void) interrupt INT_0
{
Delay5ms();
if (!EC11_KEY)
{
/* 長(zhǎng)按
Long Press */
if (Delay500ms_long_click())
{
Wave_Shape++;
if (Wave_Shape > WAVE_NUM)
Wave_Shape = 0;
if (Wave_Shape == 2)
Options = 1;
WAVE_ON = 0;
Clear_LCD_Flag = 1;
}
/* 雙擊
Double click */
else if (Delay200ms_double_click())
{
if (Wave_Shape > 0)
{
WAVE_ON = ~WAVE_ON;
}
}
/* 單擊
Single click */
else
{
if (Wave_Shape == 1)
Options = ~Options;
}
Update_Flag = 1;
}
Delay5ms();
IE0 = 0;
}
/* 更新電壓信息計(jì)時(shí)中斷
Timer interrupt for update voltage information */
void TIMER0_interrupt() interrupt TIMER_0
{
if (++Timer0_Count > 200) //200x20=4000ms
{
Timer0_Count = 0;
Update_Flag = 1;
}
}
復(fù)制代碼
作者:
tony526
時(shí)間:
2020-8-20 19:44
有沒(méi)有hen編程源碼
作者:
chanmk
時(shí)間:
2020-12-25 09:21
有配套原理圖嗎
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1