}
/*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/ void DelayMs(unsigned char t) {
while(t--) {
//大致延时1mS DelayUs2x(245); DelayUs2x(245); } }
/*------------------------------------------------ 主函数
------------------------------------------------*/ main() {
unsigned int i=512;//旋转一周时间
Init_Timer0();
EA=1; //全局中断开 EX0=1; //外部中断0开 IT0=1; //1表示边沿触发
Speed=3;
TempData[0]=dofly_DuanMa[Speed/10];//分解显示信息,如要显示68, TempData[1]=dofly_DuanMa[Speed];//则68/10=6 68=8 Coil_OFF
while(i--) //正向 { Coil_A1 DelayMs(Speed);
Coil_AB1 //遇到Coil_AB1 用{A1=1;B1=1;C1=0;D1=0;}代替 DelayMs(Speed); //改变这个参数可以调整电机转速 , //数字越小,转速越大,力矩越小 Coil_B1 DelayMs(Speed); Coil_BC1
DelayMs(Speed); Coil_C1
21
DelayMs(Speed); Coil_CD1
DelayMs(Speed); Coil_D1 DelayMs(Speed); Coil_DA1
DelayMs(Speed); } }
/*------------------------------------------------ 外部中断程序
------------------------------------------------*/ void ISR_INT0(void) interrupt 0 {
if(!INT0) {
DelayMs(10);//在此处可以添加去抖动程序,防止按键抖动造成错误 if(!INT0)
//while(!INT1);//等待按键释放 {
Speed++; if(Speed==20) Speed=3;
TempData[0]=dofly_DuanMa[Speed/10];//分解显示信息,如要显示68, TempData[1]=dofly_DuanMa[Speed];//则68/10=6 68=8 } } }
/*------------------------------------------------ 显示函数,用于动态扫描数码管
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示 如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2 ------------------------------------------------*/ void Display(unsigned char FirstBit,unsigned char Num) {
static unsigned char i=0;
DataPort=0; //清空数据,防止有交替重影 LATCH1=1; //段锁存 LATCH1=0;
22
DataPort=dofly_WeiMa[i+FirstBit]; //取位码 LATCH2=1; //位锁存 LATCH2=0;
DataPort=TempData[i]; //取显示数据,段码 LATCH1=1; //段锁存 LATCH1=0; i++;
if(i==Num) i=0; }
/*------------------------------------------------ 定时器初始化子程序
------------------------------------------------*/ void Init_Timer0(void) {
TMOD |= 0x01; //使用模式1,16位定时器,使用\符号可以在使用多个定时器时不受影响
//TH0=0x00; //给定初值 //TL0=0x00;
EA=1; //总中断打开 ET0=1; //定时器中断打开 TR0=1; //定时器开关打开 PT0=1; //优先级打开 }
/*------------------------------------------------ 定时器中断子程序
------------------------------------------------*/ void Timer0_isr(void) interrupt 1 {
TH0=(65536-2000)/256; //重新赋值 2ms TL0=(65536-2000)%6;
Display(0,8); }
23
PCF8591 DA输出模拟
4.1项目简介
PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行I2C总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C总线以串行的方式进行传输。
I2C总线
1、I2C总线数据位的传输
它通过2根线:串行数据线(SDA)和串行时钟线(SCL)组成。连接到总线上的每一个器件都有一个唯一的地址,而且都可以作为一个发生器或接收器,SDA和SCL都是双向线路,分别通过一个电阻连接到电源(+5V)端。前提是连接到总线上的器件的SDA和SCL端必须是漏极或集电极开路型。I2C总线上的数据传输速率在标准模式下可达100Kb/s,快速模式可达400Kb/s,高速模式下可达3.4Mb/s。连接到总线的器件数量只由总线的电容(400PF)限制决定。
I2C总线上每传输一个数据位必须产生一个时钟脉冲,I2C总线上数据传输的有效性要求SDA线上的数据必须在时钟线SCL的高电平期间保存稳定,数据线的改变只能在时钟线为低电平期间。在标准模式下,高低电平宽度必须大于4.7us(即每次时钟线需延时4.7us后才能改变)。 2、I2C总线数据的传输
数据传输的字节格式
发送到SDA线上的每一个字节必须为8位,每次发送的字节数量不受限制,从机在接收完一个字节后向主机发送一个应答位,主机在收到从机应答后才会发送第二字节数据,发送数据时先发数据的最高位。
24
数据传输中的应答
相应的应答位由接收方(从机)产生,在应答的时钟脉冲期间,发送方(主机)应释放SDA线(使其为高电平)。在应答过程中,接收方(从机)必须将数据线SDA拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平。 3、I2C总线的传输协议
寻址字节
主机产生起始条件后,发送的第一字节为寻址字节,该字节的前7位为从机地址,最低位决定了传输的方向,该最低位为“0”表示主机写数据到从机,“1”表示主机从从机中读数据。从机地址由一个固定的部分(如高4位1001)和可编程部分(如低3位A0~A2)及一个方向位(R/W)组成。
传输格式
主机产生起始条件后,首先发送一个寻址字节,收到从机应答后,接着就传输数据,数据传输一般由主机产生的停止位终止。但如果主机仍希望在总线上通信,则它可以产生重复起始条件和寻址另一个从机,而不必产生一个停止条件。
本项目使用DA输入,数码管显示输出数字量,LED显示模拟电压大小。 DA转换
发送给PCF8591的第三个字节被存储到DAC数据寄存器,并使用片上DA转换器转换成对应的模拟电压。这个DA转换器由连接至外部的参考电压的具有256个接头的电阻分压电路和选择开关组成。接头译码器切换一个接头至DAC输出线模拟输出电压由自动清零单位增益放大器缓冲。这个缓冲放大器可通过设置控制寄存器的模拟输出容许标志来开户或关闭。在激活状态,输出电压将保持到新的数据字节被发送。片上DA转换器也可用于逐次逼近AD转换.为释放用于AD转换周期的DAC,单位增益放大器还配备了一个跟踪和保持电路。在执行AD转换时该电路保持输出电压。
4.2电路原理图
A/D输入方式选择说明:
25