1)数据总线:D0--D7,
2)地址总线:A0--A15,
3)读写控制总线;
4)输入输出总线 PIO:
这些总线的外连端口,大部分是与PIO口复用;
设PIO输出低电平点亮灯,输出高电平熄灯;
while(1){
P0=0; P1=0; P2=0; P3=0; //所有灯同时亮
delay();
P0=0xff; P1=0xff; P2=0xff; P3=0xff; //所有灯同时灭
delay();
}
一般来说P1.7是高位,但有时可以不区分,如各个管脚分别驱动不同设备
另外象驱动7段数码管,你也可以倒著接,但编码也要相应改变
但对於P0 P2一定要把P0.7或P2.7当高位,否则,作为通用地址或数据线是要乱套的,除非你一点也不用别人的程序,并且也想让别人也看不懂你的程序
//P1.1(T0):Count They Distance
//P0.4:Tx
//P0.5:Rx
#include C8051F310.h //SFR declarations
#include stdio.h //Standard I/O definition file
#include math.h //Math library file
#include Intrins.h
#include absacc.h
unsigned int j,i;
char a=0;
unsigned int t=0;
//sbit led=P0^2;
//P0.0(PWM0):给定左轮速度.
sbit vls=P0^4; //P0.4(GPIO):给定左轮方向.
sbit vlf=P0^6; //P0.6(T0) :反馈左轮速度.
sbit dlf=P1^0; //P1.0(GPIO):反馈左轮方向.
//P0.2(PWM0):给定右轮速度.
sbit vrs=P0^5; //P0.5(GPIO):给定右轮方向.
sbit vrf=P0^7; //P0.7(T0) :反馈右轮速度.
sbit drf=P1^1; //P1.1(GPIO):反馈右轮方向.
int ol; //左轮给定值
int len;
int len_1,len_2;
int lyn_1,lyn_2;
int vl1,vl2; //反馈左轮速度值(取样周期内的方波数)
int lfz; //运算后赋给PWM的值
int lyn,lynn;
int lun=0,lun_1=0; //偏差校正值 即校正PWM输出
int lunp,luni,lund; //PID 校正值
int or; //右轮给定值
int ren;
int ren_1,ren_2;
int ryn_1,ryn_2;
int vr1,vr2; //反馈右轮速度值(取样周期内的方波数)
int rfz; //运算后赋给PWM的值
int ryn,rynn;
int run=0,run_1=0; //偏差校正值 即校正PWM输出
int runp,runi,rund; //PID 校正值
float kp=2.0; //比例系数1.8
float kd=0.2; //微分系数0.4
float lki; //积分系数
void pio_init(void);
void sys_init(void);
void t01_init(void);
void TIME3_INT(void);
void PID(void);
void interrupt_init(void);
void delay(unsigned int x);
void pwm1_1(void);
void main(void)
{
PCA0MD = ~0x40; //关闭
pio_init(); //P11为测距输入端
sys_init();
t01_init();
pwm1_1();
TIME3_INT();
interrupt_init();
vls=1;vrs=0;
while(1)
{
ol=50;
or=50;
delay(1000);
ol=100;
or=100;
delay(1000);
ol=-50;
or=50;
delay(1000);
}
}
void PID(void)
{
/****************左轮PID调节******************/
if(dlf==1)
{
lyn=(vl2*256+vl1); //dlf是左轮反馈方向,0表示向前 vl=TL0
}
else
{
lyn=-(vl2*256+vl1); //dlf=1表示是向后退,速度应该为负值
}
len=ol-lyn; //误差=给定速度-反馈速度(取样周期内的方波数)
if(abs(len)8)//30
{
lki=1.4; //ki值的确定1.4
}
else
{
lki=0.05; //积分系数:如果 | 给定值-反馈值 | 太大
} //则就可以不引入积分,或者引入的很小0.05
lunp=kp*(len-len_1); //比例校正
luni=lki*len; //积分校正
lund=kd*(len-2*len_1+len_2); //微分校正
lun=lunp+luni+lund+lun_1; //总校正
/*************新旧数据更新*************************/
len_2=len_1;
len_1=len; //len:当前取样周期内出现的速度偏差;len_1:上次取样周期内出现的速度偏差
lun_1=lun; //lun:当前取样周期内得出的PWM校正值;lun_1:上次取样周期内得出的PWM校正值
/*************新旧数据更新*************************/
if(lun255)
{
lun=255; //正速度
}
if(lun-255)
{
lun=-255; //负速度
}
if(lun0)
{
vls=1;
PCA0CPH0=-lun;
}
if(lun=0)
{
vls=0;
PCA0CPH0=lun;
}
/****************右轮PID调节******************/
if(drf==0)
{
ryn=(vr2*256+vr1); //drf是右轮反馈方向,0表示向前 vl=TL0
}
else
{
ryn=-(vr2*256+vr1); //dlf=1表示是向后退,速度应该为负值
}
ren=or-ryn; //误差=给定速度-反馈速度(取样周期内的方波数)
if(abs(ren)8)//30
{
lki=1.4; //ki值的确定1.4
}
else
{
lki=0.05; //积分系数:如果 | 给定值-反馈值 | 太大
} //则就可以不引入积分,或者引入的很小0.05
runp=kp*(ren-ren_1); //比例校正
runi=lki*ren; //积分校正
rund=kd*(ren-2*ren_1+ren_2); //微分校正
run=runp+runi+rund+run_1; //总校正
/*************新旧数据更新*************************/
ren_2=ren_1;
ren_1=ren; //len:当前取样周期内出现的速度偏差;len_1:上次取样周期内出现的速度偏差
run_1=run; //lun:当前取样周期内得出的PWM校正值;lun_1:上次取样周期内得出的PWM校正值
/*************新旧数据更新*************************/
if(run255)
{
run=255; //正速度
}
if(run-255)
{
run=-255; //负速度
}
if(run0)
{
vrs=1;
PCA0CPH1=-run;
}
if(run=0)
{
vrs=0;
PCA0CPH1=run;
}
//因为这里的PCA0CPH0越大,对应的电机速度越小,所以要255来减一下
}
void pio_init(void)
{
XBR0=0x00; //0000 0001
XBR1=0x72; //0111 0010 时能弱上拉 T0T1连接到脚口P06、P07 CEX0、CEX1连接到脚口P00、P01
P0MDIN=0xff; //模拟(0);数字(1) 1111 0011
P0MDOUT=0xc3;//开漏(0);推挽(1) 1111 1111
P0SKIP=0x3c; //0011 1100
P1MDIN=0xff; //1111 1111
P1MDOUT=0xfc;//
P1SKIP=0x00; //1111 1111
}
void sys_init(void) //12MHz
{
OSCICL=0x43;
OSCICN=0xc2;
CLKSEL=0x00;
}
void pwm1_1(void) //PWM的初始化
{
PCA0MD=0x08; //PCA时钟为12分频
PCA0CPL0=200; //左轮
PCA0CPM0=0x42; //设置左轮为8位PWM输出
PCA0CPH0=200;
PCA0CPL1=200; //平衡校正
PCA0CPM1=0x42; //设置为8位PWM输出
PCA0CPH1=200;
PCA0CN=0x40; //允许PCA工作
}
void t01_init(void)
{
TCON=0x50; //计数器1、2允许
TMOD=0x55; //定时器1、2采用16位计数功能
CKCON=0x00;
TH1=0x00; //用于采集左轮的速度
TL1=0x00;
TH0=0x00; //用于采集右轮的速度
TL0=0x00;
}
void TIME3_INT(void)
{
TMR3CN = 0x00; //定时器3为16位自动重载
CKCON = ~0x40;
TMR3RLL = 0xff;
TMR3RLH = 0xd7;
TMR3L = 0xff;
TMR3H = 0xd7;
TMR3CN |= 0x04;
}
void T3_ISR() interrupt 14 //定时器3中断服务程序
{
//led=~led;
EA=0;
TCON =~0x50; //关闭计数器0、1
vl1=TL0; //取左轮速度值
vl2=TH0;
vr1=TL1; //取右轮速度值
vr2=TH1;
TH1=0x00;
TL1=0x00;
TH0=0x00;
TL0=0x00;
PID(); //PID处理
TMR3CN =~0x80; //清中断标志位
TCON |=0x50; //重新开计数器0、1
EA=1;
}
void interrupt_init(void)
{ IE=0x80;
IP=0x00;
EIE1|=0x80;
EIP1|=0x80;
}
void delay(unsigned int m) //延时程序
{
for(i=0;i2000;i++)
{
for(j=0;jm;j++){_nop_(); _nop_();}
}
}
CE和SCLK是DS1302芯片的信号线,但也是与单片机的PIO口连接的;
因此初始化CE和SCLK,也就是初始化单片机的PIO口了;
在代码中,你可以去看看 DS1302_CE、DS1302_SCLK 的定义就明白了;
要搞清楚单片机与PLC的异同,首先得明确什幺是单片机,什幺是PLC。对此,我们简要回顾一下计算机的发展历程也许有帮助,按计算机专家的原始定义,计算机系统由五大部分--即控制单元(CU)、算术运算单元(ALU)、存储器(Memory)、输入设备(Input)、输出设备(Output)组成。早期计算机(晶体管的或集成电路的,不包括电子管的)的CU或ALU由一块甚至多块电路板组成,CU和ALU是分离的,随着集成度的提高,CU和ALU合在一块就组成了中央处理单元(CPU),接着将CPU集成到单块集成电路中就产生MPU或MCU,出现了如Intel4004、8008、8080,8085、8086、8088、Z80等MPU。此后,MPU的发展产生了两条分支,一支往高性能、高速度、大容量方向发展,典型芯片如:Intel80186、286、386、486、586、P2、P3、P4等,速度从4.7MHz到现在的3.2GHz。另一支则往多功能方向发展,将存储器(ROM、PROM、EPROM、EEPROM、FLASH ROM、SRAM等)、输入/出接口(Timer/Counter、PWM、ADC/DAC、UART、IIC、SPI、RTC、PCA、FPGA等)全部集成在一块集成电路中而成为SOC。依愚之见,这就是当今广泛应用的单片计算机,简称单片机。这一分支可谓品种繁多,位宽从8位到32位,引脚数从6个到几百个,工作频率从几十KHz到几百MHz,体系结构既有CISC也有RISC,数不胜数。常用的有MCS-51系列、MCS-96系列、PIC系列、AVR系列、ARM7/9系列、TMS320系列、MSP430系列、MOTOROLA众多的单片机等等。
至此,我们可以将计算机核心处理器的发展划分为三个阶段:板级的CPU、芯片级的MPU和SOC。
PLC是什幺呢?PLC的全称是Programmable Logic Controller(可编程序控制器),刚引入国内时,曾简称为PC。后来,IBM-PC获得广泛应用,PC成了个人电脑的代名词,才改为PLC。PLC还有另外的一个意思是Power Line Carrier(电力线载波)。
PLC是一种产品,但这种产品有点特别,在没有下载控制程序之前,它不具备任何控制功能,也就是说,没有应用程序的PLC是毫无用处的。PLC实际上是专为工业环境使用的通用控制平台,它必须进行二次开发才能完成最终控制目的,因此,它还需程序编辑/调试软件的配合。
PLC是智能产品,它的核心控制器采用什幺方案呢?板级的CPU肯定是不能考虑的,MPU也要好几块集成电路构成,以Z80 MPU为例,需要Z80MPU、PIO、CTC、SIO、EPROM、SRAM等,把这些集成电路安装在一块电路板上,这就是早期的单板计算机。这种方案体积太大,不适合现代要求。由此可见,PLC的核心控制器采用单片机是最合适的。
由此可得出结论:
1, PLC是建立在单片机之上的产品,单片机是一种集成电路,两者不具有可比性。
2, 单片机可以构成各种各样的应用系统,从微型、小型到中型、大型都可,PLC是单片机应用系统的一个特例。
3, 不同厂家的PLC有相同的工作原理,类似的功能和指标,有一定的互换性,质量有保证,编程软件正朝标准化方向迈进。这正是PLC获得广泛应用的基础。而单片机应用系统则是八仙过海,各显神通,功能千差万别,质量参差不齐,学习、使用和维护都很困难。
最后,从工程的角度,谈谈PLC与单片机系统的选用;
1, 对单项工程或重复数极少的项目,采用PLC方案是明智、快捷的途径,成功率高,可靠性好,手尾少,但成本较高。
2,对于量大的配套项目,采用单片机系统具有成本低、效益高的优点,但这要有相当的研发力量和行业经验才能使系统稳定、可靠地运行。最好的方法是单片机系统嵌入PLC的功能,这样可大大简化单片机系统的研制时间,性能得到保障,效益也就有保证。
单片机pio的介绍到此就结束了,感谢您耐心阅读,谢谢。
本文标签:单片机pio