程序源碼
附錄 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=0時sda能變化值 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;
} }
|