STM32F0 #16进程帖(一)----- LCD12864液晶显示
本帖最后由 Kite 于 2014-5-14 04:13 编辑最近各种忙啊,上课、写报告、画板子、还要准备坑爹的期中考试{:soso_e153:},最坑爹的是这分数还占期末成绩20%{:soso_e109:}。。。不过大家都在努力,我也不能闲着。今天就用Discovery调了一下12864液晶。。
代码是以前写的,直接移植过来了。话说STM32系列的固件库规则都差不多,F0系列和F1系列的程序移植几乎只用改个头文件了。废话少说,先上个图{:soso_e144:},手机抓拍的,光线又不好,也只能拍成这样了{:soso_e143:}
12864是采用串行双线控制的方法,电路图如下,RS拉高,PSB拉低,R/W 和 E 在串行控制中分别作为数据线和时钟线
下面是代码。(附上完整工程供下载,由于M0的SysTick与M3的一样,故直接复制粘贴了以前的延时代码,在此对原作者“正点原子”表示感谢{:soso_e121:})
main.c#include "stm32f0xx.h"
#include "delay.h"
#include "device_init.h"
#include "LCD12864.h"
int main(void)
{
Device_Init();
LCD12864_Display_Words(0, 0, "Hello, world!");
LCD12864_Display_Words(1, 0, "www.eeboard.com");
while(1);
}//end main
LCD12864.h/**
******************************************************************************
* @file LCD12864.h
* @authorKite
* @version NULL
* @date 1-August-2012
* @brief The LCD12864 header file.
******************************************************************************
*/
#ifndef __LCD12864_H
#define __LCD12864_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx.h"
#if !defined u8 && !defined u16 && !defined u32
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#endif
/* Definitions ---------------------------------------------------------------*/
//接口输出操作(SID: PC0SCLK: PC1)
#define LCD12864_SID_OUT(x) (x) ? (GPIOC->BSRR |= 1<<0) : (GPIOC->BRR |= 1<<0)
#define LCD12864_SCLK_OUT(x) (x) ? (GPIOC->BSRR |= 1<<1) : (GPIOC->BRR |= 1<<1)
/* Write command or dat select */
#define WRITE_CMD 0xF8
#define WRITE_DAT 0xFA
/* Exported functions declared ---------------------------------------------- */
void LCD12864_Init(void); //液晶初始化函数
void LCD12864_Clear(void); //液晶清屏
void LCD12864_Display_Words(u8 x, u8 y, u8 *str); //液晶字符显示函数
void LCD12864_Display_Picture(u8 *pic); //液晶图片显示函数
#endif
LCD12864.c/**
******************************************************************************
* @file LCD12864.c
* @authorKite
* @version NULL
* @date 1-August-2012
* @brief The LCD12864 C file.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "LCD12864.h"
#include "delay.h"
/* Private variables ---------------------------------------------------------*/
/* 字符显示RAM地址 */
u8 LCD12864_DDRAM_ADDR={
{0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87}, //第一行
{0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97}, //第二行
{0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F}, //第三行
{0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F} //第四行
};
//delay functions
void delay_12864_ms(u16 xms)
{
delay_ms(xms);
}
void delay_12864_us(u16 xus)
{
delay_us(xus);
}
/* Private functions declared ------------------------------------------------*/
void LCD12864_SendByte(u8 Byte);
void LCD12864_Write(u8 writeSelect, u8 cmdOrDat);
/* Exported functions ------------------------------------------------------- */
/**
* @briefInitialize the LCD12864.
* @paramNone
* @retval None
*/
void LCD12864_Init(void)
{
delay_12864_ms(50); //等待液晶自检(延时>40ms)
LCD12864_Write(WRITE_CMD, 0x30); //功能设定
delay_12864_us(150); //延时>100us
LCD12864_Write(WRITE_CMD, 0x30); //功能设定
delay_12864_us(40); //延时>37us
LCD12864_Write(WRITE_CMD, 0x0C); //开显示
delay_12864_us(150); //延时>100us
LCD12864_Write(WRITE_CMD, 0x01); //清屏
delay_12864_ms(15); //延时>10ms
LCD12864_Write(WRITE_CMD, 0x06); //进入设定点,初始化完成
}
/**
* @briefClear the screen.
* @paramNone
* @retval None
*/
void LCD12864_Clear(void)
{
LCD12864_Write(WRITE_CMD, 0x01); //清屏指令
delay_12864_ms(2); //延时以待液晶稳定【至少1.6ms】
}
/**
* @briefLCD12864 display words.
* @paramx: row(0~3)y: line(0~7)str: the pointer to words
* @retval None
*/
void LCD12864_Display_Words(u8 x, u8 y, u8 *str)
{
LCD12864_Write(WRITE_CMD, LCD12864_DDRAM_ADDR);
while(*str)
{
LCD12864_Write(WRITE_DAT, *str);
str++;
}
}
/**
* @briefLCD12864 display picture.
* @parampic: The pointer to the picture array.
* @retval None
*/
void LCD12864_Display_Picture(u8 *pic)
{
u8 x,y,i;
LCD12864_Write(WRITE_CMD, 0x34); //切换到扩充指令
LCD12864_Write(WRITE_CMD, 0x34); //关闭图形显示
for(i = 0; i < 9; i = i+8)
{
for(y=0;y<32;y++)
{
for(x=0;x<8;x++)
{
LCD12864_Write(WRITE_CMD, 0x80 + y); //行地址
LCD12864_Write(WRITE_CMD, 0x80 + x+i); //列地址
LCD12864_Write(WRITE_DAT, *pic ++); //写数据 D15-D8
LCD12864_Write(WRITE_DAT, *pic ++); //写数据 D7-D0
}
}
}
LCD12864_Write(WRITE_CMD, 0x36);//打开图形显示
LCD12864_Write(WRITE_CMD, 0x30); //切换回基本指令
}
/* Private functions -------------------------------------------------------- */
/**
* @brief Transmit single byte in TWO_WIRE_SERIAL_CONTROL.
* @paramByte: The byte to be written.
* @retval None
*/
void LCD12864_SendByte(u8 Byte)
{
u8 i;
for(i = 0; i < 8; i++)
{
LCD12864_SCLK_OUT(0); //时钟线置低
LCD12864_SID_OUT(Byte & (0x80>>i)); //将一字节数据送到数据总线
LCD12864_SCLK_OUT(1); //装载数据
LCD12864_SCLK_OUT(0);
}
}
/**
* @briefLCD12864 write command or data.
* @paramwriteSelect: Select to write command or data.
* This parameter can be one of the following values:
* @arg WRITE_CMD: Select to write command
* @arg WRITE_DAT: Select to write data
* @paramcmdOrDat: The command or data to be written.
* @retval None
*/
void LCD12864_Write(u8 writeSelect, u8 cmdOrDat)
{
delay_12864_ms(1);
LCD12864_SendByte(writeSelect); //写指令【RW=0,RS=0】
LCD12864_SendByte(0xF0 & cmdOrDat); //写高4位
LCD12864_SendByte(0xF0 & cmdOrDat << 4); //写低4位
}
sky-Hawk where发表于 2012-11-1 20:24
顶你一下,以前用并口做的,呵呵,你用串口,这下全家福了
顶你一下,谢谢分享 谢谢。。。。。; 不错,用串口驱动省IO口,!!!,我也用起来!!! Ljmp 发表于 2016-1-19 11:30 static/image/common/back.gif
搞起不错!!!
:P:P:P:P:P:P:P:P:P:P:P:P :lol:lol:lol搞起不错!!! 同上,一直蓝屏,电路图连接都对啊,为什么不好使啊。。 在吗?为什么我按照你的连接并且把程序烧进去液晶屏不亮呢,开电源只是轻微的闪了一下 这个确定能点亮,我怎么弄进去没亮 搞了两天也没出来 现在就是蓝屏 电路图是按你的接的 帮我看看哪里有问题吧