main.c
上传用户:sdaoma
上传日期:2013-08-07
资源大小:3838k
文件大小:11k
源码类别:

GPS编程

开发平台:

C/C++

  1. /****************************************Copyright (c)**************************************************
  2. **                               Guangzou ZLG-MCU Development Co.,LTD.
  3. **                                      graduate school
  4. **                                 http://www.zlgmcu.com
  5. **
  6. **--------------File Info-------------------------------------------------------------------------------
  7. ** File name: main.c
  8. ** Last modified Date:  2004-09-16
  9. ** Last Version: 1.0
  10. ** Descriptions: The main() function example template
  11. **
  12. **------------------------------------------------------------------------------------------------------
  13. ** Created by: Chenmingji
  14. ** Created date: 2004-09-16
  15. ** Version: 1.0
  16. ** Descriptions: The original version
  17. **
  18. **------------------------------------------------------------------------------------------------------
  19. ** Modified by:
  20. ** Modified date:
  21. ** Version:
  22. ** Descriptions:
  23. **
  24. ********************************************************************************************************/
  25. #include "config.h"
  26. #include "stdlib.h"
  27. /********************add by yehaoben ***********/
  28. #define TaskStkGPSLengh 164 //Define the Task0 stack length 定义用户任务0的堆栈长度
  29.  
  30. OS_STK TaskStkGPS [TaskStkGPSLengh]; //Define the Task0 stack 定义用户任务0的堆栈
  31. void  TaskGPS(void *pdata); //Task0 任务0
  32. /************************** end ****************/
  33. extern void minigui_app_entry (void);
  34. // 定义输入消息数据结构
  35. typedef  struct  TOUCH_KEY
  36. {   uint8  sta;     // 状态字,d1位为1时表示按键输入,d0为1时表示触摸屏输入;
  37.                     // d7为1时表示按键/触摸屏按下,为0时表示放开。
  38.     uint8  key;     // 按键码(0--15)
  39.     
  40.     // 触摸屏输入的坐标
  41.     uint16  x;      
  42.     uint16  y;
  43. }  TouchKey_Sta;
  44. // 定义用于保存触摸屏(0,0)和两个校准点的坐标的电压值
  45. uint16  g_vx_min, g_vy_min;
  46. uint16  g_vinx0, g_viny0;
  47. uint16  g_vinx1, g_viny1;
  48. uint16  touch_wide, touch_high;
  49. /* 按键消息邮箱 */
  50. OS_EVENT  *TouchKeyMbox = NULL;          // 按键消息邮箱
  51. #define TaskStkLengh 64 // Define the Task0 stack length 定义用户任务0的堆栈长度
  52. OS_STK TaskStk [TaskStkLengh]; // Define the Task0 stack 定义用户任务0的堆栈
  53. void  Task0(void *pdata); // Task0 任务0
  54. OS_STK Task1Stk [TaskStkLengh];    // Define the Task1 stack 定义用户任务1的堆栈
  55. void  Task1(void *pdata); // Task0 任务1
  56. int  main(void)
  57. {
  58. OSInit ();
  59. OSTaskCreate (Task0,(void *)0, &TaskStk[TaskStkLengh - 1], 10);
  60. minigui_app_entry();
  61. TouchKeyMbox = OSMboxCreate(NULL);   // 建立一个邮箱,用于传递按键消息
  62. OSStart();
  63. return(0);
  64. }
  65. /****************************************************************************
  66. * 名称:TestTouch()
  67. * 功能:
  68. * 入口参数:无
  69. * 出口参数:返回1表示已校准过,返回0表示没有校准。
  70. * 说明:E2PROM中的数据结构定义如下。
  71. *       0xE0、0xE1保存触摸屏是否校准标志,为0x5A、0xA5时表示校准过;
  72. *
  73. *       0xE2、0xE3保存(0,0)点坐标的电压转换值g_vx_min; 
  74. *       0xE4、0xE5保存(0,0)点坐标的电压转换值g_vy_min;
  75. *       0xE6、0xE7保存第1个校验点的电压转换值g_vinx0;
  76. *       0xE8、0xE9保存第1个校验点的电压转换值g_viny0;
  77. *       0xEA、0xEB保存第2个校验点的电压转换值g_vinx1;
  78. *       0xEC、0xED保存第2个校验点的电压转换值g_viny1;
  79. *
  80. *       0xF0、0xF1保存第1、2校验点之间的x轴点数wide;
  81. *       0xF2、0xF4保存第1、2校验点之间的y轴点数high;
  82. ****************************************************************************/ 
  83. uint8  TestTouch(void)
  84. {   uint8  dat_buf1[20];
  85.     uint8  adr_buf[2];
  86.     // 读出E2PROM中的数据
  87.     adr_buf[0] = 0xE0;
  88.     I2cRead(CAT1025, dat_buf1, adr_buf, 1, 14);    
  89.     adr_buf[0] = 0xF0;
  90.     I2cRead(CAT1025, &dat_buf1[14], adr_buf, 1, 4);
  91.     
  92.     // 取得参数
  93.     g_vx_min = (dat_buf1[2] << 8) + dat_buf1[3];
  94.     g_vy_min = (dat_buf1[4] << 8) + dat_buf1[5];
  95.     g_vinx0  = (dat_buf1[6] << 8) + dat_buf1[7];
  96.     g_viny0  = (dat_buf1[8] << 8) + dat_buf1[9];
  97.     g_vinx1  = (dat_buf1[10] << 8) + dat_buf1[11];
  98.     g_viny1  = (dat_buf1[12] << 8) + dat_buf1[13];    
  99.     touch_wide = (dat_buf1[14] << 8) + dat_buf1[15];
  100.     touch_high = (dat_buf1[16] << 8) + dat_buf1[17];
  101.     
  102.     // 判断是否已经校准过
  103.     if((dat_buf1[0] == 0x5A) && (dat_buf1[1] == 0xA5)) return(1);
  104.         else  return(0);    
  105. }
  106. /****************************************************************************
  107. * 名称:GetLCD_XY()
  108. * 功能:读取触摸屏上触摸点的坐标。
  109. *       程序会一直等待,直到有触摸输入。
  110. * 入口参数:x       用于保存触摸点x坐标(LCD)的变量指针
  111. *           y       用于保存触摸点y坐标(LCD)的变量指针
  112. * 出口参数:无
  113. * 说明:先通测量y轴的触摸输入,判断是否有触摸动作。如果有,则进行6次数据
  114. *       采集,并进行去极值平均滤波处理。最后还要判断触摸输入是否合法,只有
  115. *       当触摸输入合法时才返回。
  116. ****************************************************************************/
  117. uint8  GetLCD_XY(uint16 *vx, uint16 *vy)
  118. {   uint16  vx_dat, vy_dat;
  119.     uint16  vx_dat1, vy_dat1;
  120.     int     i;           
  121.     
  122.     // 判断是否有触摸动作(通过ADS7843的PENIRQ引脚进行判断)
  123.     for(i=0; i<3; i++)
  124.     {   vy_dat = ADS7843_WriteRead(AIN_Y);
  125.         *vy = vy_dat;               // 初始化vy,以便于判断无触摸输入(vy=0)
  126.         
  127.         if(vy_dat != 0) break;
  128.     } // end of while(1)...
  129.     if(i>=3) return(0);
  130.     
  131.     // 进行数据采集
  132.     vx_dat = ADS7843_WriteRead(AIN_X);
  133.     vy_dat = ADS7843_WriteRead(AIN_Y);
  134.     for(i=0; i<100; i++);
  135.     vx_dat1 = ADS7843_WriteRead(AIN_X);
  136.     vy_dat1 = ADS7843_WriteRead(AIN_Y);
  137.         
  138.     if((vy_dat<3) || (vy_dat1<3)) return(0);   
  139.          
  140.     if(vx_dat>vx_dat1) 
  141.     {   if((vx_dat-vx_dat1) > 13) return(0);
  142.     }
  143.     else
  144.     {   if((vx_dat1-vx_dat) > 13) return(0); 
  145.     }
  146.         
  147.     if(vy_dat>vy_dat1) 
  148.     {   if((vy_dat-vy_dat1) > 18) return(0);
  149.     }
  150.     else
  151.     {   if((vy_dat1-vy_dat) > 18) return(0); 
  152.     } 
  153.         
  154.     *vx = (vx_dat+vx_dat1) >> 1;
  155.     *vy = (vy_dat+vy_dat1) >> 1;                          
  156.     return(1);
  157. }
  158. /*********************************************************************************************************
  159. **                            Task0 任务0
  160. ** 键盘驱动任务。读取ZLG7290扫描的按键值,然后把键值发送到TouchKeyMbox邮箱。
  161. ** 由MiniGUI的"comm" IAL输入引擎接收TouchKeyMbox邮箱的消息,然后进行相应的处理。
  162. ********************************************************************************************************/
  163. void  Task0(void *pdata)
  164. {   static uint8  s_enter_sta = 0;   
  165.     static TouchKey_Sta  s_event_input;
  166.     uint16  key;    
  167.     
  168. pdata = pdata;
  169. TargetInit();
  170. if(TestTouch() == 0)            // 读取触摸屏校准参数,判断触摸屏是否已校准
  171. {   // 若触摸屏没有校准,则控制数码管显示"Error 01"
  172.     ZLG7290ShowChar(7, 0x0E);
  173.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  174.         ZLG7290ShowChar(6, 0x18);
  175.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  176.         ZLG7290ShowChar(5, 0x18);
  177.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  178.         ZLG7290ShowChar(4, 0x15);
  179.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  180.         ZLG7290ShowChar(3, 0x18);
  181.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  182.         ZLG7290ShowChar(2, 0x1F);
  183.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  184.         ZLG7290ShowChar(1, 0x00);
  185.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  186.         ZLG7290ShowChar(0, 0x01);
  187.         OSTimeDly(OS_TICKS_PER_SEC / 100);
  188. }
  189. // 创建触摸屏输入检测任务
  190. OSTaskCreate (Task1,(void *)0, &Task1Stk[TaskStkLengh - 1], 9);
  191.        
  192. while (1)
  193. {   key = ZLG7290GetKey();  // 扫描键盘输入         
  194.     
  195.     if(key&0x00FF)          // 如果有按键,则判断是否要发送按下消息
  196.     {   if(s_enter_sta == 0) // 按键单击                    
  197.         {   // 设置消息中的按键值
  198.                 s_event_input.sta = 0x82;
  199.                 s_event_input.key = (key-1)&0x000F;   // 原按键值为1-16,所以要减1变为0-15           
  200.             OSMboxPost(TouchKeyMbox, (void *)&s_event_input);
  201.             
  202.             s_enter_sta = 1;  
  203.         }         
  204.     }
  205.     else    // 如果是没有按键,则判断是否要发送放开消息        
  206.     {   if(s_enter_sta != 0)  // 按键放开,则发送按键放开消息
  207.         {   s_event_input.sta = 0x02;
  208.             OSMboxPost(TouchKeyMbox, (void *)&s_event_input);                          
  209.         }
  210.         
  211.         s_enter_sta = 0;        
  212.     } // end of if(key&0x00FF)...else...
  213.     
  214. OSTimeDly(1);   
  215. }
  216. }
  217. /*********************************************************************************************************
  218. **                            Task1 任务1
  219. ** 键盘驱动任务。读取触摸屏的触摸输入,然后把键值发送到TouchKeyMbox邮箱。
  220. ** 由MiniGUI的"comm" IAL输入引擎接收TouchKeyMbox邮箱的消息,然后进行相应的处理。
  221. ********************************************************************************************************/
  222. void  Task1(void *pdata)
  223. {   static uint8  s_enter_sta = 0;   
  224.     static TouchKey_Sta  s_event_input;
  225.     uint16  vx1, vy1;
  226.     int     x1, y1;    
  227.     
  228. pdata = pdata;
  229.     /************************************************************/
  230.     OSTaskCreate (TaskGPS,(void *)0, &TaskStkGPS[TaskStkGPSLengh - 1], 14);
  231.      /************************************************************/
  232.    
  233. while (1)
  234. {   // 判断是否有触摸屏输入 
  235.     if(GetLCD_XY(&vx1, &vy1)==1)
  236.     {   // 触摸屏按下,转换坐标值(为了实现拖动,不对s_enter_sta进行判断)
  237.             x1 = (vx1 - g_vx_min) * touch_wide / (g_vinx1 - g_vinx0);
  238.             y1 = (vy1 - g_vy_min) * touch_high / (g_viny1 - g_viny0);
  239.             if(x1<0) x1 = 0;
  240.             if(y1<0) y1 = 0;        
  241.             if(x1>319) x1 = 319;
  242.             if(y1>239) y1 = 239;                             
  243.               
  244.             // 设置消息中的坐标值  
  245.             s_event_input.sta = 0x81;
  246.             s_event_input.x = x1;
  247.             s_event_input.y = y1;
  248.             OSMboxPost(TouchKeyMbox, (void *)&s_event_input);
  249.                 
  250.             s_enter_sta = 1;                     
  251.     }   
  252.     else
  253.     {   if(vy1 == 0)
  254.         {   if(s_enter_sta != 0)     // 若是松开触摸点,则发送放开消息
  255.             {   s_event_input.sta = 0x01;
  256.                 OSMboxPost(TouchKeyMbox, (void *)&s_event_input);             
  257.             }
  258.             s_enter_sta = 0;
  259.         } // end of if(vy1 == 0)...
  260.     } // end of if(GetLCD_XY(&vx1, &vy1)==1)...else...
  261.     
  262. OSTimeDly(5);   
  263. }
  264. }
  265. /************************************************************/
  266. void TaskGPS (void *pdata)
  267. {
  268. ModemInit(19200);
  269. while(1)
  270. OSTimeDly(10);
  271. }
  272. /************************************************************/
  273.    
  274. /*********************************************************************************************************
  275. **                            End Of File
  276. ********************************************************************************************************/