欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
單片機垂直起降控制程序 PWM輸出,PCF8591讀取角度
[打印本頁]
作者:
liusang
時間:
2020-12-13 09:09
標題:
單片機垂直起降控制程序 PWM輸出,PCF8591讀取角度
垂直起降懸臂控制,代碼可以實現指定角度懸停,采用PWM輸出,PCF8591讀取角度,八位數碼管顯示設定角度與實時角度。
單片機源程序如下:
#include<reg52.h>
#include<intrins.h>
#define DataPort P0
#define CYCLE 10
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
void Display(unsigned char FirstBit,unsigned char Num);
void PWMOUT();
void wucha();
void scan();
void xianshi();
void DelayUs2x(unsigned char t);//us級延時函數聲明
void DelayMs(unsigned char t); //ms級延時
void Init_Timer0(void);
bit flag_300ms = 0;
sbit LATCH1=P2^2;
sbit LATCH2=P2^3;
sbit K1 = P3^0;
sbit K2 = P3^1;
sbit PWM = P1^3;
sbit I2C_SDA = P2^1;
sbit I2C_SCL = P2^0;//I2C通信的兩個引腳
uint8 AD_value = 0;//AD值
key=0;
TempData[8];
angle=0;
sangle=0;
Proportion=1.5;
Integral=0;
Derivative=0;
Error;
LastError;
PrevError;
out=20;
count=0;
uint8 get_ADC_vaule(uint8 chn);
code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 顯示段碼值0~9
code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分別對應相應的數碼管點亮,即位碼
void main()
{
Init_Timer0();
while(1)
{
xianshi();
scan();
wucha();
xianshi();
}
}
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延時1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
void scan()
{
P3 = 0xff;
if (P3==0xfe) key=1;
if (P3==0xfd) key=2;
if (P3==0xfb) key=3;
if (P3==0xf7) key=4;
if (P3==0xef) key=5;
if (P3==0xdf) key=6;
if (P3==0xbf) key=7;
if (P3==0x7f) key=8;
switch (key)
{
case 1:
{
sangle=0;
Proportion=3;
Integral=0;
Derivative=0;
}
break;
case 2:
{
sangle=35;
Proportion=1.7;
Integral=0.1;
Derivative=0.1;
}
break;
case 3:
{
sangle=45;
Proportion=1.85;
Integral=0;
Derivative=0;}
break;
case 4:
{
sangle=45;
Proportion=1.85;
Integral=0.2;
Derivative=0;
}
break;
case 5:
{
sangle=45;
Proportion=1.85;
Integral=0.3;
Derivative=0.1;}
break;
case 6:
{
sangle=50;
Proportion=1.5;
Integral=0;
Derivative=0;
}
break;
case 7:
{
sangle=55;
Proportion=1.8;
Integral=0.01;
Derivative=0;}
break;
case 8:
{
sangle=60;
Proportion=1.5;
Integral=0;
Derivative=0;
}
}
}
void xianshi()
{DelayMs(1);
AD_value = get_ADC_vaule(0);//讀取通道0的AD值
angle=(float)AD_value*1.41-21;
TempData[3]=dofly_DuanMa[angle%10];
TempData[2]=dofly_DuanMa[angle/10%10];
TempData[1]=dofly_DuanMa[angle/100];
TempData[7]=dofly_DuanMa[sangle%10];
TempData[6]=dofly_DuanMa[sangle/10%10];
TempData[5]=dofly_DuanMa[sangle/100];
}
void wucha()
{
angle=(float)AD_value*1.41-21;
Error=sangle-angle;
PrevError+=Error;
out=out+Proportion*Error+Integral*PrevError+Derivative*(LastError-Error);
//out=out+Proportion*(Error-LastError)+Integral*Error+Derivative*(Error+PrevError-2*LastError);
LastError=Error;
//out=50;
//out=out+Proportion*Error+Integral*Error*0.02+Derivative*Error/0.02;
if(out<0)
out=0;
if(out>100)
out=100;
}
void I2C_delay()//I2C延時函數
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void I2C_start()//I2C起始信號
{
I2C_SDA = 1;
I2C_SCL = 1;
I2C_delay();
I2C_SDA = 0;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
}
void I2C_stop()//I2C停止信號
{
I2C_SDA = 0;
I2C_SCL = 0;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
I2C_SDA = 1;
I2C_delay();
}
bit I2C_write(uint8 dat)//I2C寫一個字節
{
bit ack = 0;
uint8 mask = 0;
for(mask=0x80;mask!=0;mask>>=1)
{
if((mask&dat) == 0)
I2C_SDA = 0;
else
I2C_SDA = 1;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
}
I2C_SDA = 1;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
ack = I2C_SDA;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
return (~ack);
}
uint8 I2C_read_ACK()//I2C讀一個字節,并發送應答位
{
uint8 dat = 0;
uint8 mask = 0;
I2C_SDA = 1;
for(mask=0x80;mask!=0;mask>>=1)
{
if(I2C_SDA == 0)
dat = dat & (~mask);
else
dat = dat | mask;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
}
I2C_SDA = 0;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
return dat;
}
uint8 I2C_read_NACK()//I2C讀一個字節,并發送非應答位
{
uint8 dat = 0;
uint8 mask = 0;
I2C_SDA = 1;
for(mask=0x80;mask!=0;mask>>=1)
{
if(I2C_SDA == 0)
dat = dat & (~mask);
else
dat = dat | mask;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
}
I2C_SDA = 1;
I2C_delay();
I2C_SCL = 1;
I2C_delay();
I2C_SCL = 0;
I2C_delay();
return dat;
}
uint8 get_ADC_vaule(uint8 chn)//獲取AD值
{
uint8 value;
I2C_start();//I2C起始信號
if(!I2C_write(0X90))//寫入PCF8591地址及讀寫選擇位為寫
{
I2C_stop();
return 0;
}
I2C_write(0X40 | chn);//寫入PCF8591通道0
I2C_write(0x00 | chn);//寫入PCF8591通道0
I2C_start();//I2C起始信號
I2C_write(0x48<<1 | 0x01);
I2C_read_ACK();//提供轉換所需的時鐘信號
value = I2C_read_NACK();//讀取上一次轉換的結果
I2C_stop();//I2C結束信號
return value;
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=0x00; //給定初值
TL0=0x00;
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關打開
}
void Timer0_isr(void) interrupt 1
{
static unsigned char count;
TH0=(65536-10)/256; //重新賦值 2ms
TL0=(65536-10)%256;
Display(0,8); // 調用數碼管掃描
count++;
if (count<out)
PWM= 1;
else
PWM=0;
if(count==100)
count= 0;
}
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0;
DataPort=0; //清空數據,防止有交替重影
LATCH1=1; //段鎖存
LATCH1=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位碼
LATCH2=1; //位鎖存
LATCH2=0;
DataPort=TempData[i]; //取顯示數據,段碼
LATCH1=1; //段鎖存
LATCH1=0;
i++;
if(i==Num)
i=0;
}
復制代碼
全部程序51hei下載地址:
第四次.rar
(40.58 KB, 下載次數: 16)
2020-12-13 09:06 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
51hei團團
時間:
2020-12-13 16:52
沒有原理圖 樓主能分享一下嗎?
作者:
啤酒瓶子老大
時間:
2020-12-13 19:37
我是小白,看過很多設計。看了你的設計,我沒明白的是用讀取電位器角度。沒搞錯吧。你設計的是一個飛機啊。難道你要在飛機的電位器上掛個重錘?來讀取電位器的角度?
作者:
liusang
時間:
2020-12-16 20:57
啤酒瓶子老大 發表于 2020-12-13 19:37
我是小白,看過很多設計?戳四愕脑O計,我沒明白的是用讀取電位器角度。沒搞錯吧。你設計的是一個飛機啊。 ...
阿。這就是一個小diy作品,就控制了單個懸臂
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1