51_固定频率的正弦波

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/**********************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();
    }
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#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 @   xiaoberber  阅读(104)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示