|
#i nclude //此程序?qū)崿F(xiàn)"數(shù)控步進(jìn)直流穩(wěn)壓電源"的功能,調(diào)試時(shí)為了避免資源沖突,應(yīng)使實(shí)驗(yàn)板上 的拔碼開 關(guān)S8拔向高電平 //本程序設(shè)定S9鍵為增加鍵,當(dāng)按住S9鍵不松開時(shí),輸出Vout以0.1V連續(xù)步進(jìn), //直至鍵S9松開,當(dāng)以一定的時(shí)間間隔點(diǎn)動(dòng)S9鍵時(shí),輸出Vout也為點(diǎn)動(dòng)步進(jìn) //遞減鍵S11的功能與S9基本相同時(shí),輸出電壓的值顯示在3個(gè)LED上 unsigned char R1,R2,R3,TXDATA,LEDF,BJF,COUNTW,data; unsigned int i; const char table[11]={0xc0,0xf9,0xa4,0xb0,0x99, 0x92, 0x82 ,0XD8,0x80,0x90,0xFF}; //不帶小數(shù)點(diǎn)的顯示段碼表 const char table0[11]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10, 0xFF}; //帶小數(shù)點(diǎn)的的顯示段碼表 unsigned char s[4]; //定義一個(gè)顯示緩沖數(shù)組 //把需要顯示的數(shù)字裝入顯示緩沖數(shù)組 void sfz() { s[0]=R3; s[1]=R2; s[2]=R1; s[3]=0x0A; //最后一個(gè)LED顯示"DARK" } //系統(tǒng)各寄存器初始化子程序 void initial() { R1=0X00; R2=0X00; R3=0X00; sfz(); //把需要顯示的數(shù)字裝入顯示緩沖數(shù)組 TXDATA=0X00; LEDF=0X01; BJF=0X01; TRISB1=0; TRISB2=0; TRISB4=1; TRISB5=1; //設(shè)置與鍵盤相關(guān)的各口的輸入輸出方式 RB1=0; RB2=0; //設(shè)置掃描初始條件 } //spi方式顯示初始化子程序 void SPIINIT() { PIR1=0; SSPCON=0x30; SSPSTAT=0xC0; //設(shè)置SPI的控制方式,允許SSP方式,并且時(shí)鐘下降沿發(fā)送,與"74HC595,當(dāng)其 //SCLK從低到高跳變時(shí),串行輸入寄存器"的特點(diǎn)相對(duì)應(yīng) TRISC=0xD7; //SDO引腳為輸出,SCK引腳為輸出 TRISA5=0; //RA5引腳設(shè)置為輸出,以輸出顯示鎖存信號(hào) } //I2C初始化子程序 void i2cint() { SSPCON = 0X08; //初始化SSPCON寄存器 TRISC3 =1; //設(shè)置SCL為輸入口 TRISC4 =1; //設(shè)置SDA為輸入口 TRISA4 = 0; SSPSTAT=0X80; //初始化SSPSTAT寄存器 SSPADD=0X02; //設(shè)定I2C時(shí)鐘頻率 SSPCON2=0X00; //初始化SSPCON2寄存器 di(); //關(guān)閉總中斷 SSPIF=0; //清SSP中斷標(biāo)志 RA4=0; //關(guān)掉74HC165的移位時(shí)鐘使能,以免74HC165 //移位數(shù)據(jù)輸出與I2C總線的數(shù)據(jù)線發(fā)生沖突 SSPEN=1; //SSP模塊使能 } //軟件延時(shí)子程序 void DELAY() { for(i = 3553; --i ;) continue; } //鍵服務(wù)子程序 void keyserve() { PORTB=0XFD ; if(RB5==0) BJF=0X01; //S9鍵按下,步進(jìn)加標(biāo)志置1 PORTB=0XFB ; if(RB5==0) BJF=0X00; //S11鍵按下,步進(jìn)加標(biāo)志清0 RB1=0; //恢復(fù)PORTB的值 RB2=0; } //鍵掃描子程序 void KEYSCAN() { while(1){ while(1) { if (RB5==0) break; } DELAY(); //若有鍵按下,則軟件延時(shí) if (RB5==0)break; //若還有鍵按下,則終止循環(huán)掃描,返回 } } //SPI傳送數(shù)據(jù)子程序 void SPILED(data) { SSPBUF=data; // 啟動(dòng)發(fā)送 do { ; }while(SSPIF==0); SSPIF=0; } //顯示子程序 void display() { SPIINIT(); //spi方式顯示初始化 RA5=0; //準(zhǔn)備鎖存 for(COUNTW=0;COUNTW<4;COUNTW++) { data=s[COUNTW]; if(COUNTW==1) data=table0[data];//第二位需要顯示小數(shù)點(diǎn) else data=table[data]; SPILED(data); //發(fā)送顯示段碼 } for(COUNTW=0;COUNTW<4;COUNTW++){ data=0xFF; SPILED(data); //連續(xù)發(fā)送4個(gè)DARK,使顯示看起來(lái)好看一些 } RA5=1; //最后給一個(gè)鎖存信號(hào),代表顯示任務(wù)完成 } //I2C總線輸出數(shù)據(jù)子程序 void i2cout() { i2cint(); //因?yàn)镾PI輸出和I2C輸出不能同時(shí)工作,則需要 //不斷在兩種方式見(jiàn)切換 SEN=1; //產(chǎn)生I2C啟動(dòng)信號(hào) for(i=0x02;--i;) continue; //給予一定的延時(shí),保證啟動(dòng) do { RSEN=1; //產(chǎn)生I2C啟動(dòng)信號(hào) }while(SSPIF==0); //如果沒(méi)能啟動(dòng),則反復(fù)啟動(dòng),直到啟動(dòng)為止 SSPIF=0; //SSPIF標(biāo)志清0 SSPBUF=0X58; //I2C總線發(fā)送地址字節(jié) do { ; }while(SSPIF==0); //等待地址發(fā)送完畢 SSPIF=0; //SSPIF標(biāo)志清0 SSPBUF=0X01; //I2C總線發(fā)送命令字節(jié) do { ; }while(SSPIF==0); //等待命令發(fā)送完畢 SSPIF=0; //SSPIF標(biāo)志清0 SSPBUF=TXDATA; //I2C總線發(fā)送數(shù)據(jù)字節(jié) do { ; }while(SSPIF==0); //等待數(shù)據(jù)發(fā)送完畢 SSPIF=0; //SSPIF標(biāo)志清0 PEN=1; //產(chǎn)生停止條件 do { ; }while(SSPIF==0); //等待停止條件產(chǎn)生 SSPIF=0; //SSPIF標(biāo)志清0 } //步進(jìn)加子程序 void BJADD() { R1++; TXDATA=TXDATA+2; if(R1>9) { R1=0; R2++; if(R2>9) { R2=0; R3++; } } if((R3==1)&&(R2==2)&&(R1==1)){ R3=0; R2=0; R1=0; //若R3,R2,R1超過(guò)120,則又從0計(jì)起 TXDATA=0; } sfz(); //把需要顯示的數(shù)字裝入顯示緩沖數(shù)組 } //步進(jìn)減子程序 void BJSUB() { R1--; TXDATA=TXDATA-2; if(R1==0XFF) { R1=9; R2--; if(R2==0XFF) { R2=9; R3--; if(R3==0XFF) { R3=1; R2=2; R1=0;//若R3,R2,R1小于0,則又從120計(jì)起 TXDATA=0XF0; } } } sfz(); //把需要顯示的數(shù)字裝入顯示緩沖數(shù)組 } //主程序 main() { initial(); //系統(tǒng)各寄存器初始化 display(); //調(diào)用一次顯示子程序 while(1) { i2cout(); //調(diào)用I2C子程序,啟動(dòng)D/A轉(zhuǎn)換 KEYSCAN(); //鍵盤掃描 keyserve() ; //若確實(shí)有鍵按下,則調(diào)用鍵服務(wù)程序 if(BJF==0X01) BJADD();//若步進(jìn)加標(biāo)志為1,則調(diào)用步進(jìn)加子程序 else BJSUB(); //若步進(jìn)加標(biāo)志為0,則調(diào)用步進(jìn)減子程序 display(); //調(diào)用一次顯示子程序 } |