- void xpt2046_port_init(void)
- {
- GPIO_InitType GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);
- //SD_CS XPT2046_CS
- GPIO_InitStructure.GPIO_Pins = XPT2046_CS_PIN|SD_CS_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
- GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- //XPT2046_IRQ
- GPIO_InitStructure.GPIO_Pins = XPT2046_IRQ_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_PU;//
- GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
- GPIO_Init(XPT2046_IRQ_GPIO, &GPIO_InitStructure);
- //触摸和SD均失能
- __SD_CS_SET();
- //__XPT2046_CS_SET();
- }
XPT2046读写一样定义SPI1:
- #define __XPT2046_WRITE_BYTE(__DATA) SPI1ReadWriteByte(__DATA)
XPT2046其他函数:
- uint8_t xpt2046_write_byte(uint8_t chData)
- {
- return __XPT2046_WRITE_BYTE(chData);
- }
- void xpt2046_init(void)
- {
- uint16_t hwXpos, hwYpos;
-
- __XPT2046_CS_SET();
- xpt2046_read_xy(&hwXpos, &hwYpos);
- }
- uint16_t xpt2046_read_ad_value(uint8_t chCmd)
- {
- uint16_t hwData = 0;
-
- __XPT2046_CS_CLR();
- xpt2046_write_byte(chCmd);
- hwData = xpt2046_write_byte(0x00);
- hwData <<= 8;
- hwData |= xpt2046_write_byte(0x00);
- hwData >>= 4;
- __XPT2046_CS_SET();
-
- return hwData;
- }
- #define READ_TIMES 5
- #define LOST_NUM 1
- uint16_t xpt2046_read_average(uint8_t chCmd)
- {
- uint8_t i, j;
- uint16_t hwbuffer[READ_TIMES], hwSum = 0, hwTemp;
- for (i = 0; i < READ_TIMES; i ++) {
- hwbuffer[i] = xpt2046_read_ad_value(chCmd);
- }
- for (i = 0; i < READ_TIMES - 1; i ++) {
- for (j = i + 1; j < READ_TIMES; j ++) {
- if (hwbuffer[i] > hwbuffer[j]) {
- hwTemp = hwbuffer[i];
- hwbuffer[i] = hwbuffer[j];
- hwbuffer[j] = hwTemp;
- }
- }
- }
- for (i = LOST_NUM; i < READ_TIMES - LOST_NUM; i ++) {
- hwSum += hwbuffer[i];
- }
- hwTemp = hwSum / (READ_TIMES - 2 * LOST_NUM);
- return hwTemp;
- }
- void xpt2046_read_xy(uint16_t *phwXpos, uint16_t *phwYpos)
- {
- *phwXpos = xpt2046_read_average(0xD0);
- *phwYpos = xpt2046_read_average(0x90);
- }
- #define ERR_RANGE 50
- bool xpt2046_twice_read_xy(uint16_t *phwXpos, uint16_t *phwYpos)
- {
- uint16_t hwXpos1, hwYpos1, hwXpos2, hwYpos2;
- xpt2046_read_xy(&hwXpos1, &hwYpos1);
- xpt2046_read_xy(&hwXpos2, &hwYpos2);
- if (((hwXpos2 <= hwXpos1 && hwXpos1 < hwXpos2 + ERR_RANGE) || (hwXpos1 <= hwXpos2 && hwXpos2 < hwXpos1 + ERR_RANGE))
- && ((hwYpos2 <= hwYpos1 && hwYpos1 < hwYpos2 + ERR_RANGE) || (hwYpos1 <= hwYpos2 && hwYpos2 < hwYpos1 + ERR_RANGE))) {
- *phwXpos = (hwXpos1 + hwXpos2) / 2;
- *phwYpos = (hwYpos1 + hwYpos2) / 2;
- return true;
- }
- return false;
- }
触摸应用的函数touch文件的代码,包含触摸检测,校准检测,画板程序及一个清空按键:
- #include "touch.h"
- #include "lcd.h"
- #include "XPT2046.h"
- #include <stdlib.h>
- #include <math.h>
- #include "at32_board.h"
- tp_dev_t s_tTouch;
- void tp_init(void)
- {
- xpt2046_init();
- }
- void tp_draw_touch_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor)
- {
- lcd_draw_line(hwXpos - 12, hwYpos, hwXpos + 13, hwYpos, hwColor);
- lcd_draw_line(hwXpos, hwYpos - 12, hwXpos, hwYpos + 13, hwColor);
- lcd_draw_point(hwXpos + 1, hwYpos + 1, hwColor);
- lcd_draw_point(hwXpos - 1, hwYpos + 1, hwColor);
- lcd_draw_point(hwXpos + 1, hwYpos - 1, hwColor);
- lcd_draw_point(hwXpos - 1, hwYpos - 1, hwColor);
- lcd_draw_circle(hwXpos, hwYpos, 6, hwColor);
- }
- void tp_draw_big_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor)
- {
- lcd_draw_point(hwXpos, hwYpos, hwColor);
- lcd_draw_point(hwXpos + 1, hwYpos, hwColor);
- lcd_draw_point(hwXpos, hwYpos + 1, hwColor);
- lcd_draw_point(hwXpos + 1, hwYpos + 1, hwColor);
- }
- void tp_show_info(uint16_t hwXpos0, uint16_t hwYpos0,
- uint16_t hwXpos1, uint16_t hwYpos1,
- uint16_t hwXpos2, uint16_t hwYpos2,
- uint16_t hwXpos3, uint16_t hwYpos3, uint16_t hwFac)
- {
- lcd_display_string(40, 160, (const uint8_t *)"x1", 16, RED);
- lcd_display_string(40 + 80, 160, (const uint8_t *)"y1", 16, RED);
- lcd_display_string(40, 180, (const uint8_t *)"x2", 16, RED);
- lcd_display_string(40 + 80, 180, (const uint8_t *)"y2", 16, RED);
- lcd_display_string(40, 200, (const uint8_t *)"x3", 16, RED);
- lcd_display_string(40 + 80, 200, (const uint8_t *)"y3", 16, RED);
- lcd_display_string(40, 220, (const uint8_t *)"x4", 16, RED);
- lcd_display_string(40 + 80, 220, (const uint8_t *)"y4", 16, RED);
- lcd_display_string(40, 240, (const uint8_t *)"fac is:", 16, RED);
- lcd_display_num(40 + 24, 160, hwXpos0, 4, 16, RED);
- lcd_display_num(40 + 24 + 80, 160, hwYpos0, 4, 16, RED);
- lcd_display_num(40 + 24, 180, hwXpos1, 4, 16, RED);
- lcd_display_num(40 + 24 + 80, 180, hwYpos1, 4, 16, RED);
- lcd_display_num(40 + 24, 200, hwXpos2, 4, 16, RED);
- lcd_display_num(40 + 24 + 80, 200, hwYpos2, 4, 16, RED);
- lcd_display_num(40 + 24, 220, hwXpos3, 4, 16, RED);
- lcd_display_num(40 + 24 + 80, 220, hwYpos3, 4, 16, RED);
- lcd_display_num(40 + 56, 240, hwFac, 3, 16, RED);
- }
- uint8_t tp_scan(uint8_t chCoordType)
- {
- if (!(__XPT2046_IRQ_READ())) {
- if (chCoordType) {
- xpt2046_twice_read_xy(&s_tTouch.hwXpos, &s_tTouch.hwYpos);
- } else if (xpt2046_twice_read_xy(&s_tTouch.hwXpos, &s_tTouch.hwYpos)) {
- //s_tTouch.hwXpos = 0.066 * s_tTouch.hwXpos + (-12);//s_tTouch.fXfac * s_tTouch.hwXpos + s_tTouch.iXoff;
- //s_tTouch.hwYpos = (-0.089) * s_tTouch.hwYpos + (352);//s_tTouch.fYfac * s_tTouch.hwYpos + s_tTouch.iYoff;
- s_tTouch.hwXpos = s_tTouch.fXfac * s_tTouch.hwXpos + s_tTouch.iXoff;
- s_tTouch.hwYpos = s_tTouch.fYfac * s_tTouch.hwYpos + s_tTouch.iYoff;
- }
- if (0 == (s_tTouch.chStatus & TP_PRESS_DOWN)) {
- s_tTouch.chStatus = TP_PRESS_DOWN | TP_PRESSED;
- s_tTouch.hwXpos0 = s_tTouch.hwXpos;
- s_tTouch.hwYpos0 = s_tTouch.hwYpos;
- }
- } else {
- if (s_tTouch.chStatus & TP_PRESS_DOWN) {
- s_tTouch.chStatus &= ~(1 << 7);
- } else {
- s_tTouch.hwXpos0 = 0;
- s_tTouch.hwYpos0 = 0;
- s_tTouch.hwXpos = 0xffff;
- s_tTouch.hwYpos = 0xffff;
- }
- }
- return (s_tTouch.chStatus & TP_PRESS_DOWN);
- }
- void tp_adjust(void)
- {
- uint8_t cnt = 0;
- uint16_t hwTimeout = 0, d1, d2, pos_temp[4][2];
- uint32_t tem1, tem2;
- float fac;
- lcd_clear_screen(WHITE);
- lcd_display_string(40, 40, (const uint8_t *)"Please use the stylus click the cross on the screen. The cross will always move until the screen adjustment is completed.",
- 16, RED);
- tp_draw_touch_point(20, 20, RED);
- s_tTouch.chStatus = 0;
- s_tTouch.fXfac = 0;
- while (1) {
- tp_scan(1);
- if((s_tTouch.chStatus & 0xC0) == TP_PRESSED) {
- hwTimeout = 0;
- s_tTouch.chStatus &= ~(1 << 6);
-
- pos_temp[cnt][0] = s_tTouch.hwXpos;
- pos_temp[cnt][1] = s_tTouch.hwYpos;
- cnt ++;
- switch(cnt) {
- case 1:
- tp_draw_touch_point(20, 20, WHITE);
- tp_draw_touch_point(LCD_WIDTH - 20, 20, RED);
- break;
- case 2:
- tp_draw_touch_point(LCD_WIDTH - 20, 20, WHITE);
- tp_draw_touch_point(20, LCD_HEIGHT - 20, RED);
- break;
- case 3:
- tp_draw_touch_point(20, LCD_HEIGHT - 20, WHITE);
- tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, RED);
- break;
- case 4:
- tem1=abs((int16_t)(pos_temp[0][0]-pos_temp[1][0]));//x1-x2
- tem2=abs((int16_t)(pos_temp[0][1]-pos_temp[1][1]));//y1-y2
- tem1*=tem1;
- tem2*=tem2;
- tem1+=tem2;
- d1=sqrt(tem1);
- tem1=abs((int16_t)(pos_temp[2][0]-pos_temp[3][0]));//x3-x4
- tem2=abs((int16_t)(pos_temp[2][1]-pos_temp[3][1]));//y3-y4
- tem1*=tem1;
- tem2*=tem2;
- tem1+=tem2;
- d2=sqrt(tem1);
- fac=(float)d1/d2;
- if(fac<0.95f||fac>1.05f||d1==0||d2==0) {
- cnt=0;
- tp_show_info(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);
- delay_ms(1000);
- lcd_fill_rect(96, 240, 24, 16, WHITE);
- tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
- tp_draw_touch_point(20, 20, RED);
- continue;
- }
- tem1=abs((int16_t)(pos_temp[0][0]-pos_temp[2][0]));//x1-x3
- tem2=abs((int16_t)(pos_temp[0][1]-pos_temp[2][1]));//y1-y3
- tem1*=tem1;
- tem2*=tem2;
- tem1+=tem2;
- d1=sqrt(tem1);//
- tem1=abs((int16_t)(pos_temp[1][0]-pos_temp[3][0]));//x2-x4
- tem2=abs((int16_t)(pos_temp[1][1]-pos_temp[3][1]));//y2-y4
- tem1*=tem1;
- tem2*=tem2;
- tem1+=tem2;
- d2=sqrt(tem1);//
- fac=(float)d1/d2;
- if(fac<0.95f||fac>1.05f) {
- cnt=0;
- tp_show_info(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//??¨o?¨oy?Y
- delay_ms(1000);
- lcd_fill_rect(96, 240, 24, 16, WHITE);
- tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
- tp_draw_touch_point(20, 20, RED);
- continue;
- }//
-
- tem1=abs((int16_t)(pos_temp[1][0]-pos_temp[2][0]));//x1-x3
- tem2=abs((int16_t)(pos_temp[1][1]-pos_temp[2][1]));//y1-y3
- tem1*=tem1;
- tem2*=tem2;
- tem1+=tem2;
- d1=sqrt(tem1);//
- tem1=abs((int16_t)(pos_temp[0][0]-pos_temp[3][0]));//x2-x4
- tem2=abs((int16_t)(pos_temp[0][1]-pos_temp[3][1]));//y2-y4
- tem1*=tem1;
- tem2*=tem2;
- tem1+=tem2;
- d2=sqrt(tem1);//
- fac=(float)d1/d2;
- if(fac<0.95f||fac>1.05f) {
- cnt=0;
- tp_show_info(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//??¨o?¨oy?Y
- delay_ms(1000);
- lcd_fill_rect(96, 240, 24, 16, WHITE);
- tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
- tp_draw_touch_point(20, 20, RED);
- continue;
- }
- s_tTouch.fXfac = (float)(LCD_WIDTH - 40) / (int16_t)(pos_temp[1][0] - pos_temp[0][0]);
- s_tTouch.iXoff = (LCD_WIDTH - s_tTouch.fXfac * (pos_temp[1][0] + pos_temp[0][0])) / 2;
- s_tTouch.fYfac = (float)(LCD_HEIGHT - 40) / (int16_t)(pos_temp[2][1] - pos_temp[0][1]);
- s_tTouch.iYoff = (LCD_HEIGHT - s_tTouch.fYfac * (pos_temp[2][1] + pos_temp[0][1])) / 2;
-
- if(abs(s_tTouch.fXfac) > 2 || abs(s_tTouch.fYfac) > 2) {
- cnt=0;
- tp_draw_touch_point(LCD_WIDTH - 20, LCD_HEIGHT - 20, WHITE);
- tp_draw_touch_point(20, 20, RED);
- lcd_display_string(40, 26, (const uint8_t *)"TP Need readjust!", 16, RED);
- continue;
- }
- lcd_clear_screen(WHITE);
- lcd_display_string(35, 110, (const uint8_t *)"Touch Screen Adjust OK!", 16, BLUE);
- delay_ms(1000);
- lcd_clear_screen(WHITE);
- return;
- }
- }
- delay_ms(10);
- if (++ hwTimeout >= 1000) {
- break;
- }
- }
- }
- void tp_dialog(void)
- {
- lcd_clear_screen(WHITE);
- lcd_display_string(LCD_WIDTH - 40, 0, (const uint8_t *)"CLEAR", 16, BLUE);
- }
- void tp_draw_board(void)
- {
- tp_scan(0);
- if (s_tTouch.chStatus & TP_PRESS_DOWN) {
- if (s_tTouch.hwXpos < LCD_WIDTH && s_tTouch.hwYpos < LCD_HEIGHT) {
- if (s_tTouch.hwXpos > (LCD_WIDTH - 40) && s_tTouch.hwYpos < 16) {
- tp_dialog();
- } else {
- tp_draw_big_point(s_tTouch.hwXpos, s_tTouch.hwYpos, RED);
- }
- }
- }
- }
在main文件中调用:
- int main(void)
- {
- /*!< At this stage the microcontroller clock setting is already configured,
- this is done through SystemInit() function which is called from startup
- file (startup_at32f403_xx.s) before to branch to application main.
- To reconfigure the default setting of SystemInit() function, refer to
- system_at32f4xx.c file
- */
- /* Config LED */
- AT32_Board_Init();
- /* SPIy Config -------------------------------------------------------------*/
- SPI1_Init();
- lcd_port_init();
- lcd_init();
-
- xpt2046_port_init();
- tp_init();
- //触摸校准
- tp_adjust();
- tp_dialog();
- while (1)
- {
- tp_draw_board();
- }
- }
编译测试:
代码:
SPI_LCD _XPT2046 - russa.rar
(5.26 MB, 下载次数: 158)