功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶显示当前输出波形类型和频率
2.可通过按键调整输出波形类型和频率
3.可通过按键设置频率更改步进值
4.支持正弦波/方波/三角波/锯齿波输出,输出频率范围:10~100Hz
5.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h> //包含头文件
#include <intrins.h>
#define uchar unsigned char //宏定义
#define uint unsigned int
sbit KEY_ADD = P2^1; //定义按键的接口
sbit KEY_SUB = P2^3;
sbit KEY_MODE = P2^2;
sbit KEY_SET = P2^0;
sbit LED_ZIGZAG = P3^2;
sbit LED_TRIANGLE = P3^3;
sbit LED_SQUARE = P3^5;
sbit LED_SINE = P3^4;
sbit LCD_RS = P3^6; //液晶控制位
sbit LCD_EN = P3^7;
char g_wave;
char g_cnt; //定义全局变量
int g_freq = 100; //*0.1Hz
int g_step = 1;
int g_stepDisp = 1;
uchar code g_table_num[] = "0123456789"; //定义显示的数组
uchar code g_table_str[] = "Freq: Wave form:";
unsigned long T0CNT;
int T0RH;
int T0RL;
int g_mode;
unsigned char pwmValue = 50;
unsigned char outValue = 0;
//自定义字符
uchar code USER_CHAR[] = {
0x0e, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x0e, 0x00, //正弦波 0 1
0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00,
0x00, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x07, 0x00, //矩形波 2 3
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, //三角波 4 5
0x00, 0x01, 0x03, 0x05, 0x09, 0x11, 0x00, 0x00, //锯齿波 6
};
uchar code SINE_CHAR[64] = {
135, 145, 158, 167, 176, 188, 199, 209, 218, 226, 234, 240, 245, 249, 252, 254, 254, 253, 251, 247, 243, 237, 230, 222, 213, 204, 193, 182, 170, 158,
146, 133, 121, 108, 96, 84, 72, 61, 50, 41, 32, 24, 17, 11, 7, 3, 1, 0, 0, 2, 5, 9, 14, 20, 28, 36, 45, 55, 66, 78, 90, 102, 114, 128}; //正弦波取码
uchar code SQUARE_CHAR[64] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //矩形波取码
uchar code TRIANGLE_CHAR[64] = {
0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248,
248, 240, 232, 224, 216, 208, 200, 192, 184, 176, 168, 160, 152, 144, 136, 128, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0}; //三角波取码
uchar code ZIGZAG_CHAR[64] = {
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142,
146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255}; //锯齿波取码
void DelayMs(uint t) //延时函数
{
int i, j;
for (i = t; i > 0; i--)
for (j = 110; j > 0; j--)
;
}
void LCD_WriteCom(uchar com) //写命令函数
{
LCD_RS = 0;
P0 = com;
DelayMs(1);
LCD_EN = 1;
DelayMs(1);
LCD_EN = 0;
}
void LCD_WriteData(uchar dat) //写数据函数
{
LCD_RS = 1;
P0 = dat;
DelayMs(1);
LCD_EN = 1;
DelayMs(1);
LCD_EN = 0;
}
//自定义字符集
void LCD_RAM()
{
uint i, j, k = 0, temp = 0x40;
for (i = 0; i < 7; i++)
{
for (j = 0; j < 8; j++)
{
LCD_WriteCom(temp + j);
LCD_WriteData(USER_CHAR[k]);
k++;
}
temp = temp + 8;
}
}
void Init_LCD() //初始化函数
{
uchar i;
LCD_EN = 0; //默认开始状态为关使能端,见时序图
LCD_RAM();
LCD_WriteCom(0x0f);
LCD_WriteCom(0x38); //显示模式设置,默认为0x38,不用变。
LCD_WriteCom(0x01); //显示清屏,将上次的内容清除,默认为0x01.
LCD_WriteCom(0x0c); //显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪
LCD_WriteCom(0x06); //设置光标状态默认0x06,为读一个字符光标加1.
LCD_WriteCom(0x80); //设置初始化数据指针,是在读指令的操作里进行的
for (i = 10; i < 20; i++) //显示初始化
{
LCD_WriteData(g_table_str[i]);
}
LCD_WriteCom(0x80 + 0x40);
for (i = 0; i < 9; i++)
{
LCD_WriteData(g_table_str[i]);
}
LCD_WriteCom(0x80 + 10);
LCD_WriteData(0);
LCD_WriteData(1);
LCD_WriteData(0);
LCD_WriteData(1);
LCD_WriteData(0);
LCD_WriteData(1);
LCD_WriteCom(0x80 + 0x40 + 0x09);
LCD_WriteData(' ');
LCD_WriteData('1');
LCD_WriteData('0');
LCD_WriteData('.');
LCD_WriteData('0');
LCD_WriteData('H');
LCD_WriteData('z');
}
void Init_Timer() //时钟初始化
{
TMOD = 0x01;
TH0 = T0RH;
TL0 = T0RL;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Display() //显示函数
{
uchar kilobit, hundredbit, tenbit, unitbit;
kilobit = g_freq / 1000;
hundredbit = g_freq % 1000 / 100;
tenbit = g_freq % 1000 % 100 / 10;
unitbit = g_freq % 1000 % 100 % 10;
LCD_WriteCom(0x80 + 0x40 + 0x09);
if (kilobit == 0)
LCD_WriteData(' ');
else
LCD_WriteData(g_table_num[kilobit]);
if (kilobit == 0 && hundredbit == 0)
LCD_WriteData(' ');
else
LCD_WriteData(g_table_num[hundredbit]);
LCD_WriteData(g_table_num[tenbit]);
LCD_WriteData('.');
LCD_WriteData(g_table_num[unitbit]);
LCD_WriteData('H');
LCD_WriteData('z');
if (g_wave == 0)
{
LCD_WriteCom(0x80 + 10);
LCD_WriteData(0);
LCD_WriteData(1);
LCD_WriteData(0);
LCD_WriteData(1);
LCD_WriteData(0);
LCD_WriteData(1);
}
if (g_wave == 1)
{
LCD_WriteCom(0x80 + 10);
LCD_WriteData(2);
LCD_WriteData(3);
LCD_WriteData(2);
LCD_WriteData(3);
LCD_WriteData(2);
LCD_WriteData(3);
}
if (g_wave == 2)
{
LCD_WriteCom(0x80 + 10);
LCD_WriteData(4);
LCD_WriteData(5);
LCD_WriteData(4);
LCD_WriteData(5);
LCD_WriteData(4);
LCD_WriteData(5);
}
if (g_wave == 3)
{
LCD_WriteCom(0x80 + 10);
LCD_WriteData(6);
LCD_WriteData(6);
LCD_WriteData(6);
LCD_WriteData(6);
LCD_WriteData(6);
LCD_WriteData(6);
}
}
void KeyScan() //键盘检测函数
{
if (KEY_ADD == 0)
{
EA = 0;
DelayMs(2);
if (KEY_ADD == 0)
{
while (!KEY_ADD)
;
g_freq += g_step;
if (g_freq > 1000)
{
g_freq = 100;
}
Display();
T0CNT = 65536 - (144000 / g_freq) + 25;
T0RH = T0CNT / 256;
T0RL = T0CNT % 256;
EA = 1;
}
}
if (KEY_SUB == 0)
{
DelayMs(5);
if (KEY_SUB == 0)
{
EA = 0;
while (!KEY_SUB)
;
g_freq -= g_step;
if (g_freq < 100)
{
g_freq = 1000;
}
Display();
T0CNT = 65536 - (144000 / g_freq) + 25;
T0RH = T0CNT / 256;
T0RL = T0CNT % 256;
EA = 1;
}
}
if (KEY_MODE == 0)
{
DelayMs(5);
if (KEY_MODE == 0)
{
EA = 0;
while (!KEY_MODE)
;
g_wave++;
if (g_wave >= 4)
{
g_wave = 0;
}
Display();
EA = 1;
}
}
}
void DisplayStep()
{
uint hundredbit, tenbit, unitbit;
hundredbit = g_stepDisp / 100;
tenbit = g_stepDisp % 100 / 10;
unitbit = g_stepDisp % 100 % 10;
LCD_WriteCom(0x80 + 11);
if (hundredbit == 0)
LCD_WriteData(' ');
else
LCD_WriteData(g_table_num[hundredbit]);
LCD_WriteData(g_table_num[tenbit]);
LCD_WriteData('.');
LCD_WriteData(g_table_num[unitbit]);
}
void ScanStep()
{
if (KEY_SET == 0)
{
DelayMs(5);
if (KEY_SET == 0)
{
while (!KEY_SET)
;
g_mode++;
if (g_mode == 1)
{
LCD_WriteCom(0x01);
LCD_WriteCom(0x80);
LCD_WriteData('S');
DelayMs(1); //step value
LCD_WriteData('t');
DelayMs(1);
LCD_WriteData('e');
DelayMs(1);
LCD_WriteData('p');
DelayMs(1);
LCD_WriteData(' ');
DelayMs(1);
LCD_WriteData('v');
DelayMs(1);
LCD_WriteData('a');
DelayMs(1);
LCD_WriteData('l');
DelayMs(1);
LCD_WriteData('u');
DelayMs(1);
LCD_WriteData('e');
DelayMs(1);
LCD_WriteData(':');
DelayMs(1);
g_stepDisp = g_step;
DisplayStep();
}
if (g_mode == 2)
{
g_mode = 0;
g_step = g_stepDisp;
Init_LCD();
Init_Timer();
Display();
}
}
}
if (g_mode == 1)
{
if (KEY_ADD == 0)
{
DelayMs(5);
if (KEY_ADD == 0)
{
while (!KEY_ADD)
;
g_stepDisp++;
if (g_stepDisp >= 101)
{
g_stepDisp = 1;
}
DisplayStep();
}
}
if (KEY_SUB == 0)
{
DelayMs(5);
if (KEY_SUB == 0)
{
while (!KEY_SUB)
;
g_stepDisp--;
if (g_stepDisp <= 0)
{
g_stepDisp = 100;
}
DisplayStep();
}
}
}
}
void main() //主函数
{
Init_LCD();
T0CNT = 65536 - (144000 / g_freq) + 25;
T0RH = T0CNT / 256;
T0RL = T0CNT % 256;
Init_Timer();
LED_ZIGZAG = 0;
while (1)
{
if (g_mode == 0)
{
KeyScan();
// Display();
}
ScanStep();
switch (g_wave)
{
case 0:
P1 = SINE_CHAR[g_cnt];
LED_ZIGZAG = 1;
LED_SINE = 0;
break;
case 1:
P1 = SQUARE_CHAR[g_cnt];
// P1 = outValue;
LED_SINE = 1;
LED_SQUARE = 0;
break;
case 2:
P1 = TRIANGLE_CHAR[g_cnt];
LED_SQUARE = 1;
LED_TRIANGLE = 0;
break;
case 3:
P1 = ZIGZAG_CHAR[g_cnt];
LED_TRIANGLE = 1;
LED_ZIGZAG = 0;
break;
}
}
}
void T0_time() interrupt 1 //定时器
{
TH0 = T0RH;
TL0 = T0RL;
g_cnt++;
if (g_cnt >= 64)
{
g_cnt = 0;
}
// if (g_cnt >= pwmValue)
// {
// outValue = 255;
// }
// else
// {
// outValue = 0;
// }
}