? ? ? ?這個是暑假期間為了準(zhǔn)備2013電子設(shè)計競賽做的一個小項目,其實就是2005電子競賽的E題。。今天抽出時間在此總結(jié)一下,,順便也可以和大家分享一下思路。。
? ? ? ?關(guān)于這道題的要求,我就不多說了,大家都可以百度到。。我們做的懸掛系統(tǒng)有一下四個功能:
1、讓懸掛物體走直線。
2、讓懸掛物體畫圓。
3、在TFT屏上設(shè)定坐標(biāo)并讓懸掛物從原點走到該坐標(biāo)。
4、在TFT屏上觸摸一點顯示出該點坐標(biāo)并使懸掛物從原點運動到該坐標(biāo)。
? ? ? ?下面首先說說畫直線的思路:將起點和終點的坐標(biāo)作為函數(shù)的傳遞參數(shù)。通過計算起點和終點到兩個滑輪之間的距離差可以算出兩個電機在這段時間轉(zhuǎn)過的距離。。因為時間是相同的,所以令兩個電機的速度比等于通過計算得到的距離比即可。。
? ? ? ? 接下來說說畫圓的思路:畫圓可以近似為畫一個正四百邊形(五百、六百……都可以,可以試試哪種效果最好)。把畫圓分四次,一次畫四分之一個圓,就相當(dāng)于正一百邊形的四分之一。。然后通過簡單的數(shù)學(xué)運算算出下一時刻的坐標(biāo),然后把當(dāng)前坐標(biāo)賦值為下一時刻坐標(biāo),這兩步之間延一下時,防止值沒有傳遞過去。具體代碼如下:
for(i=1; i<100; i++)
//第一象限
{
now_x1 = x0 + Circle_rx*i;
now_y1 = sqrt( r*r - (Circle_rx*i)*(Circle_rx*i) ) + y0;
Draw_Line( now_x0, now_y0, now_x1, now_y1);
Delay_ms(30);
now_x0 = now_x1;
now_y0 = now_y1;
x =?now_x1;
y =?now_y1;
}
其中now_x0 、now_y0表示當(dāng)前時刻坐標(biāo),?now_x1、now_y1表示下一時刻坐標(biāo)。
在然后就是設(shè)定坐標(biāo),調(diào)用STM32開發(fā)板光盤例程里面的TFT.c文件里面的函數(shù),即可顯示在TFT屏上面顯示出坐標(biāo)。然后通過32單片機自帶的按鍵控制即可。最后調(diào)用畫直線的函數(shù)將原點坐標(biāo)和通過TFT屏設(shè)定的坐標(biāo)分別作為起點和終點坐標(biāo)即可。
?? 之后就是第四個,觸屏點的實現(xiàn),使用TFT屏上面自帶的ADS7843這個4線電阻觸摸屏轉(zhuǎn)換接口芯片,這是一款具有同步串行接口的12位取樣模數(shù)轉(zhuǎn)換器。然后些整個觸摸控制IC的驅(qū)動程序存放在TOUCH.c文件里面:驅(qū)動步驟如下:首先寫出對觸摸控制IC的讀寫程序,然后讀取觸摸點的電壓值,然后濾波采樣,采樣后去平均值減小誤差。
具體驅(qū)動程序如下:
? *****************************************************************************
// 實現(xiàn)功能:
ADS7843啟動
*****************************************************************************/
void start_7843(void) ? ? ? ? ? ? ? ?
{
? ? GPIO_ResetBits(GPIOC, GPIO_Pin_8); ? ?//TPCLK置低
? ? GPIO_SetBits(GPIOC, GPIO_Pin_9); ? ? ?//TPCS置高
? ? GPIO_SetBits(GPIOA, GPIO_Pin_8); ? ? ?//TPDI置高
? ? GPIO_SetBits(GPIOC, GPIO_Pin_8); ? ? ?//TPCLK置高
? ? GPIO_ResetBits(GPIOC, GPIO_Pin_9); ? ?//TPCS置低
}
/*****************************************************************************
// 實現(xiàn)功能:
寫8位命令到觸摸控制IC
// 輸入?yún)?shù): ?temp 需要寫入的8位控制命令
*****************************************************************************/
void Write_7843(uchar temp) ? ? ? ? ? ? ? ? ? ? ? ?
//SPI寫8位命令到觸摸控制IC
{
uchar i=0;
for(i=0;i<8;i++) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//循環(huán)8次寫入一字節(jié)
{
? ?if(temp&0x80)
GPIO_SetBits(GPIOA, GPIO_Pin_8); ? ? ?//TPDI置高
else?
GPIO_ResetBits(GPIOA, GPIO_Pin_8); ? ?
//判斷最高位是否為1,為1則向數(shù)據(jù)位寫1
GPIO_ResetBits(GPIOC, GPIO_Pin_8);?
delay(1); ? ? ? ? ? ? ? ?
//送一個脈沖,上升沿有效,將DIN位數(shù)據(jù)送入到IC
GPIO_SetBits(GPIOC, GPIO_Pin_8);?
delay(1); ? ? ? ? ? ? ? ?
temp<<=1; ? ? ? ? ? ? ? ? ? ? ? ? ?
//待寫數(shù)據(jù)左移1位,準(zhǔn)備好寫下一位數(shù)據(jù)
}
}
/*****************************************************************************
// 實現(xiàn)功能:
從觸摸控制IC讀8位數(shù)據(jù)到控制器
// 返回參數(shù): ?temp 需要寫入的8位控制命令
*****************************************************************************/
uint Read_7843(void) ? ? ? ? ? ? ? ? ? ? ? ? ?
//SPI 讀數(shù)據(jù)
{
uchar i=0;
uint temp=0;
for(i=0;i<12;i++) ? ? ? ? ? ? ? ? ? ? ? ?
//循環(huán)12次讀取12位結(jié)果
{?
? ? ? ?temp<<=1; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
//temp左移一位,準(zhǔn)備讀取下一位
? GPIO_SetBits(GPIOC, GPIO_Pin_8); ?
? delay(1); ? ? ? ? ? ? ? ? ?
? ? //下降沿有效
? GPIO_ResetBits(GPIOC, GPIO_Pin_8); ?
? delay(1);
? if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_11))?
? temp++; ? ? ? ? ? ? ? ? ? ?
//判斷控制IC送出的一位數(shù)據(jù)是否為1,如果為1,賦給temp的最低位
? ? ?}
? ? return(temp); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //返回結(jié)果
}
/*****************************************************************************
// 實現(xiàn)功能:讀取觸摸點X軸和Y軸電壓值
// 返回參數(shù):pix 讀取到的觸摸點電壓值
*****************************************************************************/
struct struct1 AD7843() ? ? ? ? ? ?
{
struct struct1 pix;
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
Write_7843(0x90); ? ? ? ? ? ? ? ? //送控制字 10010000 即用差分方式讀X坐標(biāo),詳細(xì)請見有關(guān)資料
GPIO_SetBits(GPIOC, GPIO_Pin_8);?
delay(1);?
GPIO_ResetBits(GPIOC, GPIO_Pin_8);?
delay(1);?
pix.y=Read_7843();
Write_7843(0xD0); ? ? ? ? ? ? ? ? //送控制字 11010000 即用差分方式讀Y坐標(biāo) 詳細(xì)請見有關(guān)資料
GPIO_SetBits(GPIOC, GPIO_Pin_8);?
delay(1);?
GPIO_ResetBits(GPIOC, GPIO_Pin_8);?
delay(1);?
pix.x=Read_7843();
GPIO_SetBits(GPIOC, GPIO_Pin_9);?
return pix;
}
/*****************************************************************************
// 實現(xiàn)功能:軟件濾波,濾掉波動過大的采樣點
// 返回參數(shù):flag 采集數(shù)據(jù)是否有效標(biāo)志,flag=1;則數(shù)據(jù)有效
*****************************************************************************/
uchar pix_filter(struct struct1 pix1,struct struct1 pix2)
{
uchar flag=0;
int x=pix1.x>pix2.x?pix1.x-pix2.x:pix2.x-pix1.x; ?//X軸兩次采樣絕對值
int y=pix1.y>pix2.y?pix1.y-pix2.y:pix2.y-pix1.y; ?//Y軸兩次采樣絕對值
if(x<10&&y<10)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//軟件濾波,2次取樣的值相差太大的視為噪聲
{
flag=1;
coordinate.x=(pix1.x+pix2.x)/2; ? ? ? ? ? ? ? ? //求兩次采樣平均值
coordinate.y=(pix1.y+pix2.y)/2;
}
return flag;
}
/*****************************************************************************
// 實現(xiàn)功能:讀取采集結(jié)果,兩次取均值
*****************************************************************************/
uchar Getpix(void) //取采樣值,此處使用軟件濾波,2次取樣的值相差太大的視為噪聲
{
? ? uchar flag=0;
? ? struct struct1 pix1;
? ? struct struct1 pix2;?
? ? if (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==0)
{ ?
? ? ? pix1=AD7843();
? ? ? ? pix2=AD7843();
if(pix_filter(pix1,pix2)==1) //得到當(dāng)前TP的取樣值,此處使用軟件濾波,2次取樣的值相差太大的視為噪聲
{
? ? ? ? ? ? ? ? ? if((coordinate.x>Xmin)&&(coordinate.y>Ymin))
? ? ? ? ? ? ? ? ? ?{
?lx=(uint)(240.0*(coordinate.x-Xmin)/(Xmax-Xmin)); ? //坐標(biāo)轉(zhuǎn)換,即根據(jù)采樣值計算實際坐標(biāo)值
ly=(uint)(320.0*(coordinate.y-Ymin)/(Ymax-Ymin)); ? //Xmin、max和Ymin、Ymax分別是觸摸屏橫縱坐標(biāo)的最小/最大值
flag=1;
? ? ? ? ? ? ? ? ? ?}
} ?
}
return flag;
}????
? ? ? ? 以上就是我的總結(jié),,希望對大家有所幫助。。也希望自己繼續(xù)努力。。加油!Fighting