[demo程序] 基于纳瓦特MCU+LCD1602模块

[复制链接]
 楼主| hbzjt2011 发表于 2018-6-28 18:14 | 显示全部楼层 |阅读模式
      利用中午休息的时间写了一下NV32与LCD1602的驱动,采用四线制接法,接口定义可以参考程序,程序还需要进一步完善,在此贴出来与大家分享。
微信图片_20180628180627.jpg

lcd1602.c
  1. #include "main.h"

  2. //实际测试可用任意IO读写LCD1602//系统时钟16MHz


  3. ///////////////////////////////4线LCD1602////////////////////////////////////////////////
  4. //函数名:  delay
  5. //函数功能:LCD1602延时
  6. //注释:   
  7. void delay(unsigned char z)
  8. {
  9.   unsigned char x,y,j;
  10.         for(j=0;j<4;j++)
  11.     for(x=z;x>0;x--)
  12.       for(y=110;y>0;y--);
  13. }


  14. //函数名:  LCD1602_GPIO_INIT
  15. //函数功能:LCD1602用GPIO初始化
  16. //注释:
  17. void LCD1602_GPIO_INIT(void)
  18. {
  19.         //控制位
  20.         GPIO_Init(GPIOB, GPIO_PTE0_MASK, GPIO_PinOutput);
  21.         GPIO_Init(GPIOB, GPIO_PTE1_MASK, GPIO_PinOutput);
  22.         GPIO_Init(GPIOA, GPIO_PTC5_MASK, GPIO_PinOutput);
  23.        
  24.         //数据位
  25.         GPIO_Init(GPIOB, GPIO_PTG0_MASK, GPIO_PinOutput);
  26.         GPIO_Init(GPIOB, GPIO_PTG1_MASK, GPIO_PinOutput);
  27.         GPIO_Init(GPIOB, GPIO_PTG2_MASK, GPIO_PinOutput);
  28.         GPIO_Init(GPIOB, GPIO_PTG3_MASK, GPIO_PinOutput);
  29. }


  30. //函数名:  LCD1602_INIT
  31. //函数功能:LCD1602初始化
  32. //注释:    DATA可以是指令或者数据
  33. void LCD1602_INIT(void)
  34. {
  35.         LCD1602_GPIO_INIT();
  36.         //GPIO_Init(GPIOD,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_LOW_FAST);
  37.         //GPIO_Init(GPIOC,GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_OUT_PP_LOW_FAST);
  38.         RW_L();
  39.         E_L();
  40.         RS_L();//指令
  41.         //GPIO_Write(GPIOB,0X20);
  42.         //GPIO_Write(GPIOB,GPIOB->PDOR|0xFFF2FFFF);
  43.        
  44.     if(0X20&0x10)
  45.           D4_H();
  46.         else
  47.           D4_L();
  48.         if(0X20&0x20)
  49.           D5_H();
  50.         else
  51.           D5_L();
  52.         if(0X20&0x40)
  53.           D6_H();
  54.         else
  55.           D6_L();
  56.         if(0X20&0x80)
  57.           D7_H();
  58.         else
  59.           D7_L();
  60.        
  61.   E_H();//允许
  62.         delay(50);
  63.         E_L();//4线制,在该位四线制通讯时,数据线切换必须是半字节的,之后延时必须超过40US
  64.     //        LCD1602_DATA_write(Write_order,0X28);//4位数据总线模式,显示2行数据,5*10点阵每字符        0X38为8位数据模式, 显示2行数据,5*10点阵每字符
  65.         delay(10);
  66.         LCD1602_DATA_write(Write_order,0x0c); //开显示,有光标,光标闪烁
  67.         delay(10);
  68.         LCD1602_Clear_Screen(); //清屏       
  69.         delay(10);
  70.         LCD1602_DATA_write(Write_order,0x06); //写入数据光标右移,写入新数据显示屏不移动
  71.     delay(10);
  72.         LCD1602_DATA_write(Write_order,0x80); //
  73. }

  74. //函数名:  LCD1602_Clear_Screen
  75. //函数功能:LCD1602清屏
  76. //注释:   
  77. void LCD1602_Clear_Screen(void)
  78. {
  79.         LCD1602_DATA_write(Write_order,0x01); //清屏
  80. }



  81. //函数名:  write_com
  82. //函数功能:LCD1602写指令
  83. //注释:   
  84. void write_com(unsigned int dat)
  85. {
  86.   unsigned char j;
  87.   RS_L();//指令
  88.   for(j=0;j<2;j++)
  89.   {
  90.                 //GPIO_Write(GPIOB,(dat&0x00f0));
  91.                 //GPIO_Write(GPIOB,GPIOB->PDOR&(((dat&0x000000f0)<<12)|0xFFF0FFFF));
  92.                 //GPIO_Write(GPIOB,GPIOB->PDOR | ((dat&0x000000f0)<<12));
  93.                
  94.           if(dat&0x10)
  95.             D4_H();
  96.           else
  97.             D4_L();
  98.           if(dat&0x20)
  99.             D5_H();
  100.           else
  101.             D5_L();
  102.           if(dat&0x40)
  103.             D6_H();
  104.           else
  105.             D6_L();
  106.           if(dat&0x80)
  107.             D7_H();
  108.           else
  109.             D7_L();
  110.                
  111.     E_H();//允许
  112.           delay(50);
  113.           E_L();
  114.           dat<<=4;
  115.   }
  116. }


  117. //函数名:  write_data
  118. //函数功能:LCD1602写数据
  119. //注释:   
  120. void write_data(unsigned int dat)
  121. {
  122.   unsigned char j;
  123.   RS_H();//数据
  124.   for(j=0;j<2;j++)
  125.   {
  126.                 //GPIO_Write(GPIOB,(dat&0x00f0));
  127.                 //GPIO_Write(GPIOB,GPIOB->PDOR&(((dat&0x000000f0)<<12)|0xFFF0FFFF));
  128.                 //GPIO_Write(GPIOB,GPIOB->PDOR | ((dat&0x000000f0)<<12));
  129.                
  130.           if(dat&0x10)
  131.             D4_H();
  132.           else
  133.             D4_L();
  134.           if(dat&0x20)
  135.             D5_H();
  136.           else
  137.             D5_L();
  138.           if(dat&0x40)
  139.             D6_H();
  140.           else
  141.             D6_L();
  142.           if(dat&0x80)
  143.             D7_H();
  144.           else
  145.             D7_L();
  146.           
  147.           E_H();//允许
  148.           delay(50);
  149.           E_L();
  150.           dat<<=4;
  151.   }
  152. }

  153. //函数名:lcd1602_write
  154. //作用:将数据或者指令写入LCD1602
  155. //注释:
  156. void LCD1602_DATA_write(LCD1602_Write_TypeDef order,unsigned char dat)
  157. {
  158.         if(order==Write_data)
  159.                 write_data(dat);
  160.         else
  161.           write_com(dat);
  162. }

  163. //函数名:lcd1602_show_character
  164. //作用:  在制定坐标,显示单个字符
  165. void lcd1602_show_character(unsigned char x,unsigned char y,unsigned char dat)
  166. {
  167.         unsigned char address;
  168.         x=x%16;
  169.         y=y%2;
  170.         if(y==1)
  171.                 address=0xc0+x;
  172.         else
  173.                 address=0x80+x;  
  174.         LCD1602_DATA_write(Write_order,address);
  175.         LCD1602_DATA_write(Write_data,dat);
  176. }

  177. //函数名:lcd1602_show_number
  178. //作用:
  179. //     以(X,Y)坐标为起始,显示一个数字(此数字值不能大于4294967295(0xffffffff))
  180. //注释:
  181. //     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分
  182. unsigned char lcd1602_show_number(unsigned char x,unsigned char y,unsigned short dat)
  183. {
  184.         unsigned short pow=1,instead;
  185.         unsigned char increase=0,lengh=0;
  186.         instead=dat;
  187.         while(instead!=0)
  188.         {
  189.                 instead=instead/10;
  190.                 increase++;
  191.         }
  192.         lengh=increase;
  193.         if(increase==0)
  194.         {
  195.                 lcd1602_show_character(x,y,0x30);
  196.                 return 1;
  197.         }
  198.         else
  199.         {
  200.                 for(;increase>1;increase--)
  201.                 pow=pow*10;
  202.                 while(pow!=0)
  203.                 {
  204.                         instead=dat/pow;
  205.                         lcd1602_show_character(x,y,(0x30+instead));
  206.                         x++;
  207.                         if(((x%16)==0)&&(x!=0))
  208.                         {
  209.                                 y++;
  210.                                 y=y%2;
  211.                                 x=x%16;
  212.                         }
  213.                         dat=dat%pow;
  214.                         pow=pow/10;  
  215.           }
  216.         }
  217.         return lengh;
  218. }


  219. //函数名:lcd1602_show_string
  220. //作用:
  221. //     以(X,Y)坐标为起始,显示一个字符串
  222. //注释:
  223. //     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分,字符长度小于256
  224. unsigned char lcd1602_show_string(unsigned char x,unsigned char y,unsigned char *dat)
  225. {
  226.         unsigned char lengh=0;
  227.         while(dat[lengh]!='\0')
  228.         {
  229.                 if(((x%16)==0)&&(x!=0))
  230.                 {
  231.                     y++;
  232.                                 y=y%2;
  233.                     x=x%16;
  234.                 }
  235.     lcd1602_show_character(x,y,dat[lengh]);       
  236.                 x++;
  237.                 lengh++;
  238.         }
  239.         return (lengh);
  240. }


  241. //函数名:lcd1602_show_number
  242. //作用:
  243. //     以(X,Y)坐标为起始,显示一个数字(此数字值不能大于4294967295(0xffffffff))
  244. //注释:
  245. //     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分
  246. unsigned char lcd1602_show_s32(unsigned char x,unsigned char y,short dat)
  247. {
  248.         short pow=1,instead;
  249.         unsigned char increase=0,lengh=0;
  250.         if(((dat&0x80000000)==0x80000000)&&(dat!=0xffffffff))//负数
  251.         {
  252.           instead=-dat;
  253.           y=y%2;
  254.           lcd1602_show_character(x,y,0x2D);//"-"
  255.           x++;
  256.         }
  257.         else if((dat&0x80000000)!=0x80000000)//正数
  258.         {
  259.           instead=dat;
  260.           y=y%2;
  261.           lcd1602_show_character(x,y,0X2B);//"+"
  262.           x++;     
  263.         }
  264.         else//0
  265.         {
  266.           instead=0;   
  267.         }
  268.         dat=instead;
  269.         while(instead!=0)
  270.         {
  271.                 instead=instead/10;
  272.                 increase++;
  273.         }
  274.         lengh=increase;
  275.         if(increase==0)
  276.         {
  277.                 lcd1602_show_character(x,y,0x30);
  278.                 return 1;
  279.         }
  280.         else
  281.         {
  282.                 for(;increase>1;increase--)
  283.                 pow=pow*10;
  284.                 while(pow!=0)
  285.                 {
  286.                         instead=dat/pow;
  287.                         lcd1602_show_character(x,y,(0x30+instead));
  288.                         x++;
  289.                         if(((x%16)==0)&&(x!=0))
  290.                         {
  291.                                 y++;
  292.                                 y=y%2;
  293.                                 //x=x%16;
  294.                         }
  295.                         dat=dat%pow;
  296.                         pow=pow/10;  
  297.           }
  298.         }
  299.         return lengh+1;
  300. }

复制代码
lcd1602.h
  1. #ifndef __LCD1602_H__
  2. #define __LCD1602_H__

  3. //为了适应任意IO驱动LCD1602做的定义
  4. #define RW_L() GPIO_PinClear(GPIO_PTE0)//RW=0
  5. #define RW_H() GPIO_PinSet(GPIO_PTE0)  //RW=1

  6. #define RS_L() GPIO_PinClear(GPIO_PTE1)//RS=0
  7. #define RS_H() GPIO_PinSet(GPIO_PTE1)  //RS=1

  8. #define E_L()  GPIO_PinClear(GPIO_PTC5)//E=0
  9. #define E_H()  GPIO_PinSet(GPIO_PTC5)  //E=1


  10. //#define D0_L() P2 &=~BIT0//D0=0
  11. //#define D0_H() P2 |=BIT0 //D0=1
  12. //#define D1_L() P2 &=~BIT1//D1=0
  13. //#define D1_H() P2 |=BIT1 //D1=1
  14. //#define D2_L() P2 &=~BIT2//D2=0
  15. //#define D2_H() P2 |=BIT2 //D2=1
  16. //#define D3_L() P2 &=~BIT3//D3=0
  17. //#define D3_H() P2 |=BIT3 //D3=1
  18. #define D4_L() GPIO_PinClear(GPIO_PTG0)//D4=0
  19. #define D4_H() GPIO_PinSet(GPIO_PTG0)  //D4=1
  20. #define D5_L() GPIO_PinClear(GPIO_PTG1)//D5=0
  21. #define D5_H() GPIO_PinSet(GPIO_PTG1)  //D5=1
  22. #define D6_L() GPIO_PinClear(GPIO_PTG2)//D6=0
  23. #define D6_H() GPIO_PinSet(GPIO_PTG2)  //D6=1
  24. #define D7_L() GPIO_PinClear(GPIO_PTG3)//D7=0
  25. #define D7_H() GPIO_PinSet(GPIO_PTG3)  //D7=1

  26. typedef enum
  27. {
  28.         Write_data  =0X00,
  29.         Write_order =0x01/*BIT0*/
  30. }LCD1602_Write_TypeDef;

  31. //函数名:  delay
  32. //函数功能:LCD1602延时
  33. //注释:   
  34. void delay(unsigned char z);

  35. //函数名:  LCD1602_GPIO_INIT
  36. //函数功能:LCD1602用GPIO初始化
  37. //注释:
  38. void LCD1602_GPIO_INIT(void);

  39. //函数名:  LCD1602_INIT
  40. //函数功能:LCD1602初始化
  41. //注释:    DATA可以是指令或者数据
  42. void LCD1602_INIT(void);

  43. //函数名:  LCD1602_Clear_Screen
  44. //函数功能:LCD1602清屏
  45. //注释:   
  46. void LCD1602_Clear_Screen(void);



  47. //函数名:  write_com
  48. //函数功能:LCD1602写指令
  49. //注释:   
  50. void write_com(unsigned int dat);


  51. //函数名:  write_data
  52. //函数功能:LCD1602写数据
  53. //注释:   
  54. void write_data(unsigned int dat);

  55. //函数名:lcd1602_write
  56. //作用:将数据或者指令写入LCD1602
  57. //注释:
  58. void LCD1602_DATA_write(LCD1602_Write_TypeDef order,unsigned char dat);

  59. //函数名:lcd1602_show_character
  60. //作用:  在制定坐标,显示单个字符
  61. void lcd1602_show_character(unsigned char x,unsigned char y,unsigned char dat);

  62. //函数名:lcd1602_show_number
  63. //作用:
  64. //     以(X,Y)坐标为起始,显示一个数字(此数字值不能大于4294967295(0xffffffff))
  65. //注释:
  66. //     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分
  67. unsigned char lcd1602_show_number(unsigned char x,unsigned char y,unsigned short dat);


  68. //函数名:lcd1602_show_string
  69. //作用:
  70. //     以(X,Y)坐标为起始,显示一个字符串
  71. //注释:
  72. //     返回数字的显示长度,若改行显示不下,函数自动换行, 显示其余部分,字符长度小于256
  73. unsigned char lcd1602_show_string(unsigned char x,unsigned char y,unsigned char *dat);

  74. //显示有符号S32
  75. unsigned char lcd1602_show_s32(unsigned char x,unsigned char y,short dat);

  76. #endif

复制代码


123ycli 发表于 2018-7-22 22:59 | 显示全部楼层
支持下,想起一句话,铁打的1602,流水的MCU。
tang87633187 发表于 2018-8-3 09:35 | 显示全部楼层
1602LCD 是3.3V供电,还是5V供电
lxs0026 发表于 2018-8-26 11:53 | 显示全部楼层
恩恩恩,不错不错,期待下文。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎参与LabVIEW版块的讨论学习! 点我一键即达

255

主题

2826

帖子

44

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