你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F072笔记3-移植12864液晶程序

[复制链接]
hjl240 发布时间:2015-2-4 09:56
本文例子用到:
1.  STM32F072 Nucleo开发板
2.  12864液晶
3 .   STM32CubeMX软件 Version4.3.0
4.  Keil MDK 软件Version5.12.0.0

下面开始讲解:
         首先讲一下思路。本文将MSP430单片机(16位)控制12864的程序移植到STM32F072控制12864。其实控制12864实际上就是对IO口进行写0或者写1的操作,不同单片机控制IO口输出01方法不同,比如MSP430IO口置一为P1DIR|=BIT0;IO口清零则为P1DIR~=BIT0;(此处是将MSP430P10进行置一与清零);而STM32利用库函数将IO口置一为HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);IO清零则为HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_RESET);(此处是将STM32PB13置一与清零);只需要将MSP430控制IO口的程序改为STM32控制IO口的程序就行,另外,由于不同单片机时钟频率不一样,运行速度不一样,因此可能需要改一下移植程序中的延时。(另外,IO口配置输入输出的方式也需要改)
         12864液晶有并行和串行两种接线方式,本文采用串行控制。串行控制至少需要将液晶的三个IO口连到STM32IO口。分别是片选信号CSRS),数据信号SIDRW),时钟信号SCLKE),PSB直接接到GNDRST可以不接。
         接下来开始讲讲实际怎么操作。
1.      通过STM32CubeMX软件配置IO口。本文IO口接法:
PB13------------------CS(RS)
PB14------------------SID(RW)
PB15------------------SCLK(E)
GND-------------------PSB
GND-------------------VSS
+5V--------------------VDD
GND-------------------LEDK
+5V--------------------LEDA

STM32Cube配置如下:
1.png

2.      STM32Cube其他配置默认,生成Keil工程。

3.      首先看看要移植的lcd12864程序:

  1. #define uchar unsigned char
  2. #define uint unsigned int
  3. #define LCD12864_CS_OUT P1DIR|=BIT4
  4. #define LCD12864_CS_H P1OUT|=BIT4
  5. #define LCD12864_CS_L P1OUT&=~BIT4

  6. #define LCD12864_SID_OUT P1DIR|=BIT2
  7. #define LCD12864_SID_H P1OUT|=BIT2
  8. #define LCD12864_SID_L P1OUT&=~BIT2

  9. #define LCD12864_SCLK_OUT P1DIR|=BIT3
  10. #define LCD12864_SCLK_H P1OUT|=BIT3
  11. #define LCD12864_SCLK_L P1OUT&=~BIT3

  12. //PSB由硬件置低,故省去
  13. //#define LED12864_PSB_OUT P1DIR|=BIT5
  14. //#define LED12864_PSB_L P1OUT&=~BIT5
  15. //RST不接也行
  16. //#define LCD12864_RST_OUT P1DIR|=BIT6
  17. //#define LCD12864_RST_H P1OUT|=BIT6
  18. //#define LCD12864_RST_L P1OUT&=~BIT6


  19. /********************************************************************
  20. * 名称 : delay()
  21. * 功能 : 软件延时
  22. * 输入 : t
  23. * 输出 : 无
  24. ***********************************************************************/
  25. void delay(unsigned int t)
  26. {
  27.         unsigned int i,j;
  28.         for(i=0; i<t;  i++)
  29.     for(j=0; j<3; j++);
  30. }

  31. /********************************************************************
  32. * 名称 : sendbyte()
  33. * 功能 : 按照液晶的串口通信协议,发送数据
  34. * 输入 : zdata
  35. * 输出 : 无
  36. ***********************************************************************/
  37. void sendbyte(unsigned char zdata)
  38. {
  39.         unsigned int i;
  40.         for(i=0; i<8; i++)
  41.         {
  42.                 if((zdata << i) & 0x80)
  43.                 {
  44.                         LCD12864_SID_H;//SID=1
  45.                 }
  46.                 else
  47.                 {
  48.                         LCD12864_SID_L ;
  49.                 }
  50.                 LCD12864_SCLK_L;//SCLK = 0;
  51.                 LCD12864_SCLK_H;//SCLK = 1;
  52.         }
  53. }

  54. /********************************************************************
  55. * 名称 : write_com()
  56. * 功能 : 写串口指令
  57. * 输入 : cmdcode
  58. * 输出 : 无
  59. ***********************************************************************/
  60. void write_com(unsigned char cmdcode)
  61. {
  62.         LCD12864_CS_H ;//CS = 1;
  63.         sendbyte(0xf8);
  64.         sendbyte(cmdcode & 0xf0);
  65.         sendbyte((cmdcode << 4) & 0xf0);
  66.         delay(1);
  67. }

  68. /********************************************************************
  69. * 名称 : write_data()
  70. * 功能 : 写串口数据
  71. * 输入 : Dispdata
  72. * 输出 : 无
  73. ***********************************************************************/
  74. void write_data(unsigned char Dispdata)
  75. {
  76.         LCD12864_CS_H ;//CS = 1;
  77.         sendbyte(0xfa);
  78.         sendbyte(Dispdata & 0xf0);
  79.         sendbyte((Dispdata << 4) & 0xf0);
  80.         delay(1);
  81. }

  82. /********************************************************************
  83. * 名称 : init()
  84. * 功能 : 初始化函数
  85. * 输入 : cmdcode
  86. * 输出 : 无
  87. ***********************************************************************/
  88. void lcd12864_init()
  89. {
  90.         LCD12864_CS_OUT ;
  91.         LCD12864_SID_OUT ;
  92.         LCD12864_SCLK_OUT ;
  93. //        LED12864_PSB_OUT ;
  94. //        LCD12864_RST_OUT ;
  95. //        LED12864_PSB_L;
  96. //        LCD12864_RST_L;//RST = 0;
  97. //        delay_ms(100);
  98. //        LCD12864_RST_H;//RST = 1;
  99. //        delay_ms(5);
  100.         write_com(0x30);
  101.         delay(2000);
  102.         write_com(0x0c);
  103. delay(2000);
  104.         write_com(0x01);
  105. }

  106. // *清除图像显示
  107. void clearLCD(void)
  108. {

  109.         uchar i, j;

  110.         write_com(0x36);        // 8位,扩充指令集,图形显示开
  111.         for (i = 0; i < 32; i++)        // 32行,12864=25632
  112.         {
  113.                 write_com(0x80 + i);        // 绘图区的Y地址
  114.                 write_com(0x80);        // 绘图区的X地址
  115.                 for (j = 0; j < 32; j++) {
  116.                         write_data(0x00);        // 清除
  117.                 }
  118.         }
  119.         write_com(0x30);        // 8位,基本指令集
  120. }


  121. void pos(uchar x,uchar y)          //*设定LCD写位置
  122. {
  123.   uchar pos;
  124.   if(x==0) x=0x80;
  125.   else if(x==1) x=0x90;
  126.   else if(x==2) x=0x88;
  127.   else if(x==3) x=0x98;
  128.   pos=x+y;
  129.   write_com(pos);
  130. }
复制代码

4.      上面的程序写的比较规范,IO口控制都是通过宏定义,我们只需要将
  1. #define LCD12864_CS_OUT P1DIR|=BIT4
  2. #define LCD12864_CS_H P1OUT|=BIT4
  3. #define LCD12864_CS_L P1OUT&=~BIT4
复制代码
改为
  1. #define LCD12864_CS_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_SET)
  2. #define LCD12864_CS_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_RESET)
复制代码
由于在STM32Cube中我们已经将对于IO口配置为输出,故
#define LCD12864_CS_OUT P1DIR|=BIT4可以不用理会。

其他IO配置相同。总的配置如下:
  1. #define LCD12864_CS_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_SET)
  2. #define LCD12864_CS_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,GPIO_PIN_RESET)

  3. #define LCD12864_SID_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_SET)
  4. #define LCD12864_SID_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_RESET)

  5. #define LCD12864_SCLK_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15,GPIO_PIN_SET)
  6. #define LCD12864_SCLK_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15,GPIO_PIN_RESET)
复制代码
再看看lcd12864初始化函数:
  1. void lcd12864_init()
  2. {
  3.         LCD12864_CS_OUT ;
  4.         LCD12864_SID_OUT ;
  5.         LCD12864_SCLK_OUT ;
  6. //        LED12864_PSB_OUT ;
  7. //        LCD12864_RST_OUT ;
  8. //        LED12864_PSB_L;
  9. //        LCD12864_RST_L;//RST = 0;
  10. //        delay_ms(100);
  11. //        LCD12864_RST_H;//RST = 1;
  12. //        delay_ms(5);
  13.         write_com(0x30);
  14.         delay(2000);
  15.         write_com(0x0c);
  16. delay(2000);
  17.         write_com(0x01);
  18. }
复制代码
由于我们在STM32Cube中已经将IO口设置为输出,故可以将
  1. LCD12864_CS_OUT ;
  2.         LCD12864_SID_OUT ;
  3.         LCD12864_SCLK_OUT ;
复制代码
这三句删除。
5.      由于12864液晶对延时要求不是很严格,故此处不用改延时,如果出现问题,可以尝试改改延时程序。
6.      将修改好的程序放入生成的keil工程中,放在
/* USER CODE BEGIN 0 */与/* USER CODE END 0*/之间
7.      最后,写个小程序测试一下。

main函数如下:
  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */
  4.         int i=0;
  5.         unsigned char  a[]="--Hello Nucleo!-";
  6.         unsigned char  b[]="--Hello World!--";
  7.         unsigned char  c[]="--Hello STMCU!--";       
  8.         unsigned char  d[]="    ~@^_^@~     ";       
  9.   /* USER CODE END 1 */

  10.   /* MCU Configuration----------------------------------------------------------*/

  11.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  12.   HAL_Init();

  13.   /* Configure the system clock */
  14.   SystemClock_Config();

  15.   /* System interrupt init*/
  16.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  17.   /* Initialize all configured peripherals */
  18.   MX_GPIO_Init();

  19.   /* USER CODE BEGIN 2 */
  20.         lcd12864_init();//lcd12864液晶初始化
  21.         delay(10000);//适当延时
  22.         pos(0,0);//设置显示起始位置
  23.         for(i=0;i<16;i++)//设置显示内容
  24.         {
  25.                 write_data(a[i]);
  26.         }
  27.         pos(1,0);
  28.         for(i=0;i<16;i++)
  29.         {
  30.                 write_data(b[i]);
  31.         }
  32.         pos(2,0);
  33.         for(i=0;i<16;i++)
  34.         {
  35.                 write_data(c[i]);
  36.         }       
  37.         pos(3,0);
  38.         for(i=0;i<16;i++)
  39.         {
  40.                 write_data(d[i]);
  41.         }               
  42.   /* USER CODE END 2 */

  43.   /* USER CODE BEGIN 3 */
  44.   /* Infinite loop */
  45.   while (1)
  46.   {

  47.   }
  48.   /* USER CODE END 3 */

  49. }
复制代码
显示效果如下:
2.png

参考程序: Lcd12864.zip (2.85 MB, 下载次数: 123)

评分

参与人数 1 ST金币 +1 收起 理由
Georgeabc + 1 请问并口LCD的STM32的端口设置?.

查看全部评分

收藏 2 评论21 发布时间:2015-2-4 09:56

举报

21个回答
hjl240 回答时间:2015-2-5 08:29:02
zhangdaijin 发表于 2015-2-4 10:18
这样的贴不顶对不起观众啊

谢谢支持
hjl240 回答时间:2015-2-7 10:15:10
党国特派员 发表于 2015-2-6 09:11
这样的贴不顶对不起观众啊

谢谢支持
hjl240 回答时间:2015-2-6 08:44:12

谢谢支持
chendiand 回答时间:2015-2-4 10:12:47
不错,挺详细的
zhangdaijin 回答时间:2015-2-4 10:18:14
这样的贴不顶对不起观众啊
子曰小玖 回答时间:2015-2-4 10:19:43
必须赞一个!!楼主继续啊   
fjjjnk1234 回答时间:2015-2-4 11:56:48
很详细!感谢分享!
stary666 回答时间:2015-2-4 13:30:07
好!!!!!!!!!!!!!!!!!!!!
770781327 回答时间:2015-2-4 16:39:30
不错,支持
党国特派员 回答时间:2015-2-6 09:11:19
这样的贴不顶对不起观众啊
大秦正声 回答时间:2015-2-6 09:18:27
很给力啊!
拼命三郎 回答时间:2015-2-6 09:28:06
aaaaaaaaa.jpg
梦旺龙 回答时间:2015-2-6 09:37:56
赞一个
759611 回答时间:2015-2-6 09:39:30
好贴,感谢分享!
tcmax 回答时间:2015-2-6 09:45:16
回去试试
12下一页

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版