打印
[AVR单片机]

[求助]M16用IO模拟SPI与ADS7843通信

[复制链接]
3260|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mianhuacar|  楼主 | 2010-8-7 16:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在在尝试做一个四线电阻屏的控制器,计划用tiny44+ADS7843。

用m16的硬件SPI能成功与ADS7843通信,但由于tiny44的硬件SPI只有3或2线模式,ADS7843要用4线模式,所以想用IO口模拟SPI。然后就尝试用m16模拟SPI,但试了很久也不明白为什么自己写的程序不能与ADS7843通信,请求各位大侠帮助

*******M16硬件SPI成功的程序*******

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>     /* for _delay_ms() */
/*------宏定义------*/
#define uchar unsigned char
#define uint unsigned int
#define NOP() asm("nop")

#define KOU PORTB
#define SB(bitn)    (KOU |=(1<<(bitn)))
#define CB(bitn)    (KOU&=~(1<<(bitn)))
#define GB(bitn)    (KOU &(1<<(bitn)) )
#define SCK  7//DCLK
#define SS   4//CS
#define MOSI 5//DIN
#define BUSY 0//
#define MISO 6//DOUT
#define IQR  1//
unsigned char duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x76,0x6e};
//unsigned char test1,test2,test3;
/*------函数定义------*/
void Display(unsigned int TX,unsigned int TY)
{
unsigned char i;
    unsigned char num[9];
DDRA=0xff;
DDRC=0xff;
    num[1]=TX/1000;
    num[2]=(TX%1000)/100;
    num[3]=(TX%100)/10;
    num[4]=TX%10;
    num[5]=TY/1000;
    num[6]=(TY%1000)/100;
    num[7]=(TY%100)/10;
    num[8]=TY%10;
    for(i=0;i<8;i++)
{
   PORTA=0;
   PORTC=i;
   PORTA=duanma[num[i+1]];
   _delay_ms(1);
}
}
//------------------------------------------------------------------------
void SPI_MasterInit(void)
{
  DDRB=0b10110000;//SCK、MOSI、SS置输出,MISO置输入
  SB(MISO);//MISO、SS使用上拉电阻
  SB(SS);
  //SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
  /* Enable SPI, Master, set clock rate fck/128 */
  SPCR=0b01010011;
}
void SPI_MasterSent(uchar cData)
{
  SPDR = cData;
  while(!(SPSR & (1<<SPIF)));
  //test1=SPSR & (1<<SPIF);
}
uint SPI_MasterRead(void)//功能:使用SPI接收AD转换的值
{
   uint temp=0,thig=0,tlow=0;
   SPDR = 0x00;
   while(!(SPSR & (1<<SPIF)));
   //test2=SPSR & (1<<SPIF);
   thig=SPDR;//对SPDR操作后,SPI中断位变0。AD转换值的高8位存在thig的低8位
   SPDR = 0x00;
   while(!(SPSR & (1<<SPIF)));
   //test3=SPSR & (1<<SPIF);
   tlow=SPDR;//AD转换值的低4位存在tlow的5-8位
   tlow=tlow&0x00f0;//将没用位清0
   thig=thig&0x00ff;
   temp = (thig<<4)+(tlow>>4);
   return temp;
}
void SPI_Start(void)
{
  CB(SS);NOP();NOP();
  //_delay_us(100);
}
void SPI_Stop(void)
{
  SB(SS);
}
//----------------------------------------------------------
//主函数
int main(void)
{
   uint X=0,Y=0,zux[7],zuy[7];
   SPI_MasterInit();
   while(1)
   {
if(!(PINB &(1<<(1))))//有点击时
    {
      SPI_Start();
   SPI_MasterSent(0X90);
   X=SPI_MasterRead();
   SPI_Stop();
   SPI_Start();
   SPI_MasterSent(0XD0);
   Y=SPI_MasterRead();
   SPI_Stop();
    }
Display(X,Y);
   }
}

相关帖子

沙发
mianhuacar|  楼主 | 2010-8-7 16:46 | 只看该作者
M16模拟SPI失败的程序

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>     /* for _delay_ms() */
/*------宏定义------*/
#define uchar unsigned char
#define uint unsigned int
#define NOP() asm("nop")

#define KOU PORTB
#define SB(bitn)    (KOU |=(1<<(bitn)))
#define CB(bitn)    (KOU&=~(1<<(bitn)))
#define GB(bitn)    (KOU &(1<<(bitn)) )
#define SCK  7//DCLK
#define SS   4//CS
#define MOSI 5//DIN
//#define BUSY 0//
#define MISO 6//DOUT
#define IQR  1//
unsigned char duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x76,0x6e};
//unsigned char test1,test2,test3;
/*------函数定义------*/
void Display(unsigned int TX,unsigned int TY)
{
unsigned char i;
    unsigned char num[9];
DDRA=0xff;
DDRC=0xff;
    num[1]=TX/1000;
    num[2]=(TX%1000)/100;
    num[3]=(TX%100)/10;
    num[4]=TX%10;
    num[5]=TY/1000;
    num[6]=(TY%1000)/100;
    num[7]=(TY%100)/10;
    num[8]=TY%10;
    for(i=0;i<8;i++)
{
   PORTA=0;
   PORTC=i;
   PORTA=duanma[num[i+1]];
   _delay_ms(1);
}
}
//------------------------------------------------------------------------
void SPI_MasterInit(void)
{
  DDRB=0b10110000;//SCK、MOSI、SS置输出,MISO置输入
  SB(MISO);//MISO使用上拉电阻
  SB(SS);
  //SB(MOSI);
}
void SPI_MasterSent(uchar cData)
{
  uchar spicount=0;
  CB(SCK);
  _delay_us(10);
  for(spicount=0;spicount<8;spicount++)
  {
   
   if(cData&0x80)
     SB(MOSI);
   else
     CB(MOSI);
   cData<<=1;
   CB(SCK);_delay_us(10);
   SB(SCK);_delay_us(10);
   
  }
  
}
uint SPI_MasterRead(void)//功能:使用SPI接收AD转换的值
{
   uchar spicount=0;
   uint temp=0;
   for(spicount=0;spicount<12;spicount++)
   {
temp<<=1;
SB(SCK);_delay_us(10);
CB(SCK);_delay_us(10);
    if(GB(MISO))
   temp++;
   }
   return temp;
   
}
void SPI_Start(void)
{
  SB(SCK);_delay_us(10);
  CB(SS);_delay_us(10);
}
void SPI_Stop(void)
{
  SB(SCK);
  SB(SS);
  //SB(MOSI);
}
//----------------------------------------------------------
//主函数
int main(void)
{
   uint X=0,Y=0,zux[7],zuy[7];
   SPI_MasterInit();
   while(1)
   {
if(!(PINB &(1<<(1))))//有点击时
    {
      SPI_Start();
   SPI_MasterSent(0X90);
   //CB(SCK);_delay_us(5);
   SB(SCK);_delay_us(10);
   CB(SCK);_delay_us(10);
   X=SPI_MasterRead();
   SPI_Stop();
   SPI_Start();
   SPI_MasterSent(0XD0);
   Y=SPI_MasterRead();
   SPI_Stop();
}
Display(X,Y);
   }
}

使用特权

评论回复
板凳
mianhuacar|  楼主 | 2010-8-7 16:47 | 只看该作者
C51模拟SPI成功的程序

#include<reg52.h>   
#include <intrins.h> //包含一些汇编函数
sbit DCLK=P1^7;   //根据用户自己的定义
sbit CS=P1^4;
sbit DIN=P1^5;
sbit BUSY=P1^3;
sbit DOUT=P1^6;
sbit IQR=P1^1;
sbit TLight=P1^0;
unsigned char code duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x76,0x6e};
unsigned int X=0,Y=0,avx=0,avy=0;
unsigned char zt=0,jishu=0,fsjishu=0,fashong[5];
//------------延时程序----------------
void delay (int i)
{
  while(i--);
}

//
void start() //SPI开始
{
DCLK=1;
CS=0;
}

void WriteCharTo7843(unsigned char num) //SPI写数据
{
unsigned char count=0;
DCLK=0;
for(count=0;count<8;count++)
{
if(num&0x80)
  DIN=1;
else
  DIN=0;
num<<=1;
DCLK=0; _nop_();//_nop_();_nop_(); //上升沿有效
DCLK=1; _nop_();//_nop_();_nop_();
}
}


ReadFromCharFrom7843() //SPI 读数据
{
unsigned char count=0;
unsigned int Num=0;
for(count=0;count<12;count++)
{
TLight=0;
Num<<=1;
DCLK=1; _nop_();//_nop_();_nop_(); //下降沿有效
DCLK=0; _nop_();//_nop_();_nop_();
if(DOUT) Num++;
}
return(Num);
}
/*---------------数码管显示-------------------------------*/
void Display(unsigned int TX,TY)
{
unsigned char i;
    unsigned char num[9];
     //X=3124;Y=1234;
           num[1]=TX/1000;
           num[2]=(TX%1000)/100;
           num[3]=(TX%100)/10;
           num[4]=TX%10;
           num[5]=TY/1000;
           num[6]=(TY%1000)/100;
           num[7]=(TY%100)/10;
           num[8]=TY%10;
          for(i=0;i<8;i++)
    {
     P0=0;
     P2=i;
     P0=duanma[num[i+1]];
     delay(200) ;
    }
}
/*---------------采集主程序-------------------------------*/
void ZhongDuan()//用查询接受发来的数据
{
delay(25); //中断后延时以消除抖动,使得采样数据更准确
start(); //启动SPI
delay(2);
WriteCharTo7843(0x90); //送控制字 10010000 即用差分方式读X坐标
DCLK=1; _nop_();_nop_();_nop_();_nop_();
DCLK=0; _nop_();_nop_();_nop_();_nop_();
delay(2);
X=ReadFromCharFrom7843();   //读X轴坐标
delay(2);
WriteCharTo7843(0xD0); //送控制字 11010000 即用差分方式读Y坐标
DCLK=1; _nop_();_nop_();_nop_();_nop_();
DCLK=0; _nop_();_nop_();_nop_();_nop_();
Y=ReadFromCharFrom7843();   //读Y轴坐标
CS=1;
}


/*---------------主程序-------------------------------*/
void main()
{
unsigned char i=0;
   while(1)
       {
    if(!IQR)
    {
    ZhongDuan();
    }
    Display(X,Y);
    delay(60);  
    }
}

使用特权

评论回复
地板
mianhuacar|  楼主 | 2010-8-7 16:49 | 只看该作者
M16 IO模拟SPI的程序我是完全按照C51的改的,竟然不行,输出4095,请求各大侠抽点空帮帮忙ORZ

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

8

帖子

1

粉丝