基于mini2440简易计算器

基于mini2440简易计算器使用的是数组实现,并非逆波兰式,因此功能不够强大,仅供驱动学习,以及C语言基础编程学习之用.有时间读者可以用逆波兰式来实现强大功能计算器,原理也很简单,建议读《c程序设计第二版》里面有算法的代码.读者自行研究.此程序基于电子相册的改进,触摸屏,LCD,字符现实,数字输入等等

mini2440  索尼X35   LCD液晶屏

主函数部分:

  1. #include "def.h"
  2. #include "option.h"
  3. #include "2440addr.h"
  4. #include "profile.h"
  5. #include "mmu.h"
  6. extern U32 X,Y;
  7. extern void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp);
  8. extern void CLK_init(void);
  9. extern void LCD_IO_init(void);
  10. extern void LCD_POWER(void);
  11. extern void LCD_init(void);
  12. extern void LCD_on(void);
  13. extern void LCD_off(void);
  14. extern void Tc_calibrate(void);
  15. extern void input(void);
  16. extern void Touch_Init(void);
  17. extern void word(int x,int y,char* string);
  18. extern unsigned char gImage[];  //extern引用外部数组,计算器界面
  19. void Main(void)
  20. {
  21. rGPBCON=(1<<0);
  22. rGPBDAT=(0<<0);//关闭蜂鸣器
  23. CLK_init();
  24. LCD_POWER();
  25. LCD_IO_init();
  26. LCD_init();
  27. LCD_on();
  28. Touch_Init();
  29. MMU_Init(); //初始化MMU,解决中断向量表入口与内存地址不一致问题,地址重映射
  30. BMP_display(0, 0, 240,320, gImage); //显示计算器界面  240×320屏
  31. while(1)
  32. {
  33. Tc_calibrate();
  34. input();
  35. }
  36. }

计算器的输入及其计算部分,结合触摸屏,利用数组实现字符和数字的存储等:

pasting

  1. #include "def.h"
  2. #include "2440addr.h"
  3. #define touch_p  (X>0&&X<42&&Y>0&&Y<80)         //定义触摸屏按键区域
  4. #define touch_0  (X>0&&X<42&&Y>80&&Y<160)
  5. #define touch_e  (X>0&&X<42&&Y>160&&Y<240)
  6. #define touch_a  (X>0&&X<42&&Y>240&&Y<320)
  7. #define touch_1  (X>42&&X<84&&Y>0&&Y<80)
  8. #define touch_2  (X>42&&X<84&&Y>80&&Y<160)
  9. #define touch_3  (X>42&&X<84&&Y>160&&Y<240)
  10. #define touch_s  (X>42&&X<84&&Y>240&&Y<320)
  11. #define touch_4  (X>84&&X<126&&Y>0&&Y<80)
  12. #define touch_5  (X>84&&X<126&&Y>80&&Y<160)
  13. #define touch_6  (X>84&&X<126&&Y>160&&Y<240)
  14. #define touch_m  (X>84&&X<126&&Y>240&&Y<320)
  15. #define touch_7  (X>126&&X<168&&Y>0&&Y<80)
  16. #define touch_8  (X>126&&X<168&&Y>80&&Y<160)
  17. #define touch_9  (X>126&&X<168&&Y>160&&Y<240)
  18. #define touch_d  (X>126&&X<168&&Y>240&&Y<320)
  19. #define touch_c  (X>168&&X<196&&Y>240&&Y<320)
  20. #define white 0xffffff
  21. #define B_off rGPBDAT=(0<<0) //?????
  22. #define B_on  rGPBDAT=(1<<0) //?????
  23. extern U32 X,Y;
  24. extern unsigned char gImage[];  //extern????????
  25. extern Draw_REC(int x,int y,int x1,int y1,U32 color);
  26. extern void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp);
  27. extern void Draw_ASCII(U32 x,U32 y,U32 color,const unsigned char ch[]);
  28. extern void word(int x,int y,char* string);
  29. extern void Main(void);
  30. char op,opf;//用于何种元算的分拣操作符
  31. int Num1,Num2;//参与运算两个数
  32. int F1,F2;//答案
  33. char num[10000];//用于显示的字符数组
  34. int num1[100],num2[100];//保存输入数字的数组
  35. int n[100],t[100]; //提取答案的各个位
  36. int n1=0,n2=0;//用于输入数字分拣操作符
  37. int len=0,len1=0;//用于计算答案的位数
  38. int i=0,j=0,k=0,a=0;
  39. /**********************************
  40. *清除各个标志函数
  41. **********************************/
  42. void Clear_f(void)
  43. {
  44. int b=0,c=0;
  45. for(c=0;c<10000;c++)
  46. {
  47. num[c]=‘ ‘;
  48. }
  49. for(b=0;b<100;b++)
  50. {
  51. num1[b]=0;
  52. num2[b]=0;
  53. n[b]=0;
  54. t[b]=0;
  55. }
  56. op=0;opf=0;
  57. Num1=0;Num2=0;
  58. F1=0;F2=0;
  59. n1=0;n2=0;
  60. len=0;len1=0;
  61. i=0;j=0;k=0;a=0;
  62. }
  63. /**********************************
  64. *四则运算函数
  65. **********************************/
  66. void Calc(int *Num_1,int *Num_2,int *f)
  67. {
  68. switch(op)  //分拣操作符
  69. {
  70. case‘n‘:    //无运算或等号
  71. *f = *f;
  72. break;
  73. case ‘+‘:   //加
  74. *f = *Num_1+*Num_2;
  75. break;
  76. case ‘-‘:   //减
  77. *f = *Num_1-*Num_2;
  78. break;
  79. case ‘*‘:    //乘
  80. *f =*Num_1*(*Num_2);
  81. break;
  82. case ‘/‘:    //除
  83. *f = *Num_1/(*Num_2);
  84. break;
  85. }
  86. }
  87. /**********************************
  88. *延迟函数
  89. **********************************/
  90. void delay(int times)
  91. {
  92. int i;
  93. for(;times>0;times--)
  94. for(i=0;i<400;i++);
  95. }
  96. /**********************************
  97. *界面输入函数
  98. **********************************/
  99. void input(void)
  100. {
  101. int flag=0;
  102. int numb[10]={0,1,2,3,4,5,6,7,8,9};
  103. char nums[10]={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘};
  104. if(op==‘+‘||op==‘-‘||op==‘*‘||op==‘/‘) flag=1;
  105. else flag=0;
  106. if(flag==0)//无运算符
  107. {
  108. if(touch_0)
  109. {
  110. num[i]=‘0‘;  //用于屏幕显示图像 0
  111. num1[i]=0;   //用于计算
  112. i++;
  113. n1++;
  114. Draw_REC(0,80,42,160,white);
  115. B_on;         //按下‘0‘键,蜂鸣器响一声
  116. delay(1000);
  117. B_off;
  118. BMP_display(0,0,240,320,gImage);
  119. }
  120. else if(touch_1)
  121. {
  122. num[i]=‘1‘;
  123. num1[i]=1;
  124. i++;
  125. n1++;
  126. Uart_Printf("n1=%4d\n",n1);
  127. Draw_REC(42,0,84,80,white);
  128. B_on;
  129. delay(1000);
  130. B_off;
  131. BMP_display(0,0,240,320,gImage);
  132. }
  133. else if(touch_2)
  134. {
  135. num[i]=‘2‘;
  136. num1[i]=2;
  137. i++;
  138. n1++;
  139. Draw_REC(42,80,84,160,white);
  140. B_on;
  141. delay(1000);
  142. B_off;
  143. BMP_display(0,0,240,320,gImage);
  144. }
  145. else if(touch_3)
  146. {
  147. num[i]=‘3‘;
  148. num1[i]=3;
  149. i++;
  150. n1++;
  151. Draw_REC(42,160,84,240,white);
  152. B_on;
  153. delay(1000);
  154. B_off;
  155. BMP_display(0,0,240,320,gImage);
  156. }
  157. else if(touch_4)
  158. {
  159. num[i]=‘4‘;
  160. num1[i]=4;
  161. i++;
  162. n1++;
  163. Draw_REC(84,0,126,80,white);
  164. B_on;
  165. delay(1000);
  166. B_off;
  167. BMP_display(0,0,240,320,gImage);
  168. }
  169. else if(touch_5)
  170. {
  171. num[i]=‘5‘;
  172. num1[i]=5;
  173. i++;
  174. n1++;
  175. Draw_REC(84,80,126,160,white);
  176. B_on;
  177. delay(1000);
  178. B_off;
  179. BMP_display(0,0,240,320,gImage);
  180. }
  181. else if(touch_6)
  182. {
  183. num[i]=‘6‘;
  184. num1[i]=6;
  185. i++;
  186. n1++;
  187. Draw_REC(84,160,126,240,white);
  188. B_on;
  189. delay(1000);
  190. B_off;
  191. BMP_display(0,0,240,320,gImage);
  192. }
  193. else if(touch_7)
  194. {
  195. num[i]=‘7‘;
  196. num1[i]=7;
  197. i++;
  198. n1++;
  199. Draw_REC(126,0,168,80,white);
  200. B_on;
  201. delay(1000);
  202. B_off;
  203. BMP_display(0,0,240,320,gImage);
  204. }
  205. else if(touch_8)
  206. {
  207. num[i]=‘8‘;
  208. num1[i]=8;
  209. i++;
  210. n1++;
  211. Draw_REC(126,80,168,160,white);
  212. B_on;
  213. delay(1000);
  214. B_off;
  215. BMP_display(0,0,240,320,gImage);
  216. }
  217. else if(touch_9)
  218. {
  219. num[i]=‘9‘;
  220. num1[i]=9;
  221. i++;
  222. n1++;
  223. Draw_REC(126,160,168,240,white);
  224. B_on;
  225. delay(1000);
  226. B_off;
  227. BMP_display(0,0,240,320,gImage);
  228. }
  229. }
  230. else   //加减乘除,以及第二个运算数字
  231. {
  232. if(touch_0)
  233. {
  234. num[i]=‘0‘;
  235. num2[j]=0;
  236. i++;
  237. j++;
  238. n2++;
  239. Draw_REC(0,80,42,160,white);
  240. B_on;
  241. delay(1000);
  242. B_off;
  243. BMP_display(0,0,240,320,gImage);
  244. }
  245. else if(touch_1)
  246. {
  247. num[i]=‘1‘;
  248. num2[j]=1;
  249. i++;
  250. j++;
  251. n2++;
  252. Draw_REC(42,0,84,80,white);
  253. B_on;
  254. delay(1000);
  255. B_off;
  256. BMP_display(0,0,240,320,gImage);
  257. }
  258. else if(touch_2)
  259. {
  260. num[i]=‘2‘;
  261. num2[j]=2;
  262. i++;
  263. j++;
  264. n2++;
  265. Draw_REC(42,80,84,160,white);
  266. B_on;
  267. delay(1000);
  268. B_off;
  269. BMP_display(0,0,240,320,gImage);
  270. }
  271. else if(touch_3)
  272. {
  273. num[i]=‘3‘;
  274. num2[j]=3;
  275. i++;
  276. j++;
  277. n2++;
  278. Draw_REC(42,160,84,240,white);
  279. B_on;
  280. delay(1000);
  281. B_off;
  282. BMP_display(0,0,240,320,gImage);
  283. }
  284. else if(touch_4)
  285. {
  286. num[i]=‘4‘;
  287. num2[j]=4;
  288. i++;
  289. j++;
  290. n2++;
  291. Draw_REC(84,0,126,80,white);
  292. B_on;
  293. delay(1000);
  294. B_off;
  295. BMP_display(0,0,240,320,gImage);
  296. }
  297. else if(touch_5)
  298. {
  299. num[i]=‘5‘;
  300. num2[j]=5;
  301. i++;
  302. j++;
  303. n2++;
  304. Draw_REC(84,80,126,160,white);
  305. B_on;
  306. delay(1000);
  307. B_off;
  308. BMP_display(0,0,240,320,gImage);
  309. }
  310. else if(touch_6)
  311. {
  312. num[i]=‘6‘;
  313. num2[j]=6;
  314. i++;
  315. j++;
  316. n2++;
  317. Draw_REC(84,160,126,240,white);
  318. B_on;
  319. delay(1000);
  320. B_off;
  321. BMP_display(0,0,240,320,gImage);
  322. }
  323. else if(touch_7)
  324. {
  325. num[i]=‘7‘;
  326. num2[j]=7;
  327. i++;
  328. j++;
  329. n2++;
  330. Draw_REC(126,0,168,80,white);
  331. B_on;
  332. delay(1000);
  333. B_off;
  334. BMP_display(0,0,240,320,gImage);
  335. }
  336. else if(touch_8)
  337. {
  338. num[i]=‘8‘;
  339. num2[j]=8;
  340. i++;
  341. j++;
  342. n2++;
  343. Draw_REC(126,80,168,160,white);
  344. B_on;
  345. delay(1000);
  346. B_off;
  347. BMP_display(126,80,168,160,gImage);
  348. }
  349. else if(touch_9)
  350. {
  351. num[i]=‘9‘;
  352. num2[j]=9;
  353. i++;
  354. j++;
  355. n2++;
  356. Draw_REC(126,160,168,240,white);
  357. B_on;
  358. delay(1000);
  359. B_off;
  360. BMP_display(0,0,240,320,gImage);
  361. }
  362. }
  363. if(touch_p)
  364. {
  365. op=‘.‘;
  366. num[i]=‘.‘;
  367. i++;
  368. Draw_REC(0,0,42,80,white);
  369. B_on;
  370. delay(1000);
  371. B_off;
  372. BMP_display(0,0,240,320,gImage);
  373. }
  374. else if(touch_e)
  375. {
  376. opf=‘=‘;
  377. //num[i]=‘=‘;
  378. //i++;
  379. Draw_REC(0,160,42,240,white);
  380. B_on;
  381. delay(1000);
  382. B_off;
  383. BMP_display(0,0,240,320,gImage);
  384. }
  385. else if(touch_a)
  386. {
  387. op=‘+‘;
  388. num[i]=‘+‘;
  389. i++;
  390. Draw_REC(0,240,42,320,white);
  391. B_on;
  392. delay(1000);
  393. B_off;
  394. BMP_display(0,0,240,320,gImage);;
  395. }
  396. else if(touch_s)
  397. {
  398. op=‘-‘;
  399. num[i]=‘-‘;
  400. i++;
  401. Draw_REC(42,240,84,320,white);
  402. B_on;
  403. delay(1000);
  404. B_off;
  405. BMP_display(0,0,240,320,gImage);
  406. }
  407. else if(touch_m)
  408. {
  409. op=‘*‘;
  410. num[i]=‘*‘;
  411. i++;
  412. Draw_REC(84,240,126,320,white);
  413. B_on;
  414. delay(1000);
  415. B_off;
  416. BMP_display(0,0,240,320,gImage);
  417. }
  418. else if(touch_d)
  419. {
  420. op=‘/‘;
  421. num[i]=‘/‘;
  422. i++;
  423. Draw_REC(126,240,168,320,white);
  424. B_on;
  425. delay(1000);
  426. B_off;
  427. BMP_display(0,0,240,320,gImage);
  428. }
  429. else if(touch_c)
  430. {
  431. Draw_REC(168,240,196,320,white);
  432. B_on;
  433. delay(1000);
  434. B_off;
  435. BMP_display(0,0,240,320,gImage);
  436. Clear_f();
  437. }
  438. switch(n1)   //合成第一个运算数
  439. {
  440. case 1:Num1=num1[0];break;
  441. case 2:Num1=num1[0]*10+num1[1];break;
  442. case 3:Num1=num1[0]*100+num1[1]*10+num1[2];break;
  443. case 4:Num1=num1[0]*1000+num1[1]*100+num1[2]*10+num1[3];break;
  444. case 5:Num1=num1[0]*10000+num1[1]*1000+num1[2]*100+num1[3]*10+num1[4];break;
  445. case 6:Num1=num1[0]*100000+num1[1]*10000+num1[2]*1000+num1[3]*100+num1[4]*10+num1[5];break;
  446. }
  447. switch(n2)    //合成第二个运算数
  448. {
  449. case 1:Num2=num2[0];break;
  450. case 2:Num2=num2[0]*10+num2[1];break;
  451. case 3:Num2=num2[0]*100+num2[1]*10+num2[2];break;
  452. case 4:Num2=num2[0]*1000+num2[1]*100+num2[2]*10+num2[3];break;
  453. case 5:Num2=num2[0]*10000+num2[1]*1000+num2[2]*100+num2[3]*10+num2[4];break;
  454. case 6:Num2=num2[0]*100000+num2[1]*10000+num2[2]*1000+num2[3]*100+num2[4]*10+num2[5];break;
  455. }
  456. word(210,2,num); //在LCD屏幕上显示算式
  457. X=0;
  458. Y=0;
  459. if(opf==‘=‘)     //如果按下等号
  460. {
  461. Calc(&Num1,&Num2,&F1); //进行运算
  462. num[i]=‘=‘;    //在屏幕显示等号
  463. F2=F1;
  464. while(F2>0)
  465. {
  466. t[a++]=F2%10; //把答案中个各位数字提取出来,放到数组中
  467. F2=F2/10;
  468. len++;
  469. }
  470. len1=len;
  471. a=0;
  472. while(len1--)
  473. {
  474. n[len1]=t[a++]; //答案中各位转移到数组n中
  475. }
  476. switch(len)
  477. {
  478. case 1:            //答案是一位数
  479. {
  480. for(k=0;k<10;k++)
  481. {if(numb[k]==n[0]) num[i+1]=nums[k];};break;
  482. }
  483. case 2:            //答案是两位数
  484. {
  485. for(k=0;k<10;k++)
  486. {if(numb[k]==n[0]) num[i+1]=nums[k];}
  487. for(k=0;k<10;k++)
  488. {if(numb[k]==n[1]) num[i+2]=nums[k];};break;
  489. }
  490. case 3:            //答案是三位数
  491. {
  492. for(k=0;k<10;k++)
  493. {if(numb[k]==n[0]) num[i+1]=nums[k];}
  494. for(k=0;k<10;k++)
  495. {if(numb[k]==n[1]) num[i+2]=nums[k];}
  496. for(k=0;k<10;k++)
  497. {if(numb[k]==n[2]) num[i+3]=nums[k];};break;
  498. }
  499. case 4:
  500. {
  501. for(k=0;k<10;k++)
  502. {if(numb[k]==n[0]) num[i+1]=nums[k];}
  503. for(k=0;k<10;k++)
  504. {if(numb[k]==n[1]) num[i+2]=nums[k];}
  505. for(k=0;k<10;k++)
  506. {if(numb[k]==n[2]) num[i+3]=nums[k];}
  507. for(k=0;k<10;k++)
  508. {if(numb[k]==n[3]) num[i+4]=nums[k];};break;
  509. }
  510. case 5:
  511. {
  512. for(k=0;k<10;k++)
  513. {if(numb[k]==n[0]) num[i+1]=nums[k];}
  514. for(k=0;k<10;k++)
  515. {if(numb[k]==n[1]) num[i+2]=nums[k];}
  516. for(k=0;k<10;k++)
  517. {if(numb[k]==n[2]) num[i+3]=nums[k];}
  518. for(k=0;k<10;k++)
  519. {if(numb[k]==n[3]) num[i+4]=nums[k];}
  520. for(k=0;k<10;k++)
  521. {if(numb[k]==n[4]) num[i+5]=nums[k];};break;
  522. }
  523. }
  524. word(210,2,num); //在屏幕上显示运算后的算式与答案
  525. Uart_Printf("Num1=%4d, Num2=%4d,F1=%4d\n",Num1,Num2,F1);
  526. op=0;
  527. opf=0;
  528. }
  529. }

LCD驱动部分:

  1. #define  GLOBAL_CLK 1
  2. #include "def.h"
  3. #include "option.h"
  4. #include "2440addr.h"
  5. #include "profile.h"
  6. #define LCD_WIDTH 240   //屏幕宽度
  7. #define LCD_HEIGHT 320  //屏幕高度
  8. #define CLKVAL 8        //时钟信号  索尼X35  LCD屏
  9. //垂直同步信号的脉宽、后肩和前肩
  10. #define VSPW (9-1)
  11. #define VBPD (2-1)
  12. #define VFPD (5-1)
  13. //水平同步信号的脉宽、后肩和前肩
  14. #define HSPW (5-1)
  15. #define HBPD (26-1)
  16. #define HFPD (1-1)
  17. //显示尺寸
  18. #define HOZVAL (LCD_WIDTH-1)
  19. #define LINEVAL (LCD_HEIGHT-1)
  20. //定义显示缓存,volatile声明编译不对此进行优化,直接读取原始地址
  21. volatile unsigned short LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
  22. //声明为静态函数,仅在本文件可见,其他文件不能使用该函数
  23. /**********************************
  24. *时钟初始化
  25. **********************************/
  26. void CLK_init(void)
  27. {
  28. rMPLLCON &= ~0xFFFFF;
  29. rMPLLCON |= (92<<12)|(1<<4)|1;  //初始化FCLK为400M
  30. rCLKDIVN = (2<<1)|1;  //HCLK = FCLK/4 = 100M,     PCLK = HCLK/2 = 50M
  31. FCLK = 400000000;     //400MHz
  32. HCLK = 100000000;     //100MHz
  33. PCLK = 50000000;      //50MHz
  34. UCLK = 48000000;      //48MHz
  35. rGPHCON = 0xa0;  //TXD[0]端口输出   RXD[0]端口接收
  36. rGPHUP  = 0x7ff; //禁止上拉电阻
  37. Uart_Init(0,115200);
  38. Uart_Select(0);
  39. }
  40. /**********************************
  41. *LCD端口初始化
  42. **********************************/
  43. void LCD_IO_init(void)
  44. {
  45. rGPCUP=0xff;    //GPC口上拉电阻不可用
  46. rGPCCON=0xaaaa02aa;//GPC8-15设置为VD, VM,VFRAME,VLINE,VCLK,LEND
  47. rGPDUP=0xff;    //GPD口上拉电阻不可用
  48. rGPDCON=0xaaaaaaaa; //GPD0-15设置为VD
  49. }
  50. /**********************************
  51. *LCD电源管理
  52. **********************************/
  53. void LCD_POWER(void)
  54. {
  55. rGPGUP=(1<<4);
  56. rGPGCON=(3<<8);       //GPG4设置为LCD_PWREN
  57. rLCDCON5=(1<<3);  //Enable PWREN signal
  58. }
  59. /**********************************
  60. *LCD开启
  61. **********************************/
  62. void LCD_on(void)
  63. {
  64. rLCDCON1 |=1;   //利用LCDCON1控制相关参数实现开启LCD
  65. }
  66. /**********************************
  67. *LCD关闭
  68. **********************************/
  69. void LCD_off(void)
  70. {
  71. rLCDCON1 &=~1;   //利用LCDCON1控制相关参数实现关闭LCD
  72. }
  73. /**********************************
  74. *LCD初始化
  75. **********************************/
  76. void LCD_init(void)
  77. {
  78. CLK_init();
  79. LCD_POWER();
  80. LCD_IO_init();
  81. LCD_on();
  82. rLCDCON1 = (CLKVAL<<8) | (3<<5) | (12<<1) | (0<<0);
  83. rLCDCON2 = (VBPD<<24) | (LINEVAL<<14) | (VFPD<<6) | (VSPW);
  84. rLCDCON3 = (HBPD<<19) | (HOZVAL<<8) | (HFPD);
  85. rLCDCON4 = HSPW;
  86. rLCDCON5 = (1<<11) | (1<<9) | (1<<8) | (1<<6) | (1<<3)|(0<<1)|(1);
  87. /*显存起始地址[30:22]保存到LCDSADDR1[29:21],显存始地址[21:1]位
  88. 保存到LCDSADDR1[20:0],显存结束地址[21:1]保存到LCDSADDR2[20:0]*/
  89. rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|(((U32)LCD_BUFFER&0x3fffff)>>1);
  90. rLCDSADDR2=(((U32)LCD_BUFFER+LCD_WIDTH*LCD_HEIGHT*2)>>1)&0x1fffff;
  91. rLCDSADDR3=LCD_WIDTH; //设置虚拟屏设置为屏幕宽度,没有可以不设置
  92. rTPAL=0; //临时调色板不可用
  93. rLCDINTMSK |=3; //屏蔽 LCD 中断
  94. rTCONSEL &=~(0x17);//LCC3600,LPC3600不可用
  95. }

GUI部分,字符,图片处理函数等

  1. #include "def.h"
  2. #include "Font_libs.h"
  3. #define LCD_WIDTH 240   //屏幕宽度
  4. #define LCD_HEIGHT 320  //屏幕高度
  5. //定义显示缓存,volatile声明编译不对此进行优化,直接读取原始地址
  6. extern volatile unsigned short LCD_BUFFER[LCD_HEIGHT][LCD_WIDTH];
  7. /**********************************
  8. *刷新背景颜色
  9. **********************************/
  10. void LCD_clear(U32 color)
  11. {
  12. U32 x,y;
  13. for(y=0;y<LCD_HEIGHT;y++)
  14. {
  15. for(x=0;x<LCD_WIDTH;x++)
  16. {
  17. LCD_BUFFER[y][x]=color;
  18. }
  19. }
  20. }
  21. /**********************************
  22. *BMP数组图片显示
  23. **********************************/
  24. void BMP_display(int x0,int y0,int x1,int y1,const U8 *bmp)
  25. {
  26. int x,y,p=0;
  27. U32 data;
  28. for(y=0;y<y1;y++)
  29. {
  30. for(x=0;x<x1;x++)
  31. {
  32. data=(bmp[p]<<8|bmp[p+1]);
  33. if((x0+x)<LCD_WIDTH && (y0+y)<LCD_HEIGHT)
  34. LCD_BUFFER[y0+y][x0+x]=data;
  35. p=p+2;
  36. }
  37. }
  38. }
  39. /**********************************
  40. *绘制像素点
  41. **********************************/
  42. void PutPixel(U32 x,U32 y,U32 c )
  43. {
  44. LCD_BUFFER[y][x]=c;
  45. }
  46. /**********************************
  47. *绘制大小为16×16的中文字符
  48. **********************************/
  49. void Draw_Text16(U32 x,U32 y,U32 color,const unsigned char ch[])
  50. {
  51. unsigned short int i,j;
  52. unsigned char mask,buffer;
  53. for(i=0;i<16;i++)
  54. {
  55. mask = 0x80;                   //掩码
  56. buffer=ch[i*2];                //提取一行的第一个字节
  57. for(j=0;j<8;j++)
  58. {
  59. if(buffer&mask)
  60. {
  61. PutPixel(x+j,y+i,color);        //为笔画上色
  62. }
  63. mask=mask>>1;
  64. }
  65. mask=0x80;                  //掩码复位
  66. buffer=ch[i*2+1];         //提取一行的第二个字节
  67. for(j=0;j<8;j++)
  68. {
  69. if(buffer&mask)
  70. {
  71. PutPixel(x+j+8,y+i,color);           //为笔画上色
  72. }
  73. mask=mask>>1;
  74. }
  75. }
  76. }
  77. /**********************************
  78. *绘制大小为8×16的ASCII码
  79. **********************************/
  80. void Draw_ASCII(U32 x,U32 y,U32 color,const unsigned char ch[])
  81. {                                    //ch[]为16个元素中,第一个元素的地址
  82. unsigned short int i,j;
  83. unsigned char mask,buffer;
  84. for(i=0;i<16;i++)    //__ASCII中连续16个元素组成一个字符图像
  85. {
  86. mask=0x80;
  87. buffer=ch[i];    //16个元素其中的一个
  88. for(j=0;j<8;j++)   //每一个元素占8位
  89. {
  90. if(buffer&mask)
  91. {
  92. PutPixel(x-i,y+j,color);
  93. }
  94. mask=mask>>1;
  95. }
  96. }
  97. }
  98. /**********************************
  99. *绘制中文字符或ASCII
  100. **********************************/
  101. void word(int x,int y,char* string)
  102. {
  103. int i,j=0;
  104. unsigned char qh,wh;
  105. const unsigned char *mould;
  106. int length=0;
  107. while(string[length]!=‘\0‘)
  108. {length++;}
  109. for(i=0;i<=length-1;i++)
  110. {
  111. if(string[i]&0x80)        //中文字符
  112. {
  113. qh=string[i]-0xa0;            //区号
  114. wh=string[i+1]-0xa0;          //位号
  115. mould=& __CHS[((qh-1)*94+wh-1)*32 ];
  116. Draw_Text16(x+j,y,0xffffff,mould);
  117. j+=16;//每写完一个右移16个像素
  118. i++;
  119. }
  120. else  //ASCII码字符
  121. {
  122. mould=&__ASCII[string[i]*16];
  123. Draw_ASCII(x,y+j,0xffffff,mould);
  124. j+=8;      //每写完一个右移8个像素
  125. }
  126. }
  127. }
  128. /**********************************
  129. *画直线
  130. **********************************/
  131. void Draw_Line(int x1,int y1,int x2,int y2,U32 color)
  132. {
  133. int dx,dy,e;
  134. dx=x2-x1;
  135. dy=y2-y1;
  136. if(dx>=0)
  137. {
  138. if(dy >= 0) // dy>=0
  139. {
  140. if(dx>=dy) // 1/8 octant
  141. {
  142. e=dy-dx/2;
  143. while(x1<=x2)
  144. {
  145. PutPixel(x1,y1,color);
  146. if(e>0){y1+=1;e-=dx;}
  147. x1+=1;
  148. e+=dy;
  149. }
  150. }
  151. else        // 2/8 octant
  152. {
  153. e=dx-dy/2;
  154. while(y1<=y2)
  155. {
  156. PutPixel(x1,y1,color);
  157. if(e>0){x1+=1;e-=dy;}
  158. y1+=1;
  159. e+=dx;
  160. }
  161. }
  162. }
  163. else           // dy<0
  164. {
  165. dy=-dy;   // dy=abs(dy)
  166. if(dx>=dy) // 8/8 octant
  167. {
  168. e=dy-dx/2;
  169. while(x1<=x2)
  170. {
  171. PutPixel(x1,y1,color);
  172. if(e>0){y1-=1;e-=dx;}
  173. x1+=1;
  174. e+=dy;
  175. }
  176. }
  177. else        // 7/8 octant
  178. {
  179. e=dx-dy/2;
  180. while(y1>=y2)
  181. {
  182. PutPixel(x1,y1,color);
  183. if(e>0){x1+=1;e-=dy;}
  184. y1-=1;
  185. e+=dx;
  186. }
  187. }
  188. }
  189. }
  190. else //dx<0
  191. {
  192. dx=-dx;     //dx=abs(dx)
  193. if(dy >= 0) // dy>=0
  194. {
  195. if(dx>=dy) // 4/8 octant
  196. {
  197. e=dy-dx/2;
  198. while(x1>=x2)
  199. {
  200. PutPixel(x1,y1,color);
  201. if(e>0){y1+=1;e-=dx;}
  202. x1-=1;
  203. e+=dy;
  204. }
  205. }
  206. else        // 3/8 octant
  207. {
  208. e=dx-dy/2;
  209. while(y1<=y2)
  210. {
  211. PutPixel(x1,y1,color);
  212. if(e>0){x1-=1;e-=dy;}
  213. y1+=1;
  214. e+=dx;
  215. }
  216. }
  217. }
  218. else           // dy<0
  219. {
  220. dy=-dy;   // dy=abs(dy)
  221. if(dx>=dy) // 5/8 octant
  222. {
  223. e=dy-dx/2;
  224. while(x1>=x2)
  225. {
  226. PutPixel(x1,y1,color);
  227. if(e>0){y1-=1;e-=dx;}
  228. x1-=1;
  229. e+=dy;
  230. }
  231. }
  232. else        // 6/8 octant
  233. {
  234. e=dx-dy/2;
  235. while(y1>=y2)
  236. {
  237. PutPixel(x1,y1,color);
  238. if(e>0){x1-=1;e-=dy;}
  239. y1-=1;
  240. e+=dx;
  241. }
  242. }
  243. }
  244. }
  245. }
  246. /**************************************************************
  247. 在LCD屏幕上画一个矩形
  248. **************************************************************/
  249. void Draw_REC(int x1,int y1,int x2,int y2,U32 color)
  250. {
  251. Draw_Line(x1,y1,x2,y1,color);
  252. Draw_Line(x2,y1,x2,y2,color);
  253. Draw_Line(x1,y2,x2,y2,color);
  254. Draw_Line(x1,y1,x1,y2,color);
  255. }
  256. /**********************************
  257. *画圆函数
  258. **********************************/
  259. void Draw_Circular(U32 c)
  260. {
  261. int x,y ;
  262. int tempX,tempY;
  263. int radius=80;
  264. int SquareOfR=radius*radius;
  265. for( y=0;y<LCD_WIDTH;y++ )
  266. {
  267. for( x=0; x<LCD_HEIGHT;x++ )
  268. {
  269. if(y<=120&&x<=160)
  270. {
  271. tempY=120-y;
  272. tempX=160-x;
  273. }
  274. else if(y<=120&&x>=160)
  275. {
  276. tempY=120-y;
  277. tempX=x-160;
  278. }
  279. else if(y>=120&& x<=160)
  280. {
  281. tempY=y-120;
  282. tempX=160-x;
  283. }
  284. else
  285. {
  286. tempY=y-120;
  287. tempX=x-160;
  288. }
  289. if ((tempY*tempY+tempX*tempX)<=SquareOfR)
  290. LCD_BUFFER[y][x] =c;
  291. }
  292. }
  293. }
  294. void Draw_X(int x,int y,U32 color)
  295. {
  296. Draw_Line(x-20,y,x+20,y,color);
  297. Draw_Line(x,y-20,x,y+20,color);
  298. }

触摸屏的ADC驱动部分:

  1. #include "def.h"
  2. #include "mmu.h"
  3. #include "2440addr.h"
  4. #include "2440lib.h"
  5. #define PRSCVL 9
  6. volatile int xdata, ydata;
  7. int inte=1;
  8. void __irq Adc_Tc_Handler(void);
  9. void Touch_Init(void)
  10. {
  11. rADCCON=((1<<14)|(PRSCVL<<6));    //A/D分频时钟有效,其值为9
  12. rADCTSC=0xd3;  //光标按下中断信号,YM有效,YP无效,XM有效,XP无效,XP上拉电阻,普通ADC转换,等待中断模式
  13. rADCDLY=50000; //正常转换模式转换延时大约为(1/3.6864M)*50000=13.56ms
  14. rINTSUBMSK &=~(1<<9);//TC中断使能
  15. rINTMSK &=~(1<<31);//ADC总中断使能
  16. pISR_ADC=(int)Adc_Tc_Handler;//指向中断向量表
  17. }
  18. void __irq Adc_Tc_Handler(void)
  19. {
  20. rADCTSC|=(1<<3)|(1<<2); //XP上拉电阻无效, 自动连续测量X坐标和Y坐标.
  21. rADCCON|=(1<<0);//ADC转换开始
  22. while(rADCCON&(1<<0));//检测ADC转换是否开始且ADCCON[0]自动清0
  23. while(!(rADCCON&(1<<15))); //检测ADCCON[15]是否为1,ADC转换是否结束,(必须)
  24. while(!(rINTPND&(1<<31)));//检测ADC中断是否已请求
  25. xdata=rADCDAT0&0x3ff;//读x坐标
  26. ydata=rADCDAT1&0x3ff;//读y坐标
  27. Uart_Printf("\nXdata=%04d, Ydata=%04d\n", xdata, ydata);
  28. rSUBSRCPND|=(1<<9);
  29. rSRCPND|=(1<<31);
  30. rINTPND|=(1<<31);
  31. rADCTSC =0xd3;     //ADC等待中断模式
  32. rADCTSC|=(1<<8);  //ADCTSC[8]=1,设置抬起中断信号
  33. while(!(rSUBSRCPND&(1<<9)));  //检测触屏抬起中断是否已请求
  34. rADCTSC &=~(1<<8);//ADCTSC[8]=0光标按下中断信号
  35. rSUBSRCPND|=(1<<9);
  36. rSRCPND|=(1<<31);
  37. rINTPND|=(1<<31);
  38. inte=1;
  39. }

触摸屏矫正及其计算部分(三点矫正):

  1. #include "def.h"
  2. #include "2440addr.h"
  3. #include "2440lib.h"
  4. #define LCD_CALIBRATE 0  //1时打开触摸屏校验
  5. #define BLACK (0x000000)  //黑色
  6. #define WHITE (0xffffff)  //白色
  7. #define YdataClear ydata=0
  8. #define XdataClear xdata=0
  9. extern volatile int xdata, ydata;
  10. extern int inte;
  11. extern void LCD_clear(U32 n);
  12. extern void Draw_X(int x,int y,U32 color);
  13. extern void CLK_init(void);
  14. extern void LCD_IO_init(void);
  15. extern void LCD_POWER(void);
  16. extern void LCD_init(void);
  17. extern void LCD_on(void);
  18. extern void LCD_off(void);
  19. extern void Touch_Init(void);
  20. U32 X,Y;
  21. float x0,y0,x1,y1,x2,y2;
  22. float xt,yt;
  23. float K = -281780, A = -0.293846, B = 0.000568, C = 271.255585, D = 0.007808, E = 0.400951, F = -54.646889;
  24. //读取TC坐标
  25. void Touch_GetAdXY(float *x,float *y)
  26. {
  27. *x=xdata;
  28. *y=ydata;
  29. }
  30. //矫正参数A,B,C,D,E,F,K的计算
  31. void Calculate_P(float xt0,float yt0,float xt1,float yt1,float xt2,float yt2)
  32. {
  33. float xd0=160,yd0=40,xd1=40,yd1=180,xd2=260,yd2=200;
  34. K=(xt0-xt2)*(yt1-yt2)-(xt1-xt2)*(yt0-yt2);
  35. A=((xd0-xd2)*(yt1-yt2)-(xd1-xd2)*(yt0-yt2))/K;
  36. B=((xt0-xt2)*(xd1-xd2)-(xd0-xd2)*(xt1-xt2))/K;
  37. C=(yt0*(xt2*xd1-xt1*xd2)+yt1*(xt0*xd2-xt2*xd0)+yt2*(xt1*xd0-xt0*xd1))/K;
  38. D=((yd0-yd2)*(yt1-yt2)-(yd1-yd2)*(yt0-yt2))/K;
  39. E=((xt0-xt2)*(yd1-yd2)-(yd0-yd2)*(xt1-xt2))/K;
  40. F=(yt0*(xt2*yd1-xt1*yd2)+yt1*(xt0*yd2-xt2*yd0)+yt2*(xt1*yd0-xt0*yd1))/K;
  41. }
  42. //数据的矫正
  43. void Tc_Correct(float xt,float yt)
  44. {
  45. X=(U32)(A*xt+B*yt+C);
  46. Y=(U32)(D*xt+E*yt+F);
  47. }
  48. //触摸屏矫正函数
  49. void Tc_calibrate(void)
  50. {
  51. #if LCD_CALIBRATE==1
  52. CLK_init();
  53. LCD_POWER();
  54. LCD_IO_init();
  55. LCD_init();
  56. LCD_on();
  57. Touch_Init();
  58. LCD_clear(BLACK);//全屏显示黑色
  59. //位置1
  60. Draw_X(160,40,WHITE);
  61. YdataClear;
  62. XdataClear;
  63. while(1)
  64. {
  65. Touch_GetAdXY(&x0,&y0);//读取坐标位置
  66. if((252<y0)&&(y0<256))//按键按下
  67. {
  68. Draw_X(160,40,BLACK);
  69. break;
  70. }
  71. }
  72. //位置2
  73. Draw_X(40,180,WHITE);
  74. YdataClear;
  75. XdataClear;
  76. while(1)
  77. {
  78. Touch_GetAdXY(&x1,&y1);//读取坐标位置
  79. if((702<y1)&&(y1<706))//按键按下
  80. {
  81. Draw_X(40,180,BLACK);
  82. break;
  83. }
  84. }
  85. //位置3
  86. Draw_X(260,200,WHITE);
  87. YdataClear;
  88. XdataClear;
  89. while(1)
  90. {
  91. Touch_GetAdXY(&x2,&y2);//读取坐标位置
  92. if((762<y2)&&(y2<764))//按键按下
  93. {
  94. Draw_X(260,200,BLACK);
  95. break;
  96. }
  97. }
  98. Calculate_P(x0,y0,x1,y1,x2,y2);
  99. #endif
  100. if(inte)
  101. {
  102. Touch_GetAdXY(&xt,&yt);//读取坐标位置
  103. Tc_Correct(xt,yt);
  104. Uart_Printf("X=%4d, Y=%4d\n",X,Y);
  105. inte=0;
  106. }
  107. }

Font_libs.h  http://download.csdn.net/detail/lc123yx/8322405

时间: 2024-08-03 19:25:00

基于mini2440简易计算器的相关文章

基于mini2440简易计算器(二)

在LCD屏幕上显示数字 /********************************** *绘制大小为8×16的ASCII码 **********************************/ void Draw_ASCII(U32 x,U32 y,U32 color,const unsigned char ch[]) {                                    //ch[]为16个元素中,第一个元素的地址 unsigned short int i,j;

基于Tkinter用50行Python代码实现简易计算器

Tkinter一般是python自带的,所以代码不需要其他组件,本程序是在python2.7版本实现的. 主要涉及了tkinter的使用,函数定义和调用,匿名函数的使用,类成员函数定义等python基础知识,适合新手学习. 代码如下: from Tkinter import * #创建横条型框架 def frame(root, side): w = Frame(root) w.pack(side = side, expand = YES, fill = BOTH) return w #创建按钮

制作一个简易计算器——基于Android Studio实现

一个计算器Android程序的源码部分分为主干和细节两部分. 一.主干 1. 主干的构成 计算器的布局 事件(即计算器上的按钮.文本框)监听 实现计算 2. 详细解释 假设我们的项目名为Calculator,而布局名称(Layout Name)为默认的activity_main .即设置如下图所示: 在这种前提下,有: 设置计算器布局的文件:Calculator/app/src/main/res/layout/activity_main.xml 事件监听和计算实现在同一个文件里:Calculat

函数调用_猜数字和简易计算器

package app1; import java.util.*; public class TestFunction{     public static void main(String[] args){         Scanner sc=new Scanner(System.in);         System.out.print("请选择一项应用:\n1.猜数字\n2.简易计算器");         int n=sc.nextInt();         switch(

如何用jsp实现一个简易计算器(三)

做这个jsp页面,主要是为了实现在同一个页面提交和接受数据的功能. 这个小程序存在很多不足,希望大家多多批评指正. <%@ page language="java" contentType="text/html;" pageEncoding="gbk"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://w

C# 简易计算器

编写如下界面的简易计算器界面代码: using System; using System.Windows.Forms; using exp; namespace calculator { public partial class Form1 : Form { public Form1() { InitializeComponent(); } enum symbol { plus,dec,mult,div}; private void button1_Click(object sender, Ev

PyQt5 简易计算器

剩下计算函数(self.calculator)未实现,有兴趣的朋友可以实现它 [知识点] 1.利用循环添加按钮部件,及给每个按钮设置信号/槽 2.给按钮设置固定大小:button.setFixedSize(QtCore.QSize(60,30)) 3.取事件的的发送者(此例为各个按钮)的文本: self.sender().text() [效果图] [源代码] 1 import sys 2 from PyQt5 import QtWidgets,QtCore,QtGui 3 4 5 class E

java简易计算器

此小程序实现了计算器的基本功能: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SimpleCalc extends JFrame{ private static final long serialVersionUID = 1L; String[] labels = {"←","CE","±","√", "

js css 实现简易计算器

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-