搜索
bottom↓
回复: 9

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

[复制链接]

出0入0汤圆

发表于 2010-8-7 16:24:43 | 显示全部楼层 |阅读模式
现在在尝试做一个四线电阻屏的控制器,计划用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);
   }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-8-7 16:25:21 | 显示全部楼层
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);
   }
}

出0入0汤圆

 楼主| 发表于 2010-8-7 16:25:44 | 显示全部楼层
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);  
    }
}

出0入0汤圆

 楼主| 发表于 2010-8-7 16:27:07 | 显示全部楼层
用M16把程序写得跟51的一模一样,但就是不能通信,太令人迷惑了。。。。。。

出0入0汤圆

 楼主| 发表于 2010-8-8 09:32:21 | 显示全部楼层
自己顶一下,希望高手们出手相助

出0入22汤圆

发表于 2010-8-8 10:04:19 | 显示全部楼层
楼主,其实tiny44的spi的3根线已经够你用了。SS那个,你可以随便用一个io来实现就可以了。mosi,miso,sck都是齐的。

出0入0汤圆

发表于 2010-8-14 10:35:53 | 显示全部楼层
定!!!!!!!!

出0入0汤圆

发表于 2010-9-23 19:55:32 | 显示全部楼层
我遇到一样的问题,软件模拟SPI采集不到数据啊,楼主怎么解决了么?

出0入0汤圆

发表于 2010-11-26 21:44:19 | 显示全部楼层
一模一样!
我的M16就是用IO模拟还是不行啊!!!
哪里的问题啊???

出0入0汤圆

发表于 2013-10-17 10:31:01 | 显示全部楼层
MARK!!!!!!!!!!!!!!!!!!!!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 00:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表