马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
这里用到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;
- }
复制代码
|