ATMEGA16用IO模擬SPI驅(qū)動ADS7843
其效果如下圖:
以下是其驅(qū)動程序:
typedef unsigned char BYTE; // 8-bit
typedef unsigned int WORD; // 16-bit
typedef unsigned long DWORD; // 32-bit
#define _nop_() asm("NOP")
#define touch_PORT PORTB
#define PEN_Q 7
#define DOUT 6
#define DIN 5 //引腳定義
#define CS 4 //mega16
#define DCLK 3
#define SPI_CS_Assert() touch_PORT &= ~_BV(CS)
#define SPI_CS_Deassert() touch_PORT |= _BV(CS)
WORD TP_X=1,TP_Y=1; //當(dāng)前觸控坐標(biāo)
//**********************************************************
void SPI_Init(void) //SPI開始
{
DDRB|=_BV(CS)|_BV(DCLK)|_BV(DIN);
touch_PORT|=_BV(CS)|_BV(DCLK)|_BV(DIN);
}
//**********************************************************
void WriteCharTo7843(unsigned char num) //SPI寫數(shù)據(jù)
{
unsigned char count=0,temp;
touch_PORT&=~_BV(DCLK);
for(count=0;count<8;count++)
{
temp=num;
if(temp&0x80)
touch_PORT|=_BV(DIN);
else
touch_PORT&=~_BV(DIN);
num<<=1;
touch_PORT&=~_BV(DCLK);
_nop_();_nop_();_nop_(); //上升沿有效
touch_PORT|=_BV(DCLK);
_nop_();_nop_();_nop_();
}
}
//**********************************************************
unsigned int ReadFromCharFrom7843(void) //SPI 讀數(shù)據(jù)
{
unsigned char count=0;
unsigned int Num=0;
for(count=0;count<12;count++)
{
Num<<=1;
touch_PORT|=_BV(DCLK);
_nop_();_nop_();_nop_(); //下降沿有效
touch_PORT&=~_BV(DCLK);
_nop_();_nop_();_nop_();
if(PINB&_BV(DOUT))
Num++;
}
return(Num);
}
void AD7843(void) //接收11次后求10次的平均值
{
static WORD X_TEMP[11],Y_TEMP[11];
static BYTE count=0;
WORD lx=0,ly=0;
if (!(PINB&_BV(PEN_Q)))
{
_delay_us(500);
while (!(PINB&_BV(PEN_Q)))
{
SPI_CS_Assert();
WriteCharTo7843(0x90); //送控制字 10010000 即用差分方式讀X坐標(biāo) 詳細(xì)請見有關(guān)資料
touch_PORT|=_BV(DCLK);
_nop_();_nop_();_nop_();
touch_PORT&=~_BV(DCLK);
_nop_();_nop_();_nop_();
Y_TEMP[count]=ReadFromCharFrom7843();
WriteCharTo7843(0xD0); //送控制字 11010000 即用差分方式讀Y坐標(biāo) 詳細(xì)請見有關(guān)資料
touch_PORT|=_BV(DCLK);
_nop_();_nop_();_nop_();
touch_PORT&=~_BV(DCLK);
_nop_();_nop_();_nop_();
X_TEMP[count]=ReadFromCharFrom7843();
SPI_CS_Deassert();
if(count++==10)
{
for(count=0;count<10;count++)
{
X_TEMP[10]+=X_TEMP[count];
Y_TEMP[10]+=Y_TEMP[count];
}
TP_X=X_TEMP[10]/10;
TP_Y=Y_TEMP[10]/10;
count=0;
// GUI_wrul(100,20,TP_X,RGB(120,255,0),color[2]);//(uchar x, uint y, unsigned long num, uint color,uint b_color);
// GUI_wrul(200,20,TP_Y,RGB(120,255,0),color[2]);
lx=240-((TP_X-240)/16); //將AD值轉(zhuǎn)換位顯示屏坐標(biāo)
ly=320-((TP_Y-380)/12); //將AD值轉(zhuǎn)換位顯示屏坐標(biāo)
// GUI_wrul(100,40,X_TEMP[10],RGB(120,255,0),color[2]);//(uchar x, uint y, unsigned long num, uint color,uint b_color);
// GUI_wrul(200,40,Y_TEMP[10],RGB(120,255,0),color[2]);
GUI_Point(lx,ly,RGB(250,0,250));
Y_TEMP[10]=0;
X_TEMP[10]=0;
}
}
count=0;
}
}
整個程序比較簡單,自己分析吧。
評論