程序運行正確,電路可以顯示正常的正弦波,方波的占空比設置不對,顯示成了矩形波的樣子,頻率也只在50KHZ-3MHZ之間有波形,高了低了都會失真
希望哪位大神可以幫忙看著是哪里出了問題,虛心請教
單片機源程序如下:
- #include"reg51.h"
- #include <intrins.h> //編譯預處理命令
- #define LCD_GO_HOME 0x02 //AC=0,光標、畫面回HOME位
- //輸入方式設置
- #define LCD_AC_AUTO_INCREMENT 0x06 //數據讀、寫操作后,AC自動增一
- #define LCD_AC_AUTO_DECREASE 0x04 //數據讀、寫操作后,AC自動減一
- #define LCD_MOVE_ENABLE 0x05 //數據讀、寫操作,畫面平移
- #define LCD_MOVE_DISENABLE 0x04 //數據讀、寫操作,畫面不動
- //設置顯示、光標及閃爍開、關
- #define LCD_DISPLAY_ON 0x0C //顯示開
- #define LCD_DISPLAY_OFF 0x08 //顯示關
- #define LCD_CURSOR_ON 0x0A //光標顯示
- #define LCD_CURSOR_OFF 0x08 //光標不顯示
- #define LCD_CURSOR_BLINK_ON 0x09 //光標閃爍
- #define LCD_CURSOR_BLINK_OFF 0x08 //光標不閃爍
- //光標、畫面移動,不影響DDRAM
- #define LCD_LEFT_MOVE 0x18 //LCD顯示左移一位
- #define LCD_RIGHT_MOVE 0x1C //LCD顯示右移一位
- #define LCD_CURSOR_LEFT_MOVE 0x10 //光標左移一位
- #define LCD_CURSOR_RIGHT_MOVE 0x14 //光標右移一位
- //工作方式設置
- #define LCD_DISPLAY_DOUBLE_LINE 0x38 //兩行顯示
- #define LCD_DISPLAY_SINGLE_LINE 0x30 //單行顯示
- void LCD_cls(void);
- void LCD_write_data(unsigned char);
- void LCD_initial(void);
- void LCD_set_position(unsigned char);
- void LCD_prints(unsigned char *);
- void LCD_printc(unsigned char);
- #define LCD_DATA P0 //LCD的數據口
- sbit LCD_BUSY=LCD_DATA^7; //LCD忙信號位
- sbit LCD_RS=P2^5; //LCD寄存器選擇
- sbit LCD_RW=P2^6; //LCD讀寫控制
- sbit LCD_EN=P2^7; //LCD使能信號*/
- extern void _nop_ (void);
- unsigned char s; //無符號
- char code tab[4][4]={ {'1','2','3','A'},
- {'4','5','6','B'},
- {'7','8','9','C'},
- {'*','0','#','D'}}; //0到F的16個鍵植
- ////////////////////////////////////////////////////////////////////
- //---------------------------------------------------//
- // 程序 //
- //---------------------------------------------------//
- sbit ad9850_w_clk =P1^2; //P2.2口接ad9850的w_clk腳/PIN7
- sbit ad9850_fq_up =P1^1; //P2.1口接ad9850的fq_up腳/PIN8
- sbit ad9850_rest =P1^0; //P2.0口接ad9850的rest腳/PIN12
- sbit ad9850_bit_data =P1^3; //P1.7口接ad9850的D7腳/PIN25
- //***************************************************//
- // ad9850復位(串行模式) //
- //---------------------------------------------------//
- void ad9850_reset_serial()
- {
- ad9850_w_clk=0;
- ad9850_fq_up=0;
- //rest信號
- ad9850_rest=0;
- ad9850_rest=1;
- ad9850_rest=0;
- //w_clk信號
- ad9850_w_clk=0;
- ad9850_w_clk=1;
- ad9850_w_clk=0;
- //fq_up信號
- ad9850_fq_up=0;
- ad9850_fq_up=1;
- ad9850_fq_up=0;
- }
- //***************************************************//
- // 向ad9850中寫命令與數據(串行) //
- //---------------------------------------------------//
- void ad9850_wr_serial(unsigned char w0,double frequence)
- {
- unsigned char i,w;
- long int y;
- double x;
- //計算頻率的HEX值
- x=4294967295/125;//適合125M晶振
- //如果時鐘頻率不為180MHZ,修改該處的頻率值,單位MHz !!!
- frequence=frequence/1000000;
- frequence=frequence*x;
- y=frequence;
- //寫w2數據
- w=(y>>8);
- for(i=0;i<8;i++)
- {
- ad9850_bit_data=(w>>i)&0x01;
- ad9850_w_clk=1;
- ad9850_w_clk=0;
- }
- //寫w1數據
- w=(y>>24);
- for(i=0;i<8;i++)
- {
- ad9850_bit_data=(w>>i)&0x01;
- ad9850_w_clk=1;
- ad9850_w_clk=0;
- }
- //寫w0數據
- w=w0;
- for(i=0;i<8;i++)
- {
- ad9850_bit_data=(w>>i)&0x01;
- }
- }
- //////////////////////////////////////////////////////////////////////
- void LCD_check_busy(void) //檢測LCD狀態,看它是不是還在忙呢
- {
- while(1)
- {
- LCD_EN=0;
- LCD_RS=0;
- LCD_RW=1;
- LCD_DATA=0xff;
- LCD_EN=1;
- if(!LCD_BUSY)break;
- }
- LCD_EN=0;
- }
- void LCD_cls(void) //LCD清屏
- {
- LCD_check_busy();
- LCD_RS=0;
- LCD_RW=0;
- LCD_DATA=1;
- LCD_EN=1;
- LCD_EN=0;
- }
- void LCD_write_instruction(unsigned char LCD_instruction) //寫指令到LCD
- {
- LCD_check_busy();
- LCD_RS=0;
- LCD_RW=0;
- LCD_DATA=LCD_instruction;
- LCD_EN=1;
- LCD_EN=0;
- }
- void LCD_write_data(unsigned char LCD_data) //輸出一個字節數據到LCD
- {
- LCD_check_busy();
- LCD_RS=1;
- LCD_RW=0;
- LCD_DATA=LCD_data;
- LCD_EN=1;
- LCD_EN=0;
- }
- void LCD_set_position(unsigned char x) //LCD光標定位到x處
- {
- LCD_write_instruction(0x80+x);
- }
- /*
- void LCD_go_home(void) //LCD光標歸位
- {
- LCD_write_instruction(LCD_GO_HOME);
- }
- */
- void LCD_printc(unsigned char lcd_data) //輸出一個字符到LCD
- {
- LCD_write_data(lcd_data);
- }
- void LCD_prints(unsigned char *lcd_string) //輸出一個字符串到LCD
- {
- unsigned char i=0;
- while(lcd_string[i]!=0x00)
- {
- LCD_write_data(lcd_string[i]);
- i++;
- }
- }
- void LCD_initial(void) //初始化LCD
- {
- LCD_write_instruction(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
- LCD_write_instruction(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
- LCD_write_instruction(LCD_DISPLAY_DOUBLE_LINE);
- LCD_cls();
- }
- void delay(unsigned char a)
- {
- unsigned char i;
- while(a--)
- for(i=100;i>0;i--)
- ;
- }
- char kbscan() //鍵盤掃描
- {
- unsigned char hang,lie,key;
- if(P3!=0x0f)
- delay(5);
- if(P3!=0x0f)
- {
-
- switch(P3&0x0f)
- {
- case 0x0e:hang=3;break;
- case 0x0d:hang=2;break;
- case 0x0b:hang=1;break;
- case 0x07:hang=0;break;
- }
- P3=0xf0;
- P3=0xf0;
- switch(P3&0xf0)
- {
- case 0xe0:lie=0;break;
- case 0xd0:lie=1;break;
- case 0xb0:lie=2;break;
- case 0x70:lie=3;break;
- }
- P3=0x0f;
- while(P3!=0x0f);
- key=tab[hang][lie];
- }
- else
- key=0;
- return (key);
- }
- void main()
- {
- unsigned char temp[10];
- unsigned int shuzi[10];
- long int f=10000;
- s=0;
- LCD_initial();
- LCD_prints("SET Frequence:");
- LCD_set_position(0x4E);
- LCD_printc('H');
- LCD_set_position(0x4f);
- LCD_printc('z');
- //LCD_cls();
- P3=0x0f;
- P0=0xff;
- //---------------------------------------------------//
- ad9850_reset_serial();
- //ad9850_wr_serial(0x00,2500);//串行寫2500Hz程序
- //---------------------------------------------------//
- while(1)
- {
-
- ad9850_wr_serial(0x00,f);
- temp[s]=kbscan();
- shuzi[s]=temp[s]-48;
-
- if(s==1)
- {
- f=shuzi[0];
- }
- if(s==2)
- {
- f=shuzi[1]+10*shuzi[0];
- }
- if(s==3)
- {
- f=shuzi[2]+10*shuzi[1]+100*shuzi[0];
- //shuzi[3]+10*shuzi[2]+100*shuzi[1]+1000*shuzi[0];
- }
- if(s==4)
- {
- f=shuzi[3]+10*shuzi[2]+100*shuzi[1]+1000*shuzi[0];
- }
- if(s==5)
- {
- f=shuzi[4]+10*shuzi[3]+100*shuzi[2]+1000*shuzi[1]+10000*shuzi[0];
- }
- if(s==6)
- {
- f=shuzi[5]+10*shuzi[4]+100*shuzi[3]+1000*shuzi[2]+10000*shuzi[1]+100000*shuzi[0];
- }
- if(s==7)
- {
- f=shuzi[6]+10*shuzi[5]+100*shuzi[4]+1000*shuzi[3]+10000*shuzi[2]+100000*shuzi[1]+1000000*shuzi[0];
- }
- if(s==8)
- {
- f=shuzi[7]+10*shuzi[6]+100*shuzi[5]+1000*shuzi[4]+10000*shuzi[3]+100000*shuzi[2]+1000000*shuzi[1]+10000000*shuzi[0];
- }
- s=0;
- shuzi[0]=0;shuzi[1]=0;shuzi[2]=0;shuzi[3]=0;shuzi[4]=0;
- shuzi[5]=0;shuzi[6]=0;shuzi[7]=0;shuzi[8]=0;shuzi[9]=0; }
- else
- {
- P0=temp[s];
- LCD_set_position(0x40+s);
- LCD_printc(temp[s]);
- s=s+1;
- }
- }
- }
- }
復制代碼
|