|
不是一般的pwm控制,就是幾個(gè)AD/DA的轉(zhuǎn)換,用三極管放大控制電樞電流..........第一次寫這種幾百行的大程序感覺好難啊
問(wèn)題是在proteus上調(diào)試發(fā)現(xiàn)速度只能加,設(shè)置速度比實(shí)際速度小的時(shí)候就不能降速了,代碼也不能發(fā)現(xiàn)問(wèn)題,來(lái)求助大家
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
調(diào)速.png (278.03 KB, 下載次數(shù): 37)
下載附件
2019-12-31 19:32 上傳
以下是單片機(jī)代碼
- #include <reg52.h>
- #define digital P0 //DAC0832 數(shù)據(jù)管腳
- #define leddat P1 //數(shù)碼管數(shù)據(jù)管腳
- #define en 1 //電機(jī)一圈的脈沖數(shù) 根據(jù)電機(jī)實(shí)際參數(shù)設(shè)定
- #define uint unsigned int
- #define uchar unsigned char
- #define ufloat unsigned float
- sbit scl=P3^5;
- sbit sda=P3^7;
- sbit Y3 = P3^0; //數(shù)碼管段選腳定義
- sbit Y2 = P3^1;
- sbit Y1 = P3^2;
- sbit Y0 = P3^3;
- sbit Y7 = P2^0; //數(shù)碼管段選腳定義
- sbit Y6 = P2^1;
- sbit Y5 = P2^2;
- sbit Y4 = P2^3;
- sbit LSA = P2^4; //138譯碼器管腳定義
- sbit LSB = P2^5;
- sbit LSC = P2^6;
- sbit LSG1 = P2^7;
- char code Led_dat[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共陰數(shù)碼管段碼 0123456789
- long double speed=0;
- long int count=0; //記錄脈沖數(shù)量
- void Delay10us()
- {
- unsigned char a,b;
- for(b=1;b>0;b--)
- for(a=2;a>0;a--);
- }
- void delay() //延時(shí)幾微秒。延時(shí)函數(shù)在很多函數(shù)里都要用它。至少要大于4.7us
- {;;} //當(dāng)你把這個(gè)函數(shù)寫在用它這個(gè)函數(shù)的前面就不用聲明了
- void init() //初始化總線。將總線都拉高以釋放
- {
- scl=1;
- delay(); //I2C總線使用時(shí)一般都要延時(shí)5us左右
- sda=1;
- delay();
- }
- void start() //啟始信號(hào)。 時(shí)鐘信號(hào)為高電平期間,數(shù)據(jù)總線產(chǎn)生下降沿。
- { //為什么要下降沿,且sda先要為1。因?yàn)橄纫WC數(shù)據(jù)線為空才能工作
- sda=1; //先釋放數(shù)據(jù)總線。高電平釋放
- delay();
- scl=1;
- delay();
- sda=0;
- delay();
- }
- void stop()
- {
- sda=0; //先要有工作狀態(tài)才能釋放,sda=0時(shí)在工作狀態(tài)
- delay();
- scl=1;
- delay();
- sda=1; //釋放數(shù)據(jù)總線
- delay();
- }
- void respons() //應(yīng)答函數(shù)
- {
- uchar i=0;
- scl=1; //每個(gè)字節(jié)發(fā)送完后的第九個(gè)時(shí)鐘信號(hào)的開始
- delay();
- while((sda==1)&&(i<255)) //此處i的定義使用了uchar.只要填一個(gè)小于255的就行
- i++; //此處的sda是從機(jī)的
- scl=0; //表示主器件默認(rèn)從器件已經(jīng)收到而不再等待。不再等待之后,時(shí)鐘的高電平過(guò)了就是低電平,所以scl=0
- //此時(shí)第酒個(gè)時(shí)鐘信號(hào)結(jié)束
- }
- void writebyte(uchar d) //寫一字節(jié),每次左移一位
- {
- uchar i,temp;
- temp=d;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0; //數(shù)據(jù)傳輸期間要想sda可變,先把時(shí)鐘拉低。此處要給sda賦值
- delay();
- sda=CY; //CY為左移移入PSW寄存器中的的CY位。
- delay();
- scl=1; //sda有數(shù)據(jù)了。保持?jǐn)?shù)據(jù)穩(wěn)定
- delay();
- }
- scl=0; //此處是寫數(shù)據(jù),是屬于數(shù)據(jù)傳輸過(guò)程中。只有在時(shí)鐘信號(hào)為低電平期間
- delay(); //數(shù)據(jù)總線才可以變化。
- sda=1; //所以要想釋放數(shù)據(jù)總線,就必須先把時(shí)鐘拉低
- delay();
- /*此處釋放總線寫在末尾是因?yàn)檎{(diào)用它時(shí),前面有起始函數(shù)釋放了總線*/
- }
- uchar readbyte()
- {
- uchar i,k;
- scl=0;
- delay();
- sda=1;
- delay();
- /*此處釋放總線放在前面是因?yàn)橐话愣际窍葘懞笞x,保險(xiǎn)起見,釋放一下總線*/
- for(i=0;i<8;i++)
- {
- scl=1; //一個(gè)時(shí)鐘信號(hào)的開始
- delay();
- k=(k<<1)|sda; //實(shí)質(zhì)是把sda的數(shù)據(jù),最先傳來(lái)的放在最高位,依次往下排
- scl=0; //一個(gè)時(shí)鐘信號(hào)結(jié)束
- delay();
- }
- return k;
- }
- void write(uchar addr,uchar dat)
- {
- start(); //初始化
- writebyte(0x90); //調(diào)用寫一字節(jié)函數(shù).PCF8591為1001。此處是給從機(jī)發(fā)送寫信號(hào)(最低位是0)
- respons(); //調(diào)用應(yīng)答函數(shù)讓從機(jī)應(yīng)答
- writebyte(addr); //寫入地址
- respons(); //每寫一字節(jié)都要應(yīng)答
- writebyte(dat);
- respons();
- stop();
- }
- uchar read(uchar addr)
- {
- uchar dat;
- start();
- writebyte(0x90); //從此處的發(fā)送地址和方向位0到從機(jī)
- respons(); //此處的從機(jī)產(chǎn)生應(yīng)答。屬于“偽寫”。用于確定和哪臺(tái)機(jī)子通信
- writebyte(addr);
- respons();
- start();
- writebyte(0x91); //從此處開始,從機(jī)向主機(jī)寫數(shù)據(jù)。讀的方向位為1
- respons();
- dat=readbyte();
- stop();
- return dat; //讀得的數(shù)據(jù)要返回
- }
- void delay1(int i) //延時(shí)函數(shù)
- {
- while(i--);
- }
- void display(int x,int y) //數(shù)碼管操作函數(shù)
- {
- delay1(100);
- leddat = ~0x00; //清屏消隱
- Y0=0;Y1=1;Y2=1;Y3=1;Y4=1;Y5=1;Y6=1;Y7=1; //段選1
- leddat = ~Led_dat[x%10]; //取余數(shù) 取出個(gè)位數(shù)
-
- delay1(100);
- leddat = ~0x00;
- Y0=1;Y1=0;Y2=1;Y3=1;Y4=1;Y5=1;Y6=1;Y7=1; //段選2
- leddat = ~Led_dat[x/10%10]; //取出十位數(shù)
-
- delay1(100);
- leddat = ~0x00;
- Y0=1;Y1=1;Y2=0;Y3=1;Y4=1;Y5=1;Y6=1;Y7=1; //段選3
- leddat = ~Led_dat[x/100%10]; //取出百位數(shù)
-
- delay1(100);
- leddat = ~0x00;
- Y0=1;Y1=1;Y2=1;Y3=0;Y4=1;Y5=1;Y6=1;Y7=1; //段選4
- leddat = ~Led_dat[x/1000]; //取出千位數(shù)
-
- delay1(100);
- leddat = ~0x00; //清屏消隱
- Y0=1;Y1=1;Y2=1;Y3=1;Y4=0;Y5=1;Y6=1;Y7=1; //段選5
- leddat = ~Led_dat[y%10]; //取余數(shù) 取出個(gè)位數(shù)
-
- delay1(100);
- leddat = ~0x00;
- Y0=1;Y1=1;Y2=1;Y3=1;Y4=1;Y5=0;Y6=1;Y7=1; //段選6
- leddat = ~Led_dat[y/10%10]; //取出十位數(shù)
-
- delay1(100);
- leddat = ~0x00;
- Y0=1;Y1=1;Y2=1;Y3=1;Y4=1;Y5=1;Y6=0;Y7=1; //段選7
- leddat = ~Led_dat[y/100%10]; //取出百位數(shù)
-
- delay1(100);
- leddat = ~0x00;
- Y0=1;Y1=1;Y2=1;Y3=1;Y4=1;Y5=1;Y6=1;Y7=0; //段選8
- leddat = ~Led_dat[y/1000]; //取出千位數(shù)
- }
- void timerInit()
- {
- TMOD=0x15; //模式設(shè)置,00000001
- TR0=1; //打開計(jì)數(shù)器
- ET0=1; //開計(jì)數(shù)器0中斷
-
- TR1=1; //打開計(jì)數(shù)器
- ET1=1; //開計(jì)數(shù)器0中斷
- TH1=(65536-45872)/256; //50ms
- TL1=(65536-45872)%256;
- TH0=0;
- TL0=0;
-
- EA=1; //開總中斷
- }
- uint T0_read()
- {
- uchar tl,th1,th2;
- uint val;
- while(1)
- {
- th1=TH0;
- tl=TL0;
- th2=TH0;
- if(th1==th2)
- break;
- }
- val=th1*256+tl;
- return val;
- }
- void main()
- {
- double dat = 0;
- int dig=0;
- int i;
- int x_speed=150; //速度增量
-
- LSA = 0; //138譯碼器 YC2輸出低
- LSB = 1;
- LSC = 0;
- LSG1 = 1;
- WR = 0; //打開dac0830轉(zhuǎn)換 WR輸出低
- timerInit();
- while(1)
- {
- dat=read(0x00);
- dat = (dat*67)/255 + 17; //設(shè)定的每秒轉(zhuǎn)速 17~84r/s 對(duì)應(yīng) 1020~5040r/min
-
- speed = count/en; //當(dāng)前速度
-
- if(speed < dat) x_speed+=1; //如果實(shí)際速度小于設(shè)定速度 速度增量加
- else x_speed-=1; //反之則減
- if(x_speed > 255)x_speed = 255; //速度增量最大255 最小0
- if(x_speed < 0) x_speed = 0;
- digital =x_speed; //電機(jī)輸出速度為 設(shè)定速度加上速度增量
-
- i=10;
- while(i--)
- {
- i--;
- display(speed*60,dat*60); //顯示當(dāng)前速度 每分鐘轉(zhuǎn)速
- }
-
- }
- }
- void timer_T1() interrupt 3 //定時(shí)器中斷
- {
- static int i = 0;
- TH1=(65536-45872)/256; //50ms
- TL1=(65536-45872)%256;
- i++;
- if(i>=20) //20*50=1000ms 定時(shí)1s
- {
- TR0=0; //關(guān)閉計(jì)數(shù)器 記錄脈沖數(shù)量
- count=T0_read();
- TH0=0;
- TL0=0;
- i=0; //脈沖清零 重新開始計(jì)數(shù)
- TR0=1;
- }
- }
復(fù)制代碼 全部資料51hei下載地址:
調(diào)速.zip
(115.21 KB, 下載次數(shù): 14)
2019-12-31 19:24 上傳
點(diǎn)擊文件名下載附件
|
|