SPI总线方式实现基于xpt2046的AD转换和PWM

一、SPI总线传送数据和读取数据,AD转换实现读取电位器的值。

  • XPT2046 时序图
    这里写图片描述

  • SPI总线写数据,赋予DIN数据->上升沿写入

    void SPI_Write(uchar dat)
    {
    uchar i;
    CLK = 0;
    for(i=0; i<8; i++) 
    {
        DIN = dat >> 7;     //右移七位,最高位先写入
        dat <<= 1;         
        CLK = 0;            //产生上升沿放置数据到DIN
        CLK = 1;
    
    }
    }

  • SPI总线读取数据。下降沿读取数据到DOUT。

    uint SPI_Read(void)
    {
    uint i, dat=0;
    CLK = 0;
    for(i=0; i<12; i++)     //读取12位数据
    {
        dat <<= 1;          //先读取最高位
        CLK = 1;            
        CLK = 0;            //下降沿放置数据
        dat |= DOUT;
    
    }
    return dat; 
    }
  • 读取AD转换输出数字值。CS = 0,CLK = 0–> SPI写入命令->DPI读取AD转换结果。

    uint Read_AD_Data(uchar cmd)
    {
    uchar i;
    uint AD_Value;
    CLK = 0; 
    CS  = 0;
    SPI_Write(cmd); //写入AD转换命令
    
    for(i=6; i>0; i--);     //等待AD转换
    CLK = 1;    //产生一个时钟周期清除BUSY  
    _nop_();
    _nop_();
    CLK = 0;
    _nop_();
    _nop_();
    AD_Value=SPI_Read(); //读取转换结果
    CS = 1;  //恢复
    return AD_Value;    
    }
    

二、DA转换,产生PWM波

  • PWM波。通过周期定时器产生一个周期PWM波。比如把一个PWM波=20个定时器周期。即 Tpwm = 20 TCLK
    这里写图片描述

    • 定时器设置和PWM产生
    u8 step = 20;
    void Timer0Init() //初始化
    {
        TMOD|=0X01;//定时模式为0,工作模式为1
    
        TH0=0XFC;   //赋值
        TL0=0X18;   
        ET0=1;//打开定时器中断
        EA=1;//打开总中断
        TR0=1;//打开定时器TRO            
    }
    void Timer0() interrupt 1 //中断函数
    {
        static u16 timer;
        TH0=0XFC;   //定时周期为1ms
        TL0=0X18;
        timer++;  //用来计数
        if(timer>(int)p) //大于电位器输出值在20上的投影
        {
            led = 1;    //灯灭
        }   
        else
            led = 0;  //灯亮
        if(timer == step){ //20个定时周期清除一次,step = 20
             timer = 0;
        }
    }

猜你喜欢

转载自blog.csdn.net/jmu201521121021/article/details/78938325
今日推荐