找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3675|回复: 2
收起左侧

PCF8591+单片机波形发生器源码

[复制链接]
ID:635139 发表于 2019-11-6 23:28 | 显示全部楼层 |阅读模式
程序源码
附录 2   程序代码

#include<reg51.h>
#include<intrins.h>
#include<math.h>
#define  uchar  unsigned  char
#define  uint  unsigned   int
unsigned long Result,i;
sbit SDA=P1^1;    //PCF8591 接口
sbit SCL=P1^0;
unsigned int a=0;            //波形采样点值
unsigned int b=0;
unsigned  int c=0;

unsigned  int bx_chang=0;
unsigned  int n=40;  //频率计算值
unsigned char TH;
unsigned char TL;
unsigned int mode=0; //0为调节幅度 1为调节频率
unsigned int fd=6;         //幅度初值  3.0V
unsigned int  x;         //采样点的间隔
unsigned int u;                 //lcd刷屏变量
//*************
sbit CS =P3^5;                  //LCD接口
sbit SID=P3^6;
sbit SCLK=P3^7;
sbit PSB=P1^5;
//*************
sbit p20=P2^0; //波形调节
sbit p21=P2^1; //增加        频率、幅度
sbit p22=P2^2; //减少        频率、幅度
sbit p32=P3^2; //频率幅度选择

                                                                  //sin波形数组
uchar code tosin[256]={
            0x80,0x83,0x86,0x89,0x8D,0x90,0x93,0x96,0x99,0x9C,0x9F,0xA2,0xA5,0xA8,0xAB,0xAE,
                        0xB1,0xB4,0xB7,0xBA,0xBC,0xBF,0xC2,0xC5,0xC7,0xCA,0xCC,0xCF,0xD1,0xD4,0xD6,0xD8,
                        0xDA,0xDD,0xDF,0xE1,0xE3,0xE5,0xE7,0xE9,0xEA,0xEC,0xEE,0xEF,0xF1,0xF2,0xF4,0xF5,
                        0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,
                        0xF5,0xF4,0xF2,0xF1,0xEF,0xEE,0xEC,0xEA,0xE9,0xE7,0xE5,0xE3,0xE1,0xDF,0xDD,0xDA,
                        0xD8,0xD6,0xD4,0xD1,0xCF,0xCC,0xCA,0xC7,0xC5,0xC2,0xBF,0xBC,0xBA,0xB7,0xB4,0xB1,
                        0xAE,0xAB,0xA8,0xA5,0xA2,0x9F,0x9C,0x99,0x96,0x93,0x90,0x8D,0x89,0x86,0x83,0x80,
                        0x80,0x7C,0x79,0x76,0x72,0x6F,0x6C,0x69,0x66,0x63,0x60,0x5D,0x5A,0x57,0x55,0x51,
                        0x4E,0x4C,0x48,0x45,0x43,0x40,0x3D,0x3A,0x38,0x35,0x33,0x30,0x2E,0x2B,0x29,0x27,
                        0x25,0x22,0x20,0x1E,0x1C,0x1A,0x18,0x16,0x15,0x13,0x11,0x10,0x0E,0x0D,0x0B,0x0A,
                        0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
                        0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
                        0x0A,0x0B,0x0D,0x0E,0x10,0x11,0x13,0x15,0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x25,
                        0x27,0x29,0x2B,0x2E,0x30,0x33,0x35,0x38,0x3A,0x3D,0x40,0x43,0x45,0x48,0x4C,0x4E,
                        0x51,0x55,0x57,0x5A,0x5D,0x60,0x63,0x66,0x69,0x6C,0x6F,0x72,0x76,0x79,0x7C,0x80
                        };


//***********************************************

void delay(unsigned int z)                                //延迟函数
{   unsigned int x,y;   
     for(x=z;x>0;x--)  
       for(y=125;y>0;y--) ;
}
//***************************************************LCD显示函数组
void SendByte(unsigned char Dbyte)                                     //LCD字节传送
{
     unsigned char i;            
         CS=1;
     for(i=0;i<8;i++)
     {        SCLK = 0;           
            if((Dbyte<<i)&0x80)        
                SID=1;                        
                else
                SID=0;
                SCLK = 1;
       SCLK = 0;
     }
         CS=0;
}

void Lcd_WriteCmd(unsigned char Cbyte )                   //LCD的数据与指令传送
{
     delay(10);
     SendByte(0xf8);           
     SendByte(0xf0&Cbyte);      
     SendByte(0xf0&(Cbyte<<4));   
}

void Lcd_WriteData(unsigned char Dbyte )
{
     delay(10);
     SendByte(0xfa);               
     SendByte(0xf0&Dbyte);      
     SendByte(0xf0&(Dbyte<<4));   
}                                                                  
void InitLCD()                                    //LCD初始化
{
        Lcd_WriteCmd(0x30);              
        Lcd_WriteCmd(0x06);               
        Lcd_WriteCmd(0x0c);               
        Lcd_WriteCmd(0x04);              
        Lcd_WriteCmd(0x01);                    
        Lcd_WriteCmd(0x02);                          
        Lcd_WriteCmd(0x80);                 
}                                                               
void xianshi(unsigned char x,unsigned char y,unsigned char *stri)        //LCD数据传送地址
{                                                               
        if(x==1)      Lcd_WriteCmd(0x80+y-1);               
        else if(x==2) Lcd_WriteCmd(0x90+y-1);
        else if(x==3) Lcd_WriteCmd(0x88+y-1);
        else if(x==4) Lcd_WriteCmd(0x98+y-1);        
while(*stri>0)
        {
                Lcd_WriteData(*stri);
                stri++;
        }        
}
//****************************************************

void delayp()                         //延迟函数
{;;}


void delay_1ms(uint z)  
{  
    uint x,y;  
    for(x=z;x>0;x--)  
        for(y=110;y>0;y--)  
            ;  
}  
//****************************************I2C协议  
void start()//开始信号  
{  
    SDA=1;  
    delayp();  
    SCL=1;  
    delayp();  
    SDA=0;  
    delayp();  
}  

void stop() //停止信号  
{  
    SDA=0;  
    delayp();  
    SCL=1;  
    delayp();  
    SDA=1;  
    delayp();  
}  


void respons()//应答    相当于一个智能的延时函数  
{  
    uchar i;  
    SCL=1;  
    delayp();  
    while((SDA==1)&&(i<250))  
        i++;  
    SCL=0;  
    delayp();  
}  

void init() //初始化  
{  
    SDA=1;  
    delayp();  
    SCL=1;  
    delayp();      
}  

void write_byte(uchar date) //写一字节数据  
{  
    uchar i,temp;  
    temp=date;  
    for(i=0;i<8;i++)  
    {  
        temp=temp<<1; //左移一位 移出的一位在CY中  
        SCL=0;          //只有在scl=0sda能变化值  
        delayp();  
        SDA=CY;  
        delayp();  
        SCL=1;  
        delayp();         
    }     
    SCL=0;  
    delayp();  
    SDA=1;  
    delayp();  
}  



void write_add(uchar date)            //D/A转换
{  
    start();  
    write_byte(0x90);   
    respons();  
    write_byte(0x40);  
    respons();  
    write_byte(date);  
    respons();  
    stop();  

}  
//****************************************************

int main()//************************************************主函数
{
    TMOD = 0x01;
        TH0 = (65536-99000/n)/256;             //定时时间
        TL0 = (65536-99000/n)%256;
        TH1 = (65536-5000)/256;
        TL1 = (65536-5000)%256;
        EA = 1;
        ET0 = 1;
        ET1 = 1;
        TR0 = 1;
        TR1 = 1;        
    init();                                    
    while(1)
  {               
                PSB=0;
                InitLCD();
//*******************************************显示模块
for(u=0;u<9;u++)
{
        xianshi(1,1,"信号发生器");
                xianshi(2,1,"波形:");

        if(bx_chang==0)                xianshi(2,4,"sin");
        if(bx_chang==1)                       xianshi(2,4,"Square");
        if(bx_chang==2)                       xianshi(2,4,"Triangle");
        if(mode==0)               
{
                xianshi(3,1,"幅度:");
                       Lcd_WriteData(0x30+(fd*5/10));
                xianshi(3,5,".");
                      Lcd_WriteData(0x30+(fd*5%10));
                xianshi(3,6,"V");
                                        }
              if(mode==1)               
{
                xianshi(3,1,"频率:");
                        Lcd_WriteData(0x30+(n/2/100));
                            Lcd_WriteData(0x30+(n/2/10));
                            Lcd_WriteData(0x30+(n/2%10));
                        xianshi(3,8,"HZ");
                                        }                    
  }
  }
}

//**************************************************************8     
void refresh_f( void ) interrupt 1           //定时器中断
{

  if(n>=0&&n<40)
{        x=14;
        TH0 = (65536-92900/n)/256;         
        TL0 = (65536-92900/n)%256;
        }
  else if (n>=40&&n<80)
{        x=15;
        TH0 = (65536-97920/n)/256;         
        TL0 = (65536-97920/n)%256;
        }


//*************************************正弦波形                     
     a=a+x;
               if(a<256&&bx_chang==0)
                {
              write_add(tosin[a]*0.1*fd);  

                 }
                if(a>=256)
                       {
                          a=0;
                         }

//************************************方波波形

        b=b+x;
                  if(b<128&&bx_chang==1)
        {
              write_add(0x00*0.1*fd);  

        }
        if(b>=128&&b<256&&bx_chang==1)
                   write_add(0xff*0.1*fd);
        if(b>=256)
        {
           b=0;
        }




//*************************************三角波波形
         c=c+x;

                  if(c<128&&bx_chang==2)

        {                          

                write_add(c*0.2*fd);  
         }
         if(c>=128&&c<256&&bx_chang==2)   
         write_add((-c+256)*0.2*fd);  


        if(c>=256)
        {
           c=0;
        }

}
//********************************************定时器中断   按键中断
void refresh_zd( void ) interrupt 3
{

        TH1 = (65536-5000)/256;                   //5000us
        TL1 = (65536-5000)%256;
//*******************************************8
        if(p32==0)                  //频率或者幅度调节选择
                {

                     delay_1ms(1000);
                         if(p32==0)
                         mode=mode+1;
                         if(mode>=2)
                         mode=0;

                }
         if(p20==0)                  //波形选择
                 {
                   delay_1ms(1000);
                   bx_chang=bx_chang+1;
                   if(bx_chang>=3)
                   bx_chang=0;

                 }
//*******************************************频率调节
                 if(p21==0&&mode==1)
                 {
                   delay_1ms(1000);
                   n=n+2;
                   if(n>=120)
                   n=1;

                 }   
                 if(p22==0&&mode==1)
                 {
                   delay_1ms(1000);
                   n=n-2;
                   if(n<=0)
                   n=120;

                 }
//*******************************************幅度调节
                 if(p21==0&&mode==0)
                 {
                   delay_1ms(1000);
                   fd=fd+1;
                   if(fd>=10)
                   fd=1;

                 }   
                 if(p22==0&&mode==0)
                 {
                   delay_1ms(1000);
                   fd=fd-1;
                   if(fd<=1)
                   fd=10;

                 }
}


图片1.png

波形发生器.doc

245.21 KB, 下载次数: 30, 下载积分: 黑币 -5

附录 2 程序代码.doc

19.23 KB, 下载次数: 26, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:253767 发表于 2019-11-7 08:03 | 显示全部楼层
谢谢分享!!!
回复

使用道具 举报

ID:662861 发表于 2019-12-12 22:43 | 显示全部楼层
我怎么没有显示波形呢大佬
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表