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(); }