历史上的今天
今天是: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 #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; }
史海拾趣
|
NXL LPC系列ARM IIC总线下读写AT24Cxx的总结 最近应用到NXP LPC系列的ARM IIC总线进行读写AT24Cxx EEPROM,总是出现一下错误,经过查阅资料才发现,原来本人范的全是最基本的错误,感觉很惭愧,现在把容易出错的地方进行总结,希望网友遇到这样的问题时 ...… 查看全部问答> |
|
#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; ...… 查看全部问答> |
|
串口使用DMA接收。手册上有这么说明:溢出错误如果RXNE 还没有被复位,又接收到一个字符,则发生溢出错误。数据只有当RXNE 位被清零后才能从移位寄存器转移到RDR 寄存器。RXNE 标记是接收到每个字节后被置位的。如果下一 ...… 查看全部问答> |
|
程序下载后,设备可正常运行,但有时设备受到一定冲击(如掉到地上或大一些的脉冲干扰)后,设备就无法正常工作了(设备可正常启动,就是部分功能不好用了)!最怪异的是,什么都不动,就是重新下一遍程序,设备马上恢复正常!!!求教各位看官这是 ...… 查看全部问答> |
|
你有没有这种感觉,当你极目远眺的下一秒,便开始为脚下的路迷茫;期待腾飞的翅膀,在现实的面前总有点不知所措。那么,怎么样找到你自己倾心想为之奋斗的事业?又如何去成功规划乃至实现它,而使自己少走弯路,截弯取直呢?独之秀职业顾问给了 ...… 查看全部问答> |




