历史上的今天
返回首页

历史上的今天

今天是:2025年01月22日(星期三)

正在发生

2021年01月22日 | 51单片机控制舵机实验

2021-01-22 来源:eefocus

简介:这里用到PCF8591 ADDA芯片和51单片机和一个电位器。通过控制电位器,产生PWM波,控制舵机旋转。并在数码管上显示角度。

电路图

这是程序,、


/*-----------------------------------------------


名称:IIC协议 PCF8591ADDA转换


内容:此程序通过IIC协议对DAAD芯片操作,读取电位器的电压,并输出模拟量,用LED亮度渐变指示,晶体选用12MHz


------------------------------------------------*/


#include"reg52.h"


#include //包含NOP空指令函数_nop_();


#define AddWr 0x90 //写数据地址


#define AddRd 0x91 //读数据地址


sbit Sda=P1^2; //定义总线连接端口


sbit Scl=P1^1;


sbit control_signal=P1^5;


data unsigned int Display[8];//定义临时存放数码管数值


unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数共阴码管段码表


unsigned int ADtemp; //定义全局变量


unsigned int high,low;


static unsigned int count1;


/*------------------------------------------------


延时程序


------------------------------------------------*/


void mDelay(unsigned char j)


{


unsigned int i;


for(;j>0;j--)


{


for(i=0;i<125;i++)


{;}


}


}


/*------------------------------------------------


初始化定时器0


------------------------------------------------*/


void Init_Timer0(void)


{


TMOD |=0x01; //定时器设置 0.1ms in 11.0592M crystal


TH0=(65536-78)/256;


TL0=(65536-78)%256; //定时0.1mS


ET0=1;//定时器中断打开


EA=1;//总中断


TR0=1; //启动定时器0


}


/*------------------------------------------------


启动IIC总线


------------------------------------------------*/


void Start(void)


{


Sda=1;


_nop_();


Scl=1;


_nop_();


Sda=0;


_nop_();


Scl=0;


}


/*------------------------------------------------


停止IIC总线


------------------------------------------------*/


void Stop(void)


{


Sda=0;


_nop_();


Scl=1;


_nop_();


Sda=1;


_nop_();


Scl=0;


}


/*------------------------------------------------


应答IIC总线


------------------------------------------------*/


void Ack(void)


{


Sda=0;


_nop_();


Scl=1;


_nop_();


Scl=0;


_nop_();


}


/*------------------------------------------------


非应答IIC总线


------------------------------------------------*/


void NoAck(void)


{


Sda=1;


_nop_();


Scl=1;


_nop_();


Scl=0;


_nop_();


}


/*------------------------------------------------


发送一个字节


------------------------------------------------*/


void Send(unsigned char Data)


{


unsigned char BitCounter=8;


unsigned char temp;


do


{


temp=Data;


Scl=0;


_nop_();


if((temp&0x80)==0x80)


Sda=1;


else


Sda=0;


Scl=1;


temp=Data<<1;


Data=temp;


BitCounter--;


}


while(BitCounter);


Scl=0;


}


/*------------------------------------------------


读入一个字节并返回


------------------------------------------------*/


unsigned char Read(void)


{


unsigned char temp=0;


unsigned char temp1=0;


unsigned char BitCounter=8;


Sda=1;


do


{


Scl=0;


_nop_();


Scl=1;


_nop_();


if(Sda)


temp=temp|0x01;


else


temp=temp&0xfe;


if(BitCounter-1)


{


temp1=temp<<1;


temp=temp1;


}


BitCounter--;


}


while(BitCounter);


return(temp);


}


/*------------------------------------------------


读取AD模数转换的值,有返回值


------------------------------------------------*/


unsigned int ReadADC(unsigned char Chl)


{


unsigned int Data;


Start(); //启始信号


Send(AddWr);//0x90


Ack();


Send(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加


//Chl的值分别为0、1、2、3,分别代表1-4通道


Ack();


Start();


Send(AddRd); //读入地址


Ack();


Data=Read(); //读数据


Scl=0;


NoAck();


Stop();


return Data; //返回值


}


/******************************************************************/


/* 主程序 */


/******************************************************************/


void main()


{


Init_Timer0();


while(1)


{


unsigned int angle;


ADtemp=ReadADC(0); //ADtemp的取值范围是0-255,定时的时间范围是0.5-2.5ms


high=65075-7.2*ADtemp; // ( high=65035-7.8*ADtemp;12MHz)(65535-(460+7.2*ADtemp 11.0592MHz)


low=47563+7.2*ADtemp; // ( low=46035+7.8*ADtemp; ) ( 65535-(17972-7.2*ADtemp 11.0592MHz )


angle=ADtemp*0.7;


Display[0]=Datatab[angle/100];//处理0通道电压显示


Display[1]=Datatab[(angle%100)/10];


Display[2]=Datatab[angle%10];


while(1)


{


P0=Display[count1];//用于动态扫描数码管


P2=count1;


mDelay(1);


count1++;


if(count1==3) //表示扫描3个数码管


{


count1=0;


break;


}


}


}


}


/******************************************************************/


/* 定时器中断函数


/******************************************************************/


void tim(void) interrupt 1 using 1


{


static unsigned char count;


if (!count)


{


control_signal = 1; //给高电平


TH0=high/256;


TL0=high%256; }


else


{


control_signal=0 ;


TH0=low/256;


TL0=low%256;


}


count=~count;


}


推荐阅读

史海拾趣

Elcoma公司的发展小趣事

Elcoma公司在其早期发展阶段,就致力于电子技术的研发和创新。他们成功研发出一种新型高效能的电子芯片,这一突破性的技术大大提高了电子设备的性能和效率。这一创新技术迅速在行业内引起了广泛关注,许多大型电子设备制造商纷纷与Elcoma合作,希望将这一技术应用到他们的产品中。Elcoma凭借这一技术突破,逐渐在电子行业中崭露头角。

ALPS公司的发展小趣事

随着全球对环保问题的日益关注,Elcoma公司也积极响应,将环保理念融入到企业的发展战略中。他们采用环保材料和工艺,减少生产过程中的污染排放,同时推出了一系列环保型电子产品,满足消费者对环保产品的需求。这种对环保的重视不仅提升了Elcoma的品牌形象,也为企业带来了可持续发展的动力。

Capar Components Corp公司的发展小趣事

在电子行业的初期,Capar Components Corp由几位热衷于电子技术的年轻人创立。他们凭借对技术的热情和对市场的敏锐洞察,决定投身于电子元器件的研发与生产。然而,创业的道路并非一帆风顺。资金短缺、技术瓶颈以及市场竞争激烈等问题接踵而至。但他们没有放弃,通过不断的技术创新和市场调研,成功研发出一款性能优异的电容器,迅速打开了市场,奠定了公司的基础。

AOS公司的发展小趣事

除了热水领域,AOS公司还积极拓展其业务范围,涉足了水处理、空气净化等多个领域。公司坚持创新驱动的发展战略,不断投入研发资源,推出了一系列具有创新性和高性能的产品。这些产品的推出不仅丰富了AOS的产品线,也进一步提升了其在全球市场的竞争力。

AnDAPT__Inc.公司的发展小趣事

进入20世纪,AOS公司开始将目光投向热水领域。1936年,公司研发出了著名的“金圭特护内胆”技术,这一创新在热水器行业中引起了革命性的变化。金圭内胆不仅提高了热水器的耐用性和安全性,也大幅提升了产品的能效。这一技术的推出使AOS公司迅速成为热水领域的领先者,并奠定了其在全球热水器市场的领导地位。

Everspin公司的发展小趣事

随着技术的不断进步,Everspin不断推出新的MRAM产品,并逐渐将市场扩展到工业自动化、游戏、能源管理、通讯、运输和航空电子等多个领域。特别是其MRAM和STT-MRAM产品在数据中心、云存储、能源、工业、汽车和运输市场中的广泛应用,为全球MRAM用户奠定了最强大、增长最快的基础。

问答坊 | AI 解惑

有个电路,不知道为何效果不太好,短路保护的,

来自EEWORLD合作群:499581  群主:wangkj 上电时不能自动导通…

查看全部问答>

基于StrongARM嵌入式Linux系统下的USB通信实现.pdf

基于StrongARM嵌入式Linux系统下的USB通信实现.pdf…

查看全部问答>

NXL LPC系列ARM IIC总线下读写AT24Cxx的总结

       最近应用到NXP LPC系列的ARM IIC总线进行读写AT24Cxx EEPROM,总是出现一下错误,经过查阅资料才发现,原来本人范的全是最基本的错误,感觉很惭愧,现在把容易出错的地方进行总结,希望网友遇到这样的问题时 ...…

查看全部问答>

初学 wince 请教大家一些问题

初学wince  请教大家一些问题 关于wince应用程序开发 1.wince应用程序开发常用IED有哪些 2.学习wince 入门书籍都有哪些 …

查看全部问答>

51串行口 工作方式0问题

#include sbit d1=P1^1;                                //接有发光二极管,低电平时灯亮 sbit rx=P3^0; void delayms(unsigned int x)      & ...…

查看全部问答>

串口发送通了 但是始终接收不到数据

        int tmp,i,j;         int receiv,send=0x30;         *ULCON0=0x03;         *UCON0=0x09;         *UBRDIV0=0x280;   ...…

查看全部问答>

****香版主请教USART1串口与DMA-5的一点疑问

串口使用DMA接收。手册上有这么说明:溢出错误如果RXNE 还没有被复位,又接收到一个字符,则发生溢出错误。数据只有当RXNE 位被清零后才能从移位寄存器转移到RDR 寄存器。RXNE 标记是接收到每个字节后被置位的。如果下一 ...…

查看全部问答>

求教一个stm8s105的怪异问题

程序下载后,设备可正常运行,但有时设备受到一定冲击(如掉到地上或大一些的脉冲干扰)后,设备就无法正常工作了(设备可正常启动,就是部分功能不好用了)!最怪异的是,什么都不动,就是重新下一遍程序,设备马上恢复正常!!!求教各位看官这是 ...…

查看全部问答>

职场发展,你如何避免少走弯路?

  你有没有这种感觉,当你极目远眺的下一秒,便开始为脚下的路迷茫;期待腾飞的翅膀,在现实的面前总有点不知所措。那么,怎么样找到你自己倾心想为之奋斗的事业?又如何去成功规划乃至实现它,而使自己少走弯路,截弯取直呢?独之秀职业顾问给了 ...…

查看全部问答>