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