【MCU方案】MSP430F149制作无线遥控手柄实例分享,欢迎指导

[复制链接]
3681|15
 楼主| liuxing4585 发表于 2015-6-11 08:56 | 显示全部楼层 |阅读模式
本帖最后由 liuxing4585 于 2015-6-17 22:09 编辑

【MCU方案】MSP430F149制作无线遥控手柄

          在很多设备中,由于现场环境要求或者是提高效率,常常需要遥控手柄进行参数设置修改,设备启停控制等,在这里我来分享一个曾经做过的实例项目,通过MSP430F149实现无线遥控手柄,可以更改不同程序实现不同设备控制,水平有限,欢迎大家指导拍砖。
        
      一.  项目需求:
          1.液晶显示(字体易辨认,显示明了)。
          2.键盘输入(需要考虑输入方便,操作简单)。
          3.电池供电(需要考虑功耗和方便使用)。
          4.无线通讯(需要考虑功耗和方便使用)。
      二.系统框图:

        三.硬件选型:
       1芯片选择:
          由于定位为手持设备,需要电池供电,所以必须考虑功耗问题。MSP430成为首选。简单介绍一下所选的芯片:
          MSP430F149是一种新型的混合信号处理器,采用了美国德州仪器(Texas Instruments)公司最新低功耗技术(工作电流为0.1一400 p A ),它将大量的外围模块整合到片内,特别适合于开发和设计单片系统。
MSP430 F149单片机主要具有如下特点:
        1.低电压、超低功耗。工作电压3.6V~1.8V ,正常工作模式280μA@1MHz,2.2V,待机模式1.6μA,RAM数据保存的掉电模式下0.1μA。 五级节电模式。
       2.快速苏醒,从待机模式下恢复工作,只需要不到6μS时间。
       3.16位精简指令集MCU,命令周期125nS。
       4.12位ADC,具有内部参考电压源,并且具有采样、保持、自动扫描等功能。具有12位的模数转换器可以得到很高的精度,并且省去了使用专门的模数转换器给设计电路板带来的麻烦。
       5.2个16位计数器。具有捕获、门限功能。
       6.具有片内比较器。
       7.支持ISP(在线系统编程),方便开发和项目升级。
       8.支持序列号,熔丝位烧写。方便简单。
       9.双串口
      10.支持超小型封装:64P-QFP、64P-QFN。
      11.拥 有 大容量的存储空间。存储器方面包括多达60 k Flash ROM和2 k RAM,如此数量的存储空间完全可以满足程序及数据的需要。
      12. 硬件乘法器。该乘法器独立于CPU进行乘法运算的操作,在提高乘法运算速度的同时也提升了CPU的利用效率。
      13.串行在系统编程。通过仿真器对程序进行下载,并通过专用软件对程序及单片机的工作状态进行监控,极大地方便了程序的调试。
从以上特点可知,使用MSP430满足要求。
   2:   通讯模块
          采购市场上现有模块,所以只需留出接口即可。
    3:   键盘模块
          采购市场上现有模块,所以只需适配接口即可。
    4:电池
4节AAA充电电池,方便更换充电,适合现场使用。成品图片:









四.系统原理图:

电源电路:实现6v转3.3v

mcu:

JTAG接口

电池电量检测


键盘接口



通讯接口
显示接口




五.源代码:

电池电量检测:
  1. #include <msp430F149.h>
  2. #define   Num_of_Results   32

  3. static uint results[Num_of_Results];    //保存ADC转换结果的数组
  4. void Trans_val(uint Hex_Val);           
  5. void ADC_Init(void);
  6. /***************ADC_Init函数************/
  7. void ADC_Init(void)
  8. {
  9.   P6SEL |= 0x01;                            // 使能ADC通道
  10.   ADC12CTL0 = ADC12ON+SHT0_8+MSC;           // 打开ADC,设置采样时间
  11.   ADC12CTL1 = CSTARTADD_0+SHP+CONSEQ_2;     // 选择存储器地址,使用采样定时器
  12.   ADC12MCTL7 = INCH_0;                      // 选择采样通道7
  13.   ADC12IE = BIT0;                           // 使能ADC中断
  14.   ADC12CTL0 |= ENC;                         // 使能转换
  15.   ADC12CTL0 |= ADC12SC;                     // 开始转换
  16. }
  17. /*******************************************
  18. 函数名称:ADC12ISR
  19. 功    能:ADC中断服务函数,在这里用多次平均的
  20.           计算P6.7口的模拟电压数值
  21. 参    数:无      
  22. 返回值  :无
  23. ********************************************/
  24. #pragma vector=ADC_VECTOR
  25. __interrupt void ADC12ISR (void)
  26. {
  27.   static uint index = 0;

  28.   results[index++] = ADC12MEM0;               // Move results
  29.   if(index == Num_of_Results)
  30.   {
  31.         uchar i;
  32.         unsigned long sum = 0;

  33.         index = 0;
  34.         for(i = 0; i < Num_of_Results; i++)
  35.         {
  36.             sum += results[i];
  37.         }
  38.         sum >>= 5;                            //除以32
  39.         
  40.         Trans_val(sum);
  41.   }
  42. }

  43. /*******************************************
  44. 函数名称:Trans_val
  45. 功    能:将16进制ADC转换数据变换成三位10进制
  46.           真实的模拟电压数据,
  47. 参    数:Hex_Val--16进制数据
  48.           n--变换时的分母等于2的n次方      
  49. 返回值  :无
  50. ********************************************/
  51. void Trans_val(uint Hex_Val)
  52. {

  53.     caltmp = Hex_Val;
  54.     caltmp = (caltmp << 5) + Hex_Val;           //caltmp = Hex_Val * 33
  55.     caltmp = (caltmp << 3) + (caltmp << 1);     //caltmp = caltmp * 10
  56.     Curr_Volt = caltmp >> 12;                   //Curr_Volt = caltmp / 2^n
  57.    Curr_Volt+=Curr_Volt<<1;
  58.    
  59. }
主程序:
  1. /*******************************************************************************
  2. **液晶采用ZX12864I-2,带中文字库
  3. **单片机采用的是MSP430F149
  4.                    电路连接图
  5.                 _______________
  6.            8   |               |<--
  7.     Data---/---| P2            |   8MHz
  8.                |               |<--
  9.       Rs-------| P3.5          |
  10.       Rw-------| P3.6          |  4
  11.        E-------| P3.7    P4.0-7|--/---KEY
  12.                |_______________|
  13.                   MSP430F149

  14.   
  15.                ___________________________  
  16.                |0x7f/功能FUN 0xfe/开关POWER|  
  17.                |0xbf/清零CLS 0xfd/标定COMP |
  18.                |0xdf/增加UP  0xfb/减少DOWN |
  19.                |0xef/取消ESC 0xf7/确认ENTER|   
  20.                |___________________________|

  21. *******************************************************************************/
  22. #include "define.h"
  23. #include "ADC.h"
  24. #include "flash.h"
  25. #include "lcd12864.h"
  26. #include "uart.h"
  27. #include "menu.h"

  28. //******************************************************************************/
  29. #include <msp430x14x.h>

  30. void main(void)
  31. {  
  32.   init_clk();
  33.   WDTCTL = WDTPW + WDTHOLD;
  34.   FCTL2 = FWKEY + FSSEL_1 + FN1;              //工作频率设为  MCLK/3,333.3KHZ

  35.   _DINT();  
  36.   pc_flash = (unsigned char *) FLASH_ADDRESS;         //为指针初始化
  37.   pc_flash_segment = (unsigned int *) FLASH_ADDRESS;  
  38.   read_array(pc_flash,checkout,4);                    //再读出刚才写的字节
  39.   if(checkout[0]!=0x01)
  40.   {  flash_erase( pc_flash_segment);                     //段擦除
  41.      write_array(pc_flash, write_buff,4);               //写入指定字节数量
  42.     _NOP();
  43.   }
  44.   read_array(pc_flash,checkout,4);                    //再读出刚才写的字节
  45.   bal=checkout[1];
  46.   init_lcdport();
  47.   CCTL0=CCIE;
  48.   CCR0=10;
  49.   TACTL=TASSEL_2+TACLR+MC_1+ID_3;
  50.   LED=1;
  51.   PowerDown=0;
  52.   P5DIR|=BIT0; //输出端口
  53.   P5OUT|=0x01;
  54.     WDTCTL = WDT_ADLY_1000;       // 设置内部看门狗工作在定时器模式,1000ms中断一次
  55.     IE1 |= WDTIE;                 // 使能看门狗中断
  56.      _EINT();
  57.     init_lcd();
  58.     Disp_HZ(0,1,"  系统正在启动  ",8);
  59.     Disp_HZ(0,2,"    请您稍后    ",8);
  60.     jindutiao(3,1); jindutiao(3,1);
  61.     jindutiao(3,1); jindutiao(3,1);
  62.     jindutiao(3,1); jindutiao(3,1);
  63.     jindutiao(3,1); jindutiao(3,1);
  64.     jindutiao(3,1); jindutiao(3,1);
  65.    
  66.     Disp_HZ(0,1,"  系统初始化中  ",8);
  67.     Disp_HZ(0,2,"    请您稍后    ",8);
  68.     jindutiao(3,1); jindutiao(3,1);
  69.     jindutiao(3,1); jindutiao(3,1);
  70.     jindutiao(3,1); jindutiao(3,1);
  71.     jindutiao(3,1); jindutiao(3,1);
  72.     jindutiao(3,1); jindutiao(3,1);
  73.     Uartinit();
  74.     Search();
  75.     menu_disp();
  76.   

  77.   while(1)
  78.   {
  79.     key_process();
  80.     if(key==UP||key==DOWN||key==ENTER||key==ESC)
  81.        {
  82.         switch(key)
  83.          {
  84.         case DOWN :
  85.           userchoose++;
  86.           if(userchoose == maxitems)
  87.           {
  88.             userchoose = 0;
  89.           }
  90.           break;
  91.         case UP :
  92.           userchoose--;
  93.           if(userchoose == 255)
  94.           {
  95.             userchoose = maxitems - 1;
  96.           }
  97.           break;
  98.         case ENTER :
  99.           if(menupoint[userchoose].subs != nullsubs)
  100.           {
  101.             (*menupoint[userchoose].subs)();
  102.           }
  103.           else if(menupoint[userchoose].childrenmenu != Null)
  104.           {
  105.             menupoint = menupoint[userchoose].childrenmenu;
  106.             userchoose = 0;
  107.             displaystart = 0;
  108.           }
  109.           break;
  110.         case ESC :
  111.           if(menupoint[userchoose].parentmenu != Null)
  112.           {
  113.             menupoint = menupoint[userchoose].parentmenu;
  114.             userchoose = 0;
  115.             displaystart = 0;
  116.           }
  117.           break;  
  118.         default : break;  
  119.         }
  120.         key=Null;
  121.         menu_disp();
  122.       
  123.       }
  124.     else if(key==COMP)
  125.          {
  126.            key=Null;
  127.            AdjWeight();
  128.          }
  129.     else if(key==CLS)
  130.     {  
  131.        key=Null;
  132.        ClsWeight();
  133.     }
  134.   }
  135. }
  136. /*******************************************
  137. 函数名称:watchdog_timer
  138. 功    能:看门狗中断服务函数,控制液晶背光和自动关机
  139. 参    数:无
  140. 返回值  :无
  141. ********************************************/
  142. #pragma vector=WDT_VECTOR
  143. __interrupt void watchdog_timer(void)
  144. {
  145.     cnt++;   
  146.     if (cnt>25) LED=0;
  147.     if (cnt>90)PowerOff();
  148.     if(adc==1)  Disp_NUM(4,1,Curr_Volt,1,0);
  149.     if(wait==1) timeout++;
  150. }

  151. //*******************************************
  152. //函数名称:Timer_A
  153. //功    能:定时器A中断服务子函数
  154. //参    数:无
  155. //返回值  :无
  156. //********************************************
  157. #pragma vector=TIMERA0_VECTOR
  158. __interrupt void Timer_A (void)
  159. {
  160.   if(ledtime<100)ledtime++;
  161.   else ledtime=0;
  162.   if (LED==1&&ledtime<bal)
  163.   LCD_LED_L;
  164. else
  165.   LCD_LED_H;
  166. }
  167. void jindutiao(uchar dispy,uchar time)
  168. { uchar i;
  169. for(i=0;i<7;i++)
  170.   {Disp_HZ(i,dispy,"■",1);
  171.    Delay_Nms(time*300);
  172.   }
  173. Disp_HZ(0,dispy,"               ",8);
  174. }





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

打赏榜单

hbzjt2011 打赏了 0.10 元 2015-07-01

21ic小喇叭 打赏了 3.00 元 2015-06-15

 楼主| liuxing4585 发表于 2015-6-11 08:59 | 显示全部楼层
菜单:
  1. #include "flash.h"
  2. #include "define.h"
  3. //************************************空函数************************************
  4. //函数名称: nullsubs
  5. //函数说明: 无
  6. //入口参数: 无
  7. //出口参数: 无
  8. //******************************************************************************
  9. void nullsubs(void)
  10. {
  11. }

  12. //******************************************************************************

  13. struct menu{
  14. unsigned char menucount; //当前层节点数
  15. unsigned char *str; //菜单标题
  16. unsigned char pos;
  17. unsigned char length;
  18. void (*subs)(); //节点函数
  19. struct menu *childrenmenu; //子节点
  20. struct menu *parentmenu; //父节点
  21. };

  22. struct menu1{
  23. unsigned char *str1;
  24. unsigned char pos1;
  25. unsigned char length1;
  26. };


  27. //******************************************************************************

  28. //******************************菜单显示内容************************************
  29. //说明: 结构体中放的是菜单的显示内容等参数,完成菜单功能变换,菜单返回
  30. // 菜单指针函数、可以指向下一级菜单,也可以指向某一项选项的功能
  31. // 实际中可以根据具体内容变换。
  32. //******************************************************************************
  33. struct menu1 menu2[2][4] = {
  34. {
  35. {"功┃",0x80,2},
  36. {"能┃",0x90,2},
  37. {"选┃",0x88,2},
  38. {"择┃",0x98,2}
  39. },
  40. {
  41. {"其┃",0x80,2},
  42. {"它┃",0x90,2},
  43. {"功┃",0x88,2},
  44. {"能┃",0x98,2}
  45. }
  46. };

  47. struct menu main_menu[8];
  48. struct menu other_menu[4];

  49. struct menu main_menu[8] = {
  50. {8,"1.目标设定",0x82,5,SetValue,Null,Null},
  51. {8,"2.全部增加",0x92,5,AllAdd,Null,Null},
  52. {8,"3.全部减少",0x8a,5,AllDec,Null,Null},
  53. {8,"4.包机搜索",0x9a,5,Search,Null,Null},
  54. {8,"5.称重清零",0x82,5,ClsWeight,Null,Null},
  55. {8,"6.电池电压",0x92,5,ADC,Null,Null},
  56. {8,"7.背光调整",0x8a,5,BaL,Null,Null},
  57. {8,"8.厂家设置",0x9a,5,PassWords,Null,Null},
  58. };

  59. struct menu other_menu[4] = {
  60. {4,"1.称重标定",0x82,5,AdjWeight,Null,main_menu},
  61. {4,"2.包机站号",0x92,5,SetAddress,Null,main_menu},
  62. {4,"3.包机子站",0x8a,5,SetStation,Null,main_menu},
  63. {4,"4.返回上级",0x9a,5,nullsubs,main_menu,main_menu}
  64. };
  65. //******************************************************************************

  66. //************************************全局变量**********************************
  67. struct menu (*menupoint) = main_menu; //结构体指针,指向结构体后由内部函数指针指向功能函数

  68. //******************************************************************************

  69. void PowerOff(void)
  70. {


  71. clrram();
  72. Disp_HZ(0,1," 正在关机 ",8);
  73. jindutiao(2,1);
  74. jindutiao(2,1);
  75. jindutiao(2,1);
  76. clrram();
  77. _DINT();
  78. LCD_LED_H;

  79. E_0;
  80. P5OUT&=0xfe;
  81. }

  82. void findkey(void)
  83. {

  84. switch(P4IN)
  85. {
  86. case 0xFB :
  87. key = DOWN;
  88. break;
  89. case 0xDF :
  90. key = UP;
  91. break;
  92. case 0xF7 :
  93. key = ENTER;
  94. break;
  95. case 0xEF :
  96. key = ESC;
  97. break;
  98. case 0x7F :
  99. key = FUN;
  100. break;
  101. case 0xBF :
  102. key = CLS;
  103. break;
  104. case 0xFD :
  105. key = COMP;
  106. break;
  107. case 0xFE :
  108. key = POWER;
  109. break;
  110. case 0x7d :
  111. key = FUN_COMP;
  112. break;
  113. default :
  114. key= Null ;
  115. break;
  116. }
  117. }

  118. //***********************************待处理函数*********************************
  119. //函数名称: aa
  120. //函数说明: 实际中要替换为具体函数原型,这里只是举例说明
  121. //入口参数: 无
  122. //出口参数: 无
  123. //******************************************************************************
  124. void aa(void)
  125. {
  126. clrram();
  127. Disp_HZ(1,1,"数据发送中",5);
  128. jindutiao(2,4);
  129. if (wait==0)
  130. {
  131. Disp_HZ(1,1," 发送成功",5);
  132. jindutiao(2,1);
  133. }
  134. else
  135. { clrram();
  136. Disp_HZ(1,1," 通讯失败",5);
  137. Disp_HZ(1,2," 请重试 ",5);

  138. while(1)
  139. {
  140. key=Null;
  141. key_process();
  142. if(key==ENTER||key==ESC)
  143. {key=Null;
  144. break;
  145. }
  146. }
  147. }
  148. clrram();
  149. }

  150. void init_clk(void)
  151. {
  152. uchar i;
  153. BCSCTL1 &= ~XT2OFF; // XT2 = HF XTAL

  154. do
  155. {
  156. IFG1 &= ~OFIFG; // Clear OSCFault flag
  157. for (i = 0xFF; i > 0; i--); // Time for flag to set
  158. }
  159. while ((IFG1 & OFIFG) != 0); // OSCFault flag still set?

  160. BCSCTL2 |= SELM1; // MCLK = XT2 (safe)
  161. }

  162. //************************************菜单显示**********************************
  163. //函数名称: void menu_disp(uchar n)
  164. //函数说明: 显示主菜单
  165. //入口参数: uint n,要显示的菜单级数号码
  166. //出口参数: 无
  167. //******************************************************************************
  168. void menu_disp(void)
  169. {
  170. uchar i;
  171. clrram();
  172. maxitems = menupoint[0].menucount;
  173. if(userchoose < 4 && maxitems < 5)
  174. {
  175. for(i = 0 ;i < maxitems;i++)
  176. {
  177. wch_disp(menupoint[i].str,menupoint[i].pos,menupoint[i].length);
  178. }
  179. }
  180. else if(userchoose < 4 && maxitems >= 5)
  181. {
  182. for(i = 0;i < 4;i++)
  183. {
  184. wch_disp(menupoint[i].str,menupoint[i].pos,menupoint[i].length);
  185. }
  186. }
  187. else if(userchoose >= 4)
  188. {
  189. clrram();
  190. clrram();
  191. for(i = 0; i < maxitems - 4;i ++)
  192. {
  193. wch_disp(menupoint[i + 4].str,menupoint[i + 4].pos,menupoint[i + 4].length);
  194. }
  195. }
  196. if(menupoint == main_menu)
  197. {
  198. for(i = 0; i < 4;i ++)
  199. {
  200. wch_disp(menu2[0][i].str1,menu2[0][i].pos1,menu2[0][i].length1);
  201. }
  202. }
  203. else if(menupoint == other_menu)
  204. {
  205. for(i = 0; i < 4;i ++)
  206. {
  207. wch_disp(menu2[1][i].str1,menu2[1][i].pos1,menu2[1][i].length1);
  208. }
  209. }
  210. con_wch_disp(menupoint[userchoose].pos,menupoint[userchoose].length);
  211. }
  212. //******************************************************************************

  213. //************************************键盘处理**********************************
  214. //函数名称: key_process
  215. //函数说明: 键盘处理
  216. //入口参数: 无
  217. //出口参数: 无
  218. //******************************************************************************
  219. void key_process(void)
  220. {
  221. if(P4IN!=0xff)
  222. {
  223. LED=1;
  224. cnt=0;
  225. Delay_Nms(KeyDelay);//延时消抖
  226. while(P4IN!=0xff)
  227. { cnt=0;
  228. findkey();
  229. Presstime++;
  230. if (Presstime > LongPress*2 && (key == DOWN||key == UP||key == FUN_COMP) )//判断长按
  231. {
  232. break;
  233. }
  234. else if (Presstime > LongPress*2 && (key == POWER)) //判断长按
  235. {
  236. PowerOff();
  237. LPM4;
  238. break;
  239. }
  240. }
  241. if((P4IN!=0xff) && (key == DOWN||key == UP)&&Setvalues==1)
  242. { PresstimeLong++;

  243. if(PresstimeLong>=10&&PresstimeLong<20) key+=10;
  244. if(PresstimeLong>=20) key+=20;
  245. }
  246. }
  247. if(P4IN==0xff)
  248. {
  249. Presstime=0;
  250. PresstimeLong=0;
  251. }
  252. }
  253. void readall(uchar nus)
  254. { uchar i;
  255. clrram();
  256. Disp_HZ(0,1,"**数据读取中****",8);
  257. Disp_HZ(0,2," 读取 号",5);

  258. if(nus>=1&&nus<=MaxStation[NowMainStation])
  259. {
  260. Disp_NUM(3,2,nus,0,0);
  261. readstation(NowMainStation,nus,0x00,0x00);
  262. jindutiao(3,1);
  263. }
  264. else
  265. {
  266. for(i=1;i<=MaxStation[NowMainStation];i++)
  267. { Disp_NUM(3,2,i,0,0);
  268. readstation(NowMainStation,i,0x00,0x00);
  269. jindutiao(3,1);
  270. }
  271. }
  272. if(nus>=1&&nus<=MaxStation[NowMainStation])
  273. {
  274. Disp_NUM(3,2,nus,0,0);
  275. readstation(NowMainStation,nus,0x00,0x00);
  276. jindutiao(3,1);
  277. }
  278. else
  279. {
  280. for(i=1;i<=MaxStation[NowMainStation];i++)
  281. { Disp_NUM(3,2,i,0,0);
  282. readstation(NowMainStation,i,0x00,0x00);
  283. jindutiao(3,1);
  284. }
  285. }

  286. if (wait==1)
  287. {Disp_HZ(1,1," 通讯失败",5);
  288. Disp_HZ(1,2," 请重试 ",5);
  289. while(1)
  290. {
  291. key=Null;
  292. key_process();
  293. if(key==ENTER||key==ESC)
  294. {key=Null;
  295. break;
  296. }
  297. }
  298. }


  299. }

  300. void Search(void)

  301. {
  302. clrram();
  303. Disp_HZ(0,0,"**搜索可用包机**",8);
  304. Disp_HZ(0,1," 搜索 号 ",8);
  305. MainsCounter=0;

  306. for(stations=Num_of_main;stations>=1;stations--)
  307. { cnt=0;
  308. readstation(stations,0xf0,0x07,0);
  309. Disp_NUM(4,1,stations,0,0);
  310. jindutiao(3,1);
  311. Disp_HZ(0,2," 搜到 个 ",8);
  312. Disp_NUM(4,2,MainsCounter,0,0);
  313. }

  314. if (MainsCounter>0)
  315. {
  316. MaxMainS=MainsCounter-1;
  317. Disp_HZ(0,1," 包机搜索完毕 ",8);
  318. Disp_HZ(0,2," 搜到 个 ",8);
  319. Disp_NUM(4,2,MainsCounter,0,0);
  320. Disp_HZ(0,3," ◆选择 号 ",8);
  321. NowMainStation=MainStation[0];
  322. Disp_NUM(4,3,NowMainStation,0,0);
  323. }
  324. else
  325. {
  326. clrram();
  327. Disp_HZ(0,0,"**搜索包机失败**",8);
  328. Disp_HZ(0,1," 请您重新搜索 ",8);
  329. Disp_HZ(0,2," 按任意键返回 ",8);
  330. }
  331. key=Null;
  332. while(key==Null)
  333. {
  334. key_process();
  335. if(MainsCounter==0)
  336. {
  337. if(key!=Null)
  338. {
  339. key=Null;
  340. break;
  341. }
  342. }
  343. else
  344. {
  345. if(key==ENTER)
  346. {
  347. key=Null;
  348. NowStation=1;
  349. menupoint =main_menu;
  350. userchoose = 0;
  351. displaystart = 0;
  352. menu_disp();
  353. break;
  354. }
  355. else if(key==UP)
  356. {
  357. if(MSCounter<MaxMainS)
  358. MSCounter++;
  359. NowMainStation=MainStation[MSCounter];
  360. Disp_NUM(4,3,NowMainStation,0,0);
  361. key=Null;
  362. }
  363. if(key==DOWN)
  364. {
  365. if(MSCounter>0)
  366. MSCounter--;
  367. NowMainStation=MainStation[MSCounter];
  368. Disp_NUM(4,3,NowMainStation,0,0);
  369. key=Null;
  370. }

  371. }
  372. }

  373. }
  374. void numdisp(uchar xx)
  375. {
  376. if (xx<5)
  377. {
  378. Disp_HZ(0,xx-1,shuzi[xx-1],1);
  379. }
  380. else if(xx>4&&xx<9)
  381. {
  382. Disp_HZ(4,xx-5,shuzi[xx-1],1);
  383. }
  384. else
  385. {
  386. Disp_HZ(0,xx-9,shuzi[xx-1],1);
  387. }
  388. }
  389. void valuedisp(uchar xx,uint *num)
  390. {

  391. if (xx<5)
  392. {
  393. Disp_HZ(0,xx-1,shuzi[xx-1],1);
  394. Disp_NUM(1,xx-1,num[xx],1,0);

  395. }
  396. else if(xx>4&&xx<9)
  397. {
  398. Disp_HZ(4,xx-5,shuzi[xx-1],1);
  399. Disp_NUM(5,xx-5,num[xx],1,0);
  400. }
  401. else
  402. {
  403. Disp_HZ(0,xx-9,shuzi[xx-1],1);
  404. Disp_NUM(1,xx-9,num[xx],1,0);
  405. }

  406. }

  407. void dis(uchar xx,uint *num)
  408. {
  409. uchar i;
  410. uchar pos;

  411. clrram();
  412. if(xx<9)
  413. {
  414. if (MaxStation[NowMainStation]<=8)
  415. {
  416. for(i=1;i<=MaxStation[NowMainStation];i++)
  417. valuedisp(i,num);
  418. }
  419. else
  420. {
  421. for(i=1;i<=8;i++)
  422. valuedisp(i,num);
  423. }
  424. }
  425. else
  426. {

  427. if (MaxStation[NowMainStation]>8)
  428. {
  429. for(i=9;i<=MaxStation[NowMainStation];i++)
  430. valuedisp(i,num);
  431. }

  432. }
  433. switch(xx)
  434. {
  435. case 1: pos=0x80;
  436. break;
  437. case 2: pos=0x90;
  438. break;
  439. case 3: pos=0x88;
  440. break;
  441. case 4: pos=0x98;
  442. break;
  443. case 5: pos=0x80+4;
  444. break;
  445. case 6: pos=0x90+4;
  446. break;
  447. case 7: pos=0x88+4;
  448. break;
  449. case 8: pos=0x98+4;
  450. break;
  451. case 9: pos=0x80;
  452. break;
  453. case 10: pos=0x90;
  454. break;
  455. case 11: pos=0x88;
  456. break;
  457. case 12: pos=0x98;
  458. break;
  459. default:
  460. break;
  461. }
  462. con_wch_disp(pos,1);

  463. }
  464. void SetValue(void)
  465. {
  466. readall(0xff);
  467. clrram();
  468. State=0;
  469. key=Null;

  470. dis(NowStation,set1);

  471. while(State==0)
  472. {Setvalues=1;
  473. key_process();
  474. Setvalues=0;
  475. if(key==ESC)
  476. {
  477. State=1;
  478. key=Null;
  479. break;
  480. }
  481. else if(key==ENTER)
  482. {
  483. readstation(NowMainStation,NowStation,0x01,set1[NowStation]);
  484. aa();
  485. readall(NowStation);
  486. clrram();
  487. dis(NowStation,set1);
  488. key=Null;
  489. }
  490. else if(key==FUN)
  491. {
  492. if (NowStation==MaxStation[NowMainStation])
  493. { NowStation=1;}
  494. else
  495. { NowStation++;}
  496. dis(NowStation,set1);
  497. key=Null;
  498. }

  499. else if(key==UP)
  500. {
  501. if(set1[NowStation]<6000)
  502. set1[NowStation]++;
  503. dis(NowStation,set1);
  504. key=Null;
  505. }
  506. else if(key==DOWN)
  507. {
  508. if(set1[NowStation]>3000)
  509. set1[NowStation]--;
  510. dis(NowStation,set1);
  511. key=Null;
  512. }
  513. else if(key==UP+10)
  514. {
  515. if(set1[NowStation]<5990)
  516. set1[NowStation]+=10;
  517. dis(NowStation,set1);

  518. key=Null;
  519. }
  520. else if(key==DOWN+10)
  521. {
  522. if(set1[NowStation]>3010)
  523. set1[NowStation]-=10;
  524. dis(NowStation,set1);
  525. key=Null;
  526. }
  527. else if(key==UP+20)
  528. {
  529. if(set1[NowStation]<5900)
  530. set1[NowStation]+=100;
  531. dis(NowStation,set1);

  532. key=Null;
  533. }
  534. else if(key==DOWN+20)
  535. {
  536. if(set1[NowStation]>3100)
  537. set1[NowStation]-=100;
  538. dis(NowStation,set1);
  539. key=Null;
  540. }

  541. }

  542. }

  543. void ClsWeight(void)
  544. {
  545. clrram(); //清除显示
  546. Disp_HZ(0,0,"**称重清零******",8);
  547. Disp_HZ(0,1,"◆喷嘴号:",4);
  548. Disp_NUM(5,1,NowStation,0,0);
  549. State=0;
  550. key=Null;
  551. while(State!=1)
  552. {key=Null;
  553. key_process();

  554. if(key==ESC)
  555. {
  556. State=1;
  557. key=Null;
  558. break;
  559. }

  560. else if(key==ENTER)
  561. {
  562. readstation(NowMainStation,NowStation,0x08,0x00);
  563. key=Null;
  564. aa();
  565. Disp_HZ(0,0,"**称重清零******",8);
  566. Disp_HZ(0,1,"◆喷嘴号:",4);
  567. Disp_NUM(5,1,NowStation,0,0);
  568. }
  569. else if(key==UP)
  570. {
  571. if (NowStation==MaxStation[NowMainStation])
  572. { NowStation=1;
  573. Disp_NUM(5,1,NowStation,0,0);
  574. }
  575. else
  576. { NowStation++;
  577. Disp_NUM(5,1,NowStation,0,0);
  578. }
  579. key=Null;
  580. }
  581. else if(key==DOWN)
  582. {
  583. if(NowStation>1)
  584. { NowStation--;
  585. Disp_NUM(5,1,NowStation,0,0);
  586. }
  587. else
  588. { NowStation=MaxStation[NowMainStation];
  589. Disp_NUM(5,1,NowStation,0,0);
  590. }

  591. key=Null;
  592. }

  593. }

  594. }
  595. void AdjWeight(void)
  596. {
  597. clrram(); //清除显示
  598. Disp_HZ(0,0,"**称重标定******",8);
  599. Disp_HZ(0,1,"进入请按组合键!",8);
  600. Disp_HZ(0,2,"退出请按取消键!",8);

  601. while(1)
  602. { key=Null;
  603. key_process();
  604. if (key == FUN_COMP)
  605. { key=Null;
  606. clrram(); //清除显示
  607. Disp_HZ(0,0,"**称重标定******",8);
  608. Disp_HZ(0,1,"◆喷嘴号:",4);
  609. Disp_NUM(5,1,NowStation,0,0);
  610. State=0;
  611. key=Null;
  612. while(State!=1)
  613. {key=Null;
  614. key_process();
  615. if(key==ESC)
  616. {
  617. State=1;
  618. key=Null;
  619. break;
  620. }
  621. else if(key==ENTER)
  622. {
  623. AdjWeight2();
  624. }


  625. else if(key==UP)
  626. {
  627. if (NowStation==MaxStation[NowMainStation])
  628. { NowStation=1;
  629. Disp_NUM(5,1,NowStation,0,0);
  630. }
  631. else
  632. { NowStation++;
  633. Disp_NUM(5,1,NowStation,0,0);
  634. }
  635. key=Null;
  636. }
  637. else if(key==DOWN)
  638. {
  639. if(NowStation>1)
  640. { NowStation--;
  641. Disp_NUM(5,1,NowStation,0,0);
  642. }
  643. else
  644. { NowStation=MaxStation[NowMainStation];
  645. Disp_NUM(5,1,NowStation,0,0);
  646. }

  647. key=Null;
  648. }
  649. }

  650. }
  651. else if(key==ESC)
  652. {
  653. key=Null;
  654. menupoint =main_menu;
  655. userchoose = 0;
  656. displaystart = 0;
  657. menu_disp();
  658. break;
  659. }
  660. }

  661. }

  662. void AdjWeight2(void)
  663. {
  664. uchar ps=0;
  665. key=Null;
  666. clrram(); //清除显示
  667. Disp_HZ(0,0,"**称重标定******",8);
  668. Disp_HZ(0,1,"◆状态:P-",5);
  669. Disp_NUM(5,1,ps,0,0);
  670. State=0;
  671. key=Null;
  672. while(1)
  673. { key=Null;
  674. key_process();

  675. if(key==ENTER)
  676. {
  677. readstation(NowMainStation,NowStation,0x09,ps);
  678. key=Null;
  679. aa();
  680. Disp_HZ(0,0,"**称重标定******",8);
  681. Disp_HZ(0,1,"◆状态:P-",5);
  682. if(ps==7)
  683. Disp_HZ(5,1,"退出",2);
  684. else
  685. {Disp_HZ(5,1," ",2);
  686. Disp_NUM(5,1,ps,0,0);
  687. }
  688. }
  689. else if(key==UP)
  690. {
  691. if (ps==7)
  692. { ps=0;
  693. if(ps==7)
  694. Disp_HZ(5,1,"退出",2);
  695. else
  696. {Disp_HZ(5,1," ",2);
  697. Disp_NUM(5,1,ps,0,0);
  698. }
  699. }
  700. else
  701. { ps++;
  702. if(ps==7)
  703. Disp_HZ(5,1,"退出",2);
  704. else
  705. {Disp_HZ(5,1," ",2);
  706. Disp_NUM(5,1,ps,0,0);
  707. }
  708. }
  709. key=Null;
  710. }
  711. else if(key==DOWN)
  712. {
  713. if(ps>0)
  714. { ps--;
  715. if(ps==7)
  716. Disp_HZ(5,1,"退出",2);
  717. else
  718. {Disp_HZ(5,1," ",2);
  719. Disp_NUM(5,1,ps,0,0);
  720. }

  721. }
  722. else
  723. { ps=7;
  724. if(ps==7)
  725. Disp_HZ(5,1,"退出",2);
  726. else
  727. {Disp_HZ(5,1," ",2);
  728. Disp_NUM(5,1,ps,0,0);
  729. }
  730. }

  731. key=Null;
  732. }

  733. else if(key==ESC)
  734. {
  735. key=Null;
  736. clrram(); //清除显示
  737. Disp_HZ(0,0,"**称重标定******",8);
  738. Disp_HZ(0,1,"◆喷嘴号:",4);
  739. Disp_NUM(5,1,NowStation,0,0);
  740. break;
  741. }
  742. }

  743. }


  744. void SetAddress(void)
  745. {
  746. uint i=1;

  747. //start:
  748. clrram(); //清除显示

  749. Disp_HZ(0,0,"**包机站号设置**",8);
  750. Disp_HZ(0,1,"◆包机号:",4);
  751. Disp_NUM(5,1,i,0,0);
  752. State=0;
  753. key=Null;
  754. while(State!=1)
  755. {key=Null;
  756. key_process();

  757. if(key==ESC)
  758. {
  759. State=1;
  760. key=Null;
  761. break;
  762. }
  763. else if(key==ENTER)
  764. {
  765. readstation(0xff,0xf0,0x05,i);
  766. key=Null;
  767. aa();
  768. Disp_HZ(0,0,"**包机站号设置**",8);
  769. Disp_HZ(0,1,"◆包机号:",4);
  770. Disp_NUM(5,1,i,0,0);
  771. }
  772. else if(key==UP)
  773. {
  774. if(i<Num_of_main)
  775. i++;
  776. else
  777. i=1;
  778. Disp_NUM(5,1,i,0,0);
  779. key=Null;
  780. }
  781. else if(key==DOWN)
  782. {
  783. if(i>1)
  784. i--;
  785. else
  786. i=Num_of_main;
  787. Disp_NUM(5,1,i,0,0);
  788. key=Null;
  789. }

  790. }
  791. }



  792. void SetStation(void)
  793. {
  794. uint i=8;
  795. clrram(); //清除显示
  796. Disp_HZ(0,0,"**喷嘴设置******",8);
  797. Disp_HZ(0,1,"◆喷嘴数:",4);
  798. Disp_NUM(5,1,i,0,0);
  799. State=0;
  800. key=Null;
  801. while(State!=1)
  802. {key=Null;
  803. key_process();

  804. if(key==ESC)
  805. {
  806. State=1;
  807. key=Null;
  808. break;
  809. }
  810. else if(key==ENTER)
  811. {
  812. readstation(0xff,0xf0,0x06,i);
  813. key=Null;
  814. aa();
  815. Disp_HZ(0,0,"**喷嘴设置******",8);
  816. Disp_HZ(0,1,"◆喷嘴数:",4);
  817. Disp_NUM(5,1,i,0,0);
  818. }
  819. else if(key==UP)
  820. {
  821. if(i<12)
  822. i++;
  823. else
  824. i=1;
  825. Disp_NUM(5,1,i,0,0);
  826. key=Null;
  827. }
  828. else if(key==DOWN)
  829. {
  830. if(i>1)
  831. i--;
  832. else
  833. i=12;
  834. Disp_NUM(5,1,i,0,0);
  835. key=Null;
  836. }
  837. }


  838. }

  839. //************************************密码函数************************************
  840. //函数名称: PassWords
  841. //函数说明: 无
  842. //入口参数: 无
  843. //出口参数: 无
  844. //******************************************************************************
  845. void PassWords(void)
  846. {
  847. uint i=0;
  848. clrram(); //清除显示
  849. Disp_HZ(0,0,"**输入密码******",8);
  850. Disp_HZ(0,1,"◆密码值:",4);
  851. Disp_NUM(5,1,i,0,0);
  852. State=0;
  853. key=Null;
  854. while(State!=1)
  855. {key=Null;
  856. Delay_Nms(500);
  857. key_process();

  858. if(key==ESC)
  859. {
  860. State=1;
  861. key=Null;
  862. menupoint =main_menu;
  863. userchoose = 0;
  864. displaystart = 0;
  865. menu_disp();
  866. break;
  867. }
  868. else if((key==ENTER) && ( i == PassWord ))
  869. {
  870. menupoint =other_menu;
  871. userchoose = 0;
  872. displaystart = 0;
  873. menu_disp();
  874. key=Null;
  875. State=1;
  876. }
  877. else if(key==UP)
  878. {
  879. if(i<99)
  880. i++;
  881. Disp_NUM(5,1,i,0,0);
  882. key=Null;
  883. }
  884. else if(key==DOWN)
  885. {
  886. if(i>0)
  887. i--;
  888. Disp_NUM(5,1,i,0,0);
  889. key=Null;
  890. }



  891. }

  892. }


  893. void BaL(void)
  894. {

  895. clrram(); //清除显示
  896. Disp_HZ(0,0,"**背光调整******",8);
  897. Disp_HZ(0,1,"◆亮度值:",4);
  898. Disp_NUM(5,1,bal,0,0);
  899. State=0;
  900. key=Null;
  901. while(State!=1)
  902. {key=Null;
  903. Delay_Nms(500);
  904. key_process();

  905. if(key==ESC)
  906. {
  907. State=1;
  908. key=Null;
  909. menupoint =main_menu;
  910. userchoose = 0;
  911. displaystart = 0;
  912. menu_disp();
  913. break;
  914. }
  915. else if(key==ENTER)
  916. {
  917. _DINT();
  918. write_buff[1]=bal;
  919. flash_erase( pc_flash_segment); //段擦除

  920. write_array(pc_flash, write_buff,4); //写入指定字节数量
  921. _NOP();
  922. read_array(pc_flash,checkout,4); //再读出刚才写的字节
  923. bal=checkout[1];
  924. key=Null;
  925. _EINT();
  926. State=1;
  927. key=Null;
  928. menupoint =main_menu;
  929. userchoose = 0;
  930. displaystart = 0;
  931. menu_disp();

  932. break;
  933. }
  934. else if(key==UP)
  935. {
  936. if(bal<99)
  937. bal++;
  938. Disp_NUM(5,1,bal,0,0);
  939. key=Null;
  940. }
  941. else if(key==DOWN)
  942. {
  943. if(bal>0)
  944. bal--;
  945. Disp_NUM(5,1,bal,0,0);
  946. key=Null;
  947. }



  948. }

  949. }

  950. //************************************电量函数************************************
  951. //函数名称: ADC
  952. //函数说明: 无
  953. //入口参数: 无
  954. //出口参数: 无
  955. //******************************************************************************
  956. void ADC(void)
  957. {
  958. adc=1;
  959. //start:
  960. clrram(); //清除显示
  961. ADC_Init();
  962. Disp_HZ(0,0,"**电池电量******",8);
  963. Disp_HZ(1,1,"电压值:",4);
  964. Disp_HZ(7,1," V",2);
  965. Disp_NUM(4,1,Curr_Volt,1,0);
  966. State=0;
  967. key=Null;
  968. while(State!=1)
  969. {key=Null;
  970. key_process();

  971. switch (State)
  972. {
  973. case 0 :
  974. if(key==ESC)
  975. {P6SEL= 0; // 使能ADC通道
  976. ADC12CTL0 = 0; // 打开ADC,设置采样时间
  977. ADC12IE = 0; // 使能ADC中断
  978. State=1;
  979. adc=0;
  980. key=Null;
  981. menupoint =main_menu;
  982. userchoose = 0;
  983. displaystart = 0;
  984. menu_disp();
  985. break;
  986. }
  987. }
  988. }


  989. }
 楼主| liuxing4585 发表于 2015-6-11 09:00 | 显示全部楼层
  1. /****************************************************************************\
  2. 文件名:flash.c
  3. 编写者:czhang
  4. 描述:用于MSP430F149。
  5. FLASH存储器读写、擦除。时钟源:MCLK 8MHz
  6. 版本:1.0        2005-2-19
  7. \****************************************************************************/
  8. #include <msp430x14x.h>
  9. #include "flash.h"

  10. /***************************************************************************
  11. 段擦除
  12. adr:要擦除的段内的任一地址
  13. ***************************************************************************/
  14. void FlashErase(unsigned int adr) [url=home.php?mod=space&uid=72445]@[/url] "MYSET"
  15. {
  16. unsigned char *p0;

  17. FCTL2=FWKEY+FSSEL_1+FN3+FN4;
  18. FCTL3=FWKEY;
  19. while(FlashBusy()==1)        //等待FLASH存储器完成操作
  20. ;
  21. FCTL1=FWKEY+ERASE;
  22. p0=(unsigned char *)adr;
  23. *p0=0;         //向段内地址任意写,启动擦除操作
  24. FCTL1=FWKEY;
  25. FCTL3=FWKEY+LOCK;
  26. while(FlashBusy()==1)        //等待FLASH存储器完成操作
  27. ;
  28. }

  29. /**************************************************************************
  30. 测试FLASH是否忙
  31. 返回值:1:忙 0:不忙
  32. **************************************************************************/
  33. unsigned char FlashBusy() @ "MYSET"
  34. {
  35. if((FCTL3&BUSY)==BUSY)
  36. return 1;
  37. else
  38. return 0;
  39. }

  40. /**************************************************************************
  41. 字编程
  42. Adr:要编程的地址,注意:不是指针类型,应当是偶地址
  43. DataW:要编程的字
  44. **************************************************************************/
  45. void FlashWW(unsigned int Adr,unsigned int DataW) @ "MYSET"
  46. {
  47. FCTL1=FWKEY+WRT;
  48. FCTL2=FWKEY+FSSEL_1+FN3+FN4;
  49. FCTL3=FWKEY;
  50. while(FlashBusy()==1)        //等待FLASH存储器完成操作
  51. ;
  52. *((unsigned int *)Adr)=DataW;
  53. FCTL1=FWKEY;
  54. FCTL3=FWKEY+LOCK;
  55. while(FlashBusy()==1)        //等待FLASH存储器完成操作
  56. ;
  57. }

  58. /**************************************************************************
  59. 字节编程
  60. Adr:指向要编程的地址,注意:不是指针类型
  61. DataB:要编程的字节
  62. **************************************************************************/
  63. void FlashWB(unsigned int Adr,unsigned char DataB) @ "MYSET"
  64. {
  65. FCTL1=FWKEY+WRT;
  66. FCTL2=FWKEY+FSSEL_1+FN3+FN4;
  67. FCTL3=FWKEY;
  68. while(FlashBusy()==1)        //等待FLASH存储器完成操作
  69. ;
  70. *((unsigned char *)Adr)=DataB;
  71. FCTL1=FWKEY;
  72. FCTL3=FWKEY+LOCK;
  73. while(FlashBusy()==1)        //等待FLASH存储器完成操作
  74. ;
  75. }
12864驱动:
  1. //******************************************************************************
  2. //MSP430驱动液晶程序
  3. //文件名 :lcd12864.h
  4. //模块名称:st7920 并行方式驱动12864液晶驱动
  5. //功能概要:st7920显示驱动
  6. //PSB模式选择管脚,直接接高电平,采用并口方式
  7. //RST管脚悬空,采用上电复位模式
  8. //D0-D7与430的P2口连接
  9. //偏置电压选择端悬空
  10. //RS,RW,E分别与P3.012口连接
  11. //******************************************************************************/
  12. #include <msp430x14x.h>


  13. #define x1 0x80
  14. #define x2 0x88
  15. #define y 0x80
  16. #define comm 0
  17. #define dat 1
  18. #define DIROUT P2DIR=0XFF
  19. #define DIRIN P2DIR=0X00
  20. #define LCD_CMDOut P1DIR|=0xe0 //P1口的高三位设置为输出
  21. #define RS_1 P1OUT|=BIT5
  22. #define RS_0 P1OUT&=~BIT5
  23. #define RW_1 P1OUT|=BIT6
  24. #define RW_0 P1OUT&=~BIT6
  25. #define E_1 P1OUT|=BIT7
  26. #define E_0 P1OUT&=~BIT7

  27. #define LCD_PSB_H P3OUT|=BIT0 //P3.0
  28. #define LCD_PSB_L P3OUT&=~BIT0 //P3.0
  29. #define LCD_RST_H P3OUT|=BIT1 //P3.1
  30. #define LCD_RST_L P3OUT&=~BIT1 //P3.1
  31. #define LCD_LED_H P3OUT|=BIT3 //P3.3
  32. #define LCD_LED_L P3OUT&=~BIT3 //P3.3

  33. void wr_lcd (uchar dat_comm,uchar content);
  34. void chk_busy (void);
  35. void delay (uint);
  36. void test(void);
  37. void Delay_1ms(void);
  38. void Delay_Nms(uint n);
  39. void X_Y(uchar X,uchar Y);
  40. void Disp_CHAR(uchar X,uchar Y,const uchar * pt,uchar num);
  41. void Disp_NUM(uchar X,uchar Y,unsigned int pt,uchar num,uchar change);
  42. void X_Y(uchar X,uchar Y)
  43. {
  44. uchar pos;
  45. switch(Y)
  46. {
  47. case 0: pos=0x80+X;
  48. break;
  49. case 1: pos=0x90+X;
  50. break;
  51. case 2: pos=0x88+X;
  52. break;
  53. case 3: pos=0x98+X;
  54. break;
  55. default:
  56. break;
  57. }
  58. wr_lcd(comm,pos);
  59. }

  60. /*******************************************
  61. 函数名称:Disp_HZ
  62. 功 能:控制液晶显示汉字
  63. 参 数:XY--显示位置的首地址
  64. pt--指向显示数据的指针
  65. num--显示字符个数
  66. 返回值 :无
  67. ********************************************/
  68. void Disp_HZ(uchar X,uchar Y,const uchar * pt,uchar num)
  69. {
  70. uchar i;
  71. X_Y(X,Y);       

  72. for(i = 0;i < (num*2);i++)
  73. wr_lcd(dat,*(pt++));

  74. }
  75. /*******************************************/
  76. //****************
  77. //**端口初始化
  78. //***************
  79. void init_lcdport(void)
  80. {

  81. P3DIR|=BIT0+BIT1+BIT3; //输出端口
  82. LCD_CMDOut;
  83. LCD_LED_H;
  84. LCD_RST_L; //复位LCD
  85. Delay_Nms(2); //保证复位所需要的时间
  86. LCD_RST_H; //恢复LCD正常工作
  87. _NOP();
  88. LCD_PSB_H; //设置LCD为8位并口通信
  89. LCD_LED_L;

  90. }
  91. /****************************************************************************************
  92. *延时子程序
  93. ****************************************************************************************/
  94. void delay(uint n)
  95. {
  96. uint i;
  97. for (i=n; i>0; i--)
  98. {
  99. ;
  100. }
  101. }
  102. /*******************************************
  103. 函数名称:Delay_1ms
  104. 功 能:延时约1ms的时间
  105. 参 数:无
  106. 返回值 :无
  107. ********************************************/
  108. void Delay_1ms(void)
  109. {
  110. uchar i;

  111. for(i = 150;i > 0;i--) _NOP();
  112. }
  113. /*******************************************
  114. 函数名称:Delay_Nms
  115. 功 能:延时N个1ms的时间
  116. 参 数:n--延时长度
  117. 返回值 :无
  118. ********************************************/
  119. void Delay_Nms(uint n)
  120. {
  121. uint i;

  122. for(i = n;i > 0;i--) Delay_1ms();
  123. }
  124. /******************************************************************************************
  125. * 函数名称 :init_lcd
  126. * 功能描述 : LCD初始化子程序
  127. * 返回值 :无
  128. ******************************************************************************************/
  129. void init_lcd(void)
  130. {
  131. wr_lcd(comm,0x30); /*30---基本指令动作*/
  132. wr_lcd(comm,0x01); /*清屏,地址指针指向00H*/
  133. wr_lcd(comm,0x06); /*光标的移动方向*/
  134. wr_lcd(comm,0x0c); /*开显示,关游标*/
  135. }

  136. /******************************************************************************************
  137. * 函数名称 :chr_disp
  138. * 功能描述 :显示字符
  139. * 返回值 :无
  140. ******************************************************************************************/
  141. void chr_disp(uchar *chn,uint x,uint nbyte)
  142. {
  143. uchar i;
  144. wr_lcd(comm,0x30); //一般功能
  145. wr_lcd(comm,x); //显示起始位置,x坐标是自加的,注意显示地址
  146. for(i=0;i<nbyte;i++)
  147. {
  148. wr_lcd(dat,chn[i]); //写数据
  149. }
  150. }
  151. /******************************************************************************************
  152. * 函数名称 :chn_disp1
  153. * 功能描述 : 上半屏显示汉字或字符,字库汉字与字符
  154. * 返回值 :无
  155. ******************************************************************************************/
  156. void chn_disp1(uchar *chn)
  157. {
  158. uchar i,j;
  159. wr_lcd(comm,0x30);
  160. delay(5);
  161. wr_lcd(comm,0x80); //第一行
  162. j=0;
  163. for(i=0;i<16;i++)
  164. {
  165. wr_lcd(dat,chn[j*16+i]);
  166. }
  167. wr_lcd(comm,0x90); //第二行
  168. j=1;
  169. for(i=0;i<16;i++)
  170. {
  171. wr_lcd(dat,chn[j*16+i]); //写数据
  172. }
  173. }

  174. /******************************************************************************************
  175. * 函数名称 :img_disp
  176. * 功能描述 :显示图形
  177. * 返回值 :无
  178. ******************************************************************************************/
  179. void img_disp(uchar *img)
  180. {
  181. uchar i,j;
  182. for(j=0;j<32;j++)
  183. {
  184. for(i=0;i<8;i++)
  185. {
  186. wr_lcd(comm,0x34); //绘图功能
  187. wr_lcd(comm,y+j);
  188. wr_lcd(comm,x1+i);
  189. wr_lcd(comm,0x30);
  190. wr_lcd(dat,img[j*16+i*2]);
  191. wr_lcd(dat,img[j*16+i*2+1]);
  192. }
  193. }
  194. for(j=32;j<64;j++)
  195. {
  196. for(i=0;i<8;i++)
  197. {
  198. wr_lcd(comm,0x34); //绘图功能
  199. wr_lcd(comm,y+j-32);
  200. wr_lcd(comm,x2+i);
  201. wr_lcd(comm,0x30);
  202. wr_lcd(dat,img[j*16+i*2]);
  203. wr_lcd(dat,img[j*16+i*2+1]);
  204. }
  205. }
  206. wr_lcd (comm,0x36); //绘图显示
  207. }

  208. /******************************************************************************************
  209. * 函数名称 :img_disp1
  210. * 功能描述 :下半屏显示图形8*16
  211. * 返回值 :无
  212. ******************************************************************************************/
  213. void img_disp1(uchar *img)
  214. {
  215. uchar i,j;
  216. for(j=0;j<32;j++)
  217. {
  218. for(i=0;i<8;i++)
  219. {
  220. wr_lcd(comm,0x34);
  221. wr_lcd(comm,y+j);
  222. wr_lcd(comm,x2+i);
  223. wr_lcd(comm,0x30);
  224. wr_lcd(dat,img[j*16+i*2]);
  225. wr_lcd(dat,img[j*16+i*2+1]);
  226. }
  227. }
  228. wr_lcd(comm,0x36);
  229. }

  230. /******************************************************************************************
  231. * 函数名称 :lat_disp
  232. * 功能描述 : 显示点阵
  233. * 返回值 :无
  234. ******************************************************************************************/
  235. void lat_disp(uchar data1,uchar data2)
  236. {
  237. uchar i,j,k,x;
  238. x=x1;
  239. for(k=0;k<2;k++)
  240. {
  241. for(j=0;j<16;j++)
  242. {
  243. for(i=0;i<8;i++)
  244. {
  245. wr_lcd(comm,0x34); //绘图功能
  246. wr_lcd(comm,y+j*2); //y坐标
  247. wr_lcd(comm,x+i); //x坐标
  248. wr_lcd(comm,0x30); //一般功能
  249. wr_lcd(dat,data1);
  250. wr_lcd(dat,data1);
  251. }
  252. for(i=0;i<8;i++)
  253. {
  254. wr_lcd(comm,0x34);
  255. wr_lcd(comm,y+j*2+1);
  256. wr_lcd(comm,x+i);
  257. wr_lcd(comm,0x30);
  258. wr_lcd(dat,data2);
  259. wr_lcd(dat,data2);
  260. }
  261. }
  262. x=x2;
  263. }
  264. wr_lcd(comm,0x36); //绘图功能打开
  265. }

  266. /******************************************************************************************
  267. * 函数名称 :con_disp
  268. * 功能描述 : 当data1=0xff,data2=0xff时,在x0,y0处反白显示16xl*yl
  269. * 返回值 :无
  270. ******************************************************************************************/
  271. void con_disp(uchar data1,uchar data2,uchar x0,uchar y0,uchar xl,uchar yl)
  272. {
  273. uchar i,j;
  274. for(j=0;j<yl;j++)
  275. {
  276. for(i=0;i<xl;i++)
  277. {
  278. wr_lcd(comm,0x34); //绘图功能
  279. wr_lcd(comm,y0+j); //y坐标
  280. wr_lcd(comm,x0+i); //x坐标
  281. wr_lcd(comm,0x30); //一般功能
  282. wr_lcd(dat,data1);
  283. wr_lcd(dat,data2);
  284. }
  285. }
  286. wr_lcd(comm,0x36); //显示功能
  287. }

  288. /******************************************************************************************
  289. * 函数名称 :clrram
  290. * 功能描述 : 清DDRAM
  291. * 返回值 :无
  292. ******************************************************************************************/
  293. void clrram(void)
  294. {
  295. wr_lcd(comm,0x30);
  296. wr_lcd(comm,0x01);
  297. }

  298. /******************************************************************************************
  299. * 函数名称 :wr_lcd
  300. * 功能描述 : 写数据和指令子程序,0时写指令,1写数据
  301. * 返回值 :无
  302. ******************************************************************************************/
  303. void wr_lcd(uchar dat_comm,uchar content)
  304. {
  305. chk_busy ();
  306. if(dat_comm)
  307. {
  308. RS_1; //写数据
  309. RW_0;
  310. }
  311. else
  312. {
  313. RS_0; //写指令
  314. RW_0;
  315. }
  316. P2OUT=content; //数据载入
  317. delay(10);
  318. E_1;
  319. _NOP();
  320. E_0; //下降沿作用
  321. }

  322. /*******************************************************************************
  323. * 函数名称 :chk_busy
  324. * 功能描述 : 检查忙信号子程序
  325. * 返回值 :无
  326. *******************************************************************************/
  327. void chk_busy(void)
  328. {
  329. int temp;
  330. DIRIN; //端口设置为输入方式
  331. RS_0;
  332. RW_1;
  333. do
  334. {
  335. E_1; //读端口状态
  336. _NOP();       
  337. temp=P2IN;
  338. E_0; //下降沿读取状态
  339. }while((temp&0X80)!=0); //高位为1为忙信号
  340. DIROUT;
  341. }

  342. /******************************************************************************************
  343. * 函数名称 :wch_disp
  344. * 功能描述 :向指定位置写入汉字和字符,(字库汉字和字符)
  345. * 返回值 :无,x字节数,nbyte写入的汉字和字符个数
  346. ******************************************************************************************/
  347. void wch_disp(uchar *chn,uint x,uint nbyte)
  348. {
  349. uchar i;
  350. wr_lcd(comm,0x30); //一般功能
  351. wr_lcd(comm,x); //显示起始位置,x坐标是自加的,注意显示地址
  352. for(i=0;i<(2*nbyte);i++)
  353. {
  354. wr_lcd(dat,chn[i]); //写数据
  355. }
  356. }

  357. /******************************************************************************************
  358. * 函数名称 :line_disp
  359. * 功能描述 :画线功能
  360. * 返回值 :无,x坐标水平,y坐标竖着往下,从80H,到80+31,下半屏也是如此
  361. ******************************************************************************************/
  362. void line_disp(uint xstart,uint ytemp,uint xend)
  363. {
  364. uint i,j;
  365. for(j=0;j<32;j++)
  366. {
  367. for(i=0;i<8;i++)
  368. {
  369. wr_lcd(comm,0x34);
  370. wr_lcd(comm,0x80+j);
  371. wr_lcd(comm,0x80+i);
  372. wr_lcd(comm,0x30);
  373. wr_lcd(dat,0x00);
  374. wr_lcd(dat,0x00);
  375. }
  376. }
  377. for(j=0;j<32;j++)
  378. {
  379. for(i=0;i<8;i++)
  380. {
  381. wr_lcd(comm,0x34);
  382. wr_lcd(comm,0x80+j);
  383. wr_lcd(comm,0x88+i);
  384. wr_lcd(comm,0x30);
  385. wr_lcd(dat,0x00);
  386. wr_lcd(dat,0x00);
  387. }
  388. }
  389. for(j=0;j<2;j++)
  390. {
  391. for(i=0;i<=(xend-xstart);i++)
  392. {
  393. wr_lcd(comm,0x34); //绘图功能
  394. wr_lcd(comm,ytemp+j); //y坐标
  395. wr_lcd(comm,xstart+i); //x坐标
  396. wr_lcd(comm,0x30); //一般功能
  397. wr_lcd(dat,0xff);
  398. wr_lcd(dat,0xff);
  399. }
  400. }
  401. /* for(i=0;i<8;i++)
  402. {
  403. wr_lcd(comm,0x34);
  404. wr_lcd(comm,ytemp+1);
  405. wr_lcd(comm,xstart+i);
  406. wr_lcd(comm,0x30);
  407. wr_lcd(dat,0xff);
  408. wr_lcd(dat,0xff);
  409. }*/
  410. wr_lcd(comm,0x36); //绘图功能打开
  411. }

  412. //************************************长延时************************************
  413. //函数名称: long_delay(uint n)
  414. //函数说明: 相对于delay()来说的,延时时间较长
  415. //入口参数: unsigned int n,延时时间常数
  416. //出口参数: 无
  417. //******************************************************************************
  418. void long_delay(uint n)
  419. {
  420. uint i,j;
  421. for(i = n;i > 0;i--)
  422. for(j = 0xff;j > 0;j--) ;
  423. }
  424. //******************************************************************************

  425. //************************************反白显示**********************************
  426. //函数名称: con_wch_disp(uchar *chn,uint x,uint nbyte)
  427. //函数说明: 反白任意位置显示字符
  428. //入口参数: uint x-反白地址,uint nbyte-长度
  429. //出口参数: 无
  430. //******************************************************************************
  431. void con_wch_disp(uint x,uint nbyte)
  432. {
  433. uchar i,j;
  434. //***************************计算地址************************
  435. uchar m,n;
  436. if ((x & 0x08) == 0x08)
  437. {
  438. m = 0x88 + (x & 0x07);
  439. }
  440. else m = 0x80 + (x & 0x07);
  441. if((x & 0x90) == 0x90)
  442. {
  443. n = 0x90;
  444. }
  445. else n = 0x80;
  446. //****************************反白*****************************
  447. for(j=0;j<32;j++)
  448. {
  449. for(i=0;i<8;i++)
  450. {
  451. wr_lcd(comm,0x34);
  452. wr_lcd(comm,0x80+j);
  453. wr_lcd(comm,0x80+i);
  454. wr_lcd(comm,0x30);
  455. wr_lcd(dat,0x00);
  456. wr_lcd(dat,0x00);
  457. }
  458. }
  459. for(j=0;j<32;j++)
  460. {
  461. for(i=0;i<8;i++)
  462. {
  463. wr_lcd(comm,0x34);
  464. wr_lcd(comm,0x80+j);
  465. wr_lcd(comm,0x88+i);
  466. wr_lcd(comm,0x30);
  467. wr_lcd(dat,0x00);
  468. wr_lcd(dat,0x00);
  469. }
  470. }
  471. for(j=0;j<16;j++)
  472. {
  473. for(i=0;i<nbyte;i++)
  474. {
  475. wr_lcd(comm,0x34);
  476. wr_lcd(comm,n+j);
  477. wr_lcd(comm,m+i);
  478. wr_lcd(comm,0x30);
  479. wr_lcd(dat,0xff);
  480. wr_lcd(dat,0xff);
  481. }
  482. }
  483. wr_lcd (comm,0x36);
  484. }
  485. void Disp_black() //在反白之前先清绘图存储区,将绘图存储区的参数全设为不反白0x00.
  486. {
  487. unsigned char i,j;
  488. wr_lcd(comm,0x36); //图形方式
  489. for(i=0;i<32;i++){
  490. wr_lcd(comm,0x80+i);
  491. wr_lcd(comm,0x80);
  492. for(j=0;j<16;j++)
  493. {
  494. wr_lcd(dat,0x00);
  495. }
  496. }
  497. for(i=0;i<32;i++){
  498. wr_lcd(comm,0x80+i);
  499. wr_lcd(comm,0x88);
  500. for(j=0;j<16;j++) {
  501. wr_lcd(dat,0x00);
  502. }
  503. }
  504. }

  505. /*******************************************
  506. 函数名称:Disp_CHAR
  507. 功 能:控制液晶显示字符
  508. 参 数:addr--显示位置的首地址
  509. pt--指向显示数据的指针
  510. num--显示字符个数
  511. 返回值 :无
  512. ********************************************/
  513. void Disp_CHAR(uchar X,uchar Y,const uchar * pt,uchar num)
  514. {
  515. uchar i;
  516. X_Y( X, Y);       
  517. for(i = 0;i <num;i++)
  518. wr_lcd(dat,*(pt++));
  519. }
  520. /*******************************************
  521. 函数名称:Disp_NUM
  522. 功 能:控制液晶显示数字
  523. 参 数:addr--显示位置的首地址
  524. pt--数字
  525. num--1.显示浮点数 99.99 ,显示整数 99
  526. 返回值 :无
  527. ********************************************/
  528. void Disp_NUM(uchar X,uchar Y,unsigned int pt,uchar num,uchar change)
  529. {
  530. unsigned char data[6];
  531. pt=pt%10000;
  532. X_Y( X, Y);
  533. if(num==0)
  534. {
  535. data[0]=0x30+pt%100/10;
  536. data[1]=0x30+pt%10;
  537. Disp_CHAR(X,Y,data,2);
  538. }
  539. else
  540. {
  541. data[0]=0x30+pt/1000;
  542. data[1]=0x30+pt%1000/100;
  543. data[2]=0x2e;
  544. data[3]=0x30+pt%100/10;
  545. data[4]=0x30+pt%10;
  546. data[5]=0x20;
  547. Disp_CHAR(X,Y,data,5);
  548. }

  549. }
  550. //******************************************************************************

  551. //*************************************************************************


JY-DX-JY 发表于 2015-6-11 13:43 | 显示全部楼层
好长的代码,顶一个。。。。。。
 楼主| liuxing4585 发表于 2015-6-11 16:21 | 显示全部楼层
JY-DX-JY 发表于 2015-6-11 13:43
好长的代码,顶一个。。。。。。

谢谢啦,
可可球 发表于 2015-6-11 20:35 | 显示全部楼层
正想做一个无线键盘呢,刚好你的可以做参考,顶一个
firstblood 发表于 2015-6-11 21:42 | 显示全部楼层
这个关键的部分还是在程序的处理上的。
firstblood 发表于 2015-6-11 21:42 | 显示全部楼层
楼主分享出来的程序代码的是非常复杂的,,这个也是不容忽视的,需要大量的工作的。
 楼主| liuxing4585 发表于 2015-6-11 23:00 | 显示全部楼层
firstblood 发表于 2015-6-11 21:42
这个关键的部分还是在程序的处理上的。

是的。原理很简单
 楼主| liuxing4585 发表于 2015-6-11 23:01 | 显示全部楼层
firstblood 发表于 2015-6-11 21:42
楼主分享出来的程序代码的是非常复杂的,,这个也是不容忽视的,需要大量的工作的。 ...

因为是实际项目,所以做的比较细了
 楼主| liuxing4585 发表于 2015-6-11 23:01 | 显示全部楼层
可可球 发表于 2015-6-11 20:35
正想做一个无线键盘呢,刚好你的可以做参考,顶一个

欢迎切磋
luchen66 发表于 2015-6-12 09:26 | 显示全部楼层
能发个实物图片吗?看看效果啊,呵呵
 楼主| liuxing4585 发表于 2015-6-12 09:57 | 显示全部楼层
luchen66 发表于 2015-6-12 09:26
能发个实物图片吗?看看效果啊,呵呵

回家拍一个
yigerenday 发表于 2015-6-15 11:09 | 显示全部楼层
源代码发个压缩包附件吧。这完全看不了呀,亲
angerbird 发表于 2015-6-15 18:55 | 显示全部楼层
低电压、超低功耗。工作电压3.6V~1.8V ,正常工作模式280μA@1MHz,2.2V,待机模式1.6μA,RAM数据保存的掉电模式下0.1μA。 五级节电模式。
angerbird 发表于 2015-6-15 18:57 | 显示全部楼层
该设计的显示部分是采用12864液晶显示的吧。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

500

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部