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

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

  • XPT2046 时序图
    SPI总线方式实现基于xpt2046的AD转换和PWM_第1张图片

  • 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个定时器周期。即 T p w m T_{pwm} Tpwm = 20 T C L K T_{CLK} TCLK
    SPI总线方式实现基于xpt2046的AD转换和PWM_第2张图片

    • 定时器设置和PWM产生

      #define maxA 4300 // 代表传感器(可变电阻)的上限
      float p; 
      u8 step = 20; // 把一个周期分为20份
      p = (float)temp/(float)maxA *(float)step; // temp 代表读取的传感器的值,这个就是比例  * 周期的份数
      
      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;
      	}
      }
      

你可能感兴趣的:(C51)