本人第一次发技术贴,是学校一个比赛项目,项目要求如下:简单说就是用51单片机产生频率可调的方波,正弦波,锯齿波和三角波。
本人使用DAC0832芯片和LM358N完成数模转换及信号放大。正弦波形有一点点失真。欢迎大神给后续意见,仅供学习。
keil文件及c语言文件在下面。
电路原理图如下:
示波器实测波形如下:
单片机源程序如下:
- #include<reg51.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit LCD_RST=P0^5;
- sbit LCD_CE=P0^4;
- sbit LCD_DC=P0^3;
- sbit SDIN=P0^2;
- sbit SCLK=P0^1;
- void LCD_write_byte(unsigned char dat, unsigned char command) ;
- void LCD_init(void);
- void delay_1us();
- void LCD_set_XY(unsigned char X, unsigned char Y);
- void LCD_clear();
- void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y);
- bit run=1;
- sbit cs=P1^2;//DAC0832的输入寄存器的选择端
- sbit wr=P1^3;//DAC0832输入寄存器的写选通信号
- sbit s1=P3^4;//按键
- sbit s2=P3^3;//按键
- sbit s3=P3^2;//按键
- uchar s1num=0,ys=30;//ys表示延时函数实参的初始值;s1num表示按键切换的代码
- uchar code Sin[256]={
- 0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,
- …………
- …………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
- 0x00,0x00,0x7F,0x40,0x50,0x48,0x44,0x43,0x44,0x48,0x50,0x40,0xFF,0x00,0x00,0x00};
- void keyscanf();//波形切换函数
- void delay1(uchar y);//声明延时函数
- void main()//主函数
- {
- uchar i;
- IT0=1;
- EX0=1;
- IT1=1;
- EX1=1;
- EA=1;
- LCD_init();//LCD初始化
- cs=0;//打开输入寄存器选择端(详见DAC0832的操作时序)
- while(1)
- {
- keyscanf();//调用波形切换函数
- if(s1num==0)//方波(s1没有按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,fang,16,16) ;
- LCD_draw_bmp_pixel(0,2,bo,16,16) ;
- LCD_draw_bmp_pixel(17,2,douhao,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,san,16,16) ;
- LCD_draw_bmp_pixel(33,4,jiao,16,16) ;
- LCD_draw_bmp_pixel(49,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=0x00;
- wr=0;//输入寄存器写选通信号有效(详见DAC0832的操作时序)
- wr=1;//关闭写选通信号
- }
- delay1(ys);//通过延时时间的长短改变信号的频率
- for(i=0;i<255;i++)
- {
- P2=0xff;
- wr=0;
- wr=1;
- }
- delay1(ys);//通过延时时间的长短改变信号的频率
- }
- if(s1num==1)//三角波(s1第一次按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,san,16,16) ;
- LCD_draw_bmp_pixel(0,2,jiao,16,16) ;
- LCD_draw_bmp_pixel(17,2,bo,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,ju,16,16) ;
- LCD_draw_bmp_pixel(33,4,chi,16,16) ;
- LCD_draw_bmp_pixel(49,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=i;
- wr=0;
- wr=1;
- }
- delay1(ys);//通过延时时间的长短改变信号的频率
- for(i=255;i>0;i--)
- {
- P2=i;
- wr=0;
- wr=1;
- }
- delay1(ys);//通过延时时间的长短改变信号的频率
- }
- if(s1num==2)//锯齿波(s1第二次按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,ju,16,16) ;
- LCD_draw_bmp_pixel(0,2,chi,16,16) ;
- LCD_draw_bmp_pixel(17,2,bo,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,zheng,16,16) ;
- LCD_draw_bmp_pixel(33,4,xian,16,16) ;
- LCD_draw_bmp_pixel(49,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=i;
- wr=0;
- wr=1;
- }
- delay1(ys);//通过延时时间的长短改变信号的频率
- }
- if(s1num==3)//正弦波(s1第三次按下)
- {
- if(run==1)
- {
- LCD_draw_bmp_pixel(0,0,dang,16,16) ;
- LCD_draw_bmp_pixel(17,0,qian,16,16) ;
- LCD_draw_bmp_pixel(33,0,shu,16,16) ;
- LCD_draw_bmp_pixel(49,0,chu,16,16) ;
- LCD_draw_bmp_pixel(65,0,zheng,16,16) ;
- LCD_draw_bmp_pixel(0,2,xian,16,16) ;
- LCD_draw_bmp_pixel(17,2,bo,16,16) ;
- LCD_draw_bmp_pixel(33,2,an,16,16) ;
- LCD_draw_bmp_pixel(49,2,xia,16,16) ;
- LCD_draw_bmp_pixel(65,2,shu,16,16) ;
- LCD_draw_bmp_pixel(0,4,chu,16,16) ;
- LCD_draw_bmp_pixel(17,4,fang,16,16) ;
- LCD_draw_bmp_pixel(33,4,bo,16,16) ;
- run=0;
- }
- for(i=0;i<255;i++)
- {
- P2=Sin[i];
- wr=0;
- wr=1;
- }
- delay1(ys);//通过延时时间的长短改变信号的频率
- }
- }
- }
- void LCD_write_byte(unsigned char dat, unsigned char command)
- {
- unsigned char i;
- LCD_CE = 0; //5110片选有效,允许输入数据
- if (command == 0) //写命令
- LCD_DC = 0;
- else LCD_DC = 1; //写数据
- for(i=0;i<8;i++) //传送8bit数据
- {
- if(dat&0x80)
- SDIN = 1;
- else
- SDIN = 0;
- SCLK = 0;
- dat = dat << 1;
- SCLK = 1;
- }
- LCD_CE = 1; //禁止5110
- }
- void delay_1us()
- {
- unsigned int y;
-
- for(y=110;y>0;y--)
- {}
- }
- /***********************************************************
- 函数名称:LCD_init
- 函数功能:5110初始化
- 入口参数:无
- 出口参数:无
- 备 注:
- ***********************************************************/
- void LCD_init(void)
- {
- LCD_RST = 0; // 产生一个让LCD复位的低电平脉冲
- delay_1us();
- LCD_RST = 1;
-
- LCD_CE = 0; // 关闭LCD
- delay_1us();
- LCD_CE = 1; // 使能LCD
- delay_1us();
-
- LCD_write_byte(0x21, 0); // 使用扩展命令设置LCD模式
- LCD_write_byte(0xc8, 0); // 设置液晶偏置电压
- LCD_write_byte(0x06, 0); // 温度校正
- LCD_write_byte(0x13, 0); // 1:48
- LCD_write_byte(0x20, 0); // 使用基本命令,V=0,水平寻址
- LCD_clear(); // 清屏
- LCD_write_byte(0x0c, 0); // 设定显示模式,正常显示
-
- LCD_CE = 0; // 关闭LCD
- }
- /***********************************************************
- 函数名称:LCD_set_XY
- 函数功能:设置LCD坐标函数
- 入口参数:X :0-83
- Y :0-5
- 出口参数:无
- 备 注:
- ***********************************************************/
- void LCD_set_XY(unsigned char X, unsigned char Y)
- {
- LCD_write_byte(0x40 | Y, 0); // column
- LCD_write_byte(0x80 | X, 0); // row
- }
- /***********************************************************
- 函数名称:LCD_draw_bmp_pixel
- 函数功能:位图绘制函数
- 入口参数:X、Y :位图绘制的起始X、Y坐标;
- *map :位图点阵数据;
- Pix_x :位图像素(长)
- Pix_y :位图像素(宽)
- 出口参数:无
- 备 注:
- ***********************************************************/
- void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y)
- {
- unsigned int i,n;
- unsigned char row;
- //计算位图所占行数
- if (Pix_y%8==0) //如果为位图所占行数为整数
- row=Pix_y/8;
- else
- row=Pix_y/8+1; //如果为位图所占行数不是整数
-
- LCD_set_XY(X,Y);
- for (n=0;n<row;n++) //换行
- {
- for(i=0;i<Pix_x;i++)
- {
- LCD_set_XY(X+i,Y+n);
- LCD_write_byte(map[i+n*Pix_x], 1);
- }
- }
- }
- void LCD_clear()
- {
- unsigned char t,k;
- LCD_set_XY(0,0);
- for(t=0;t<6;t++)
- {
- for(k=0;k<84;k++)
- LCD_write_byte(0x00,1);
- }
- }
- void keyscanf()//波形切换函数
- {
- if(s1==0)//判断按键按下
- {
- delay1(20);//延时消除抖动
- if(s1==0)//重新判断
- {
- while(!s1);//等待按键释放
- s1num++;
- run=1;
- s1num=s1num%4;//波形的切换由此数值来决定
- }
- }
- }
- void delay1(uchar y)//延时函数
- {
- uchar i;
- for(i=y;i>0;i--);
- }
- void aaaa() interrupt 0
- {
- if(s3==0)//判断按键按下
- {
- delay1(20);//延时消除抖动
- if(s3==0)//重新判断
- {
- while(!s3);//等待按键释放
- ys++;
- }
- }
- }
- void bbbb() interrupt 2
- {
- if(s2==0)//判断按键按下
- {
- delay1(20);//延时消除抖动
- if(s2==0)//重新判断
- {
- while(!s2);//等待按键释放
- …………
- …………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
基于51单片机的波形发生器.rar
(28.66 KB, 下载次数: 77)
|