51_固定频率的正弦波

 

 /**********************51单片机学习例程************************
*  平台:Keil U4 + STC89C52
*  名称: PCF8591 ,固定输出10Hz的正弦波,数码管显示频率
*  编写:Tony
*  日期:2022-2-12
*  晶体:12MHZ
*	 变更记录:无
******************************************************************/

#include <reg52.h>
#define GPIO_DIG P1		 //数码管使用的段选IO
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;			  //138译码器,数码管的位选
#define		GE 	    {LSA=1;LSB=1;LSC=1;}				//打开个位位选端
#define 	SHI  	{LSA=0;LSB=1;LSC=1;}				//打开十位位选端

#define uchar unsigned char
#define uint unsigned int
uchar code DIG_CODE[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar num_ge,num_shi;
uchar SEG_CNT;
uchar code sin_table[] = {0x7F,0x98,0xB0,0xC6,0xD9,0xE9,0xF5,0xFC,
							0xFE,0xFC,0xF5,0xE9,0xD9,0xC6,0xB0,0x98,
							0x7F,0x66,0x4E,0x38,0x25,0x15,0x09,0x02,
							0x00,0x02,0x09,0x15,0x25,0x38,0x4E,0x66};
									//正弦波数据表
uint timer0_value;	   //定时器0初值寄存器
uchar vol_num;		   //数组标号
uchar TH0_BUFF;		   //TH0装载值的暂存器
uchar TL0_BUFF;		   //TL0装载值的暂存器
void Timer0_Init(void);
void SEG_display(void);
extern void DAC_OUT_START(void);	//调用其它文件中的函数
extern bit send_byte(uchar DAT);
/***************************************************
*				定时器0初始化子函数
*			 根据定时器初值初始化定时器0
****************************************************/
void Timer0_Init(void)
{
    TMOD=0x01;   //使用定时器1,16位定时器
    TH0_BUFF=(65535-timer0_value)/256;
	TL0_BUFF=(65535-timer0_value)%256;
	TH0=TH0_BUFF;
	TL0=TL0_BUFF;
	TF0=0;		//清中断标志
	EA=1;		//开总中断
	ET0=1;		//开定时器0中断
	TR0=1;	    //启动定时器0
}
/***************************************************
*			中断子程序,1/32个周期中断一次
*		DA输出电压值,同时给TH0和TL0赋初值
****************************************************/
void Time0() interrupt 1
{
	TH0=TH0_BUFF;
	TL0=TL0_BUFF;
	send_byte(sin_table[vol_num]);//送入要转换的电压值
	if(vol_num>=31)				  //电压值更新
		vol_num=0;
	else
	    vol_num++;
}

void SEG_display(void)
{
	switch(SEG_CNT)
	{
	   case 0x01: GPIO_DIG=0x00; SHI; GPIO_DIG=	DIG_CODE[1];
	              SEG_CNT++; break;
	   case 0x02: GPIO_DIG=0x00; GE; GPIO_DIG=	DIG_CODE[0];			   
				  SEG_CNT=0x01;break;
	   default: break;

	}
}
void main()
{
    SEG_CNT=0x01;
	timer0_value=3125-37;	//补偿37
	DAC_OUT_START();
	Timer0_Init();
	while(1)
	{
		SEG_display();
	}

}

  

#include <reg52.h>
#include <intrins.h> 					//包含空指令函数_nop_();
#define uchar unsigned char
#define uint unsigned int
#define delay_6us {_nop_();_nop_();_nop_();\
					_nop_();_nop_();_nop_();}		//延时5个机器周期
#define PCF_ADDR	0x90				//定义PCF8591的地址

sbit SCL = P3^6;      					//定义总线连接端口
sbit SDA = P3^7;
void IIC_start(void);					//函数声明
void IIC_stop(void);
bit ack_check(void);
bit send_byte(uchar DAT);
void PCF8591_DAC_OUT(uchar DAT);
void DAC_OUT_START(void);
void DAC_OUT_STOP(unsigned char DAT);
/***************************************************
*								IIC总线开始信号
****************************************************/
void IIC_start(void)
{
	SDA=1;
	SCL=1;			//置一两条线
	delay_6us ;		//延时6个机器周期
	SDA=0;			//拉低数据线
	delay_6us ;		
//	SCL=0;			//拉低时钟线
}
/***************************************************
*								IIC总线停止信号
****************************************************/
void IIC_stop(void)
{
	SDA=0;			//拉低数据线
	SCL=1;			//置一时钟线
	delay_6us ;		
	SDA=1;			//置一数据线
	delay_6us ;		
 }
/***************************************************
*								检测IIC总线应答信号
****************************************************/
bit ack_check(void)
{
	bit ack_bit;		//位定义应答信号存储单元
	SDA=1;				//释放数据线,勾引从设备发送应答信号
	delay_6us ;			
	SCL=1;				//置一时钟线
	delay_6us ;		
	ack_bit = SDA;		//采样此时的数据线信号
	SCL=0;				//拉低时钟线
	return ack_bit;		//返回采样到的应答信号
}
/***************************************************
*							向从设备发送一个字节,
*							同时检测应答信号
****************************************************/
bit send_byte(uchar DAT)
{
	uchar i;
	uchar temp;					//缓存寄存器
	bit ack;					//定义位变量,反馈应答信号
	temp = DAT;					//待发送字节存入缓冲寄存器
	for(i = 0;i < 8;i++)		//循环发送8位数据
	{
		SCL = 0;				//拉低时钟线
		if((temp&0x80)==0x80)	//判断temp的高位是0还是1
			SDA=1;							
		else
			SDA=0;				//送出相应数据
		delay_6us ;			
		SCL = 1;				//拉高时钟线
		temp <<=1;		//待发送数据左移一位
		delay_6us ;			
	}
	SCL = 0;					//拉低时钟线
	ack = ack_check();			//调用应答信号检测子函数
	return ack;					//返回检测到的应答信号
}
/***************************************************
*								DA转换子函数 
*								控制DA输出电压
****************************************************/
void PCF8591_DAC_OUT(uchar DAT)
{
  IIC_start();
  if(send_byte(PCF_ADDR)==1)
    {
	   	IIC_stop();
		return;
	}
   send_byte(0x40);
   send_byte(DAT);
   IIC_stop();
}
/***************************************************
*								DA初始化子函数 
****************************************************/
void DAC_OUT_START(void)
{
  IIC_start();
  if(send_byte(PCF_ADDR)==1)
    {
	   	IIC_stop();
		return;
	}
  send_byte(0x40);
}

/***************************************************
*								DA停止子函数 
****************************************************/
void DAC_OUT_STOP(uchar DAT)
{
  send_byte(DAT);
  IIC_stop();
}

  

posted @ 2022-02-12 22:32  xiaoberber  阅读(89)  评论(0编辑  收藏  举报