自己参考大神们的程序改写的液晶驱动,希望对有需要的人能有帮助
#include \"stm32f10x.h\"
static __IO uint32_t TimingDelay;
void RCC_Configuration(void);
void Delay(__IO uint32_t nTime);
#define Line1 0x80//液晶第一行
#define Line2 0x90//液晶第二行
#define Line3 0x88//液晶第三行
#define Line4 0x98//液晶第四行
#define LCD_IO GPIOE //我用的是 E.2 E.3 E.4 E.5 E.6
#define CS GPIO_Pin_2
#define RW GPIO_Pin_3
#define CLK GPIO_Pin_4
#define PSB GPIO_Pin_5
#define RST GPIO_Pin_6
#define SET(n) GPIO_SetBits(GPIOE,n) //将对应管脚输出高电平
#define RESET(n) GPIO_ResetBits(GPIOE,n)//输出低电平
#define CMD (uint32_t)0xf8000000 //串行 写入的是命令要先写入0xf8
#define DATE (uint32_t)0xfa000000 // 串行 写入数据要先写入0xfa
void LCD_IOinit_OUT() //推挽输出模式 ,管脚配置,不多解释,库函数有
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin =CS|RW|CLK|PSB|RST;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LCD_IO, &GPIO_InitStructure);
}
void LCD_Write(uint32_t cmd,uint8_t ddata)//LCD 写函数
{
uint32_t temp=cmd;
uint32_t i;
RESET(CS); //片选拉低
temp|=((uint32_t)(ddata&(uint8_t)0xf0)<<16)+((uint32_t)(ddata&(uint8_t)0x0f)<<12);
SET(CS); //片选拉高,开始传输数据
for(i=0;i<24;i++)
{
if(temp&0x80000000)SET(RW); //取出最高位,如果是1,那么RW就写1
else RESET(RW); //如果是0 RW就写0
SET(CLK);//向液晶写数据 是在下降沿写入的
Delay(2);//稍作延时
RESET(CLK);//拉低产生下降沿,写入数据
temp=temp<<1;//左移一位 ,写入下一位
}
RESET(CS); //拉低片选,写入数据完毕
}
void Display(uint8_t addr,uint8_t *hz)
{
LCD_Write(CMD,addr);
Delay(3);
while(*hz!='\\0')
{
LCD_Write(DATE,*hz);
hz++;
Delay(3);
}
}
void LCD_init()//液晶初始化
{
RESET(CS); //拉低片选
RESET(PSB);//PSB拉低,表示是串行,拉高则是并行
RESET(RST);//拉低RST
Delay(100);
SET(RST);
Delay(40);
LCD_Write(CMD,0x30);//8位数据传输
Delay(40);
LCD_Write(CMD,0x0c);//显示开,游标开
Delay(40);
LCD_Write(CMD,0x01);//清屏
Delay(40);
LCD_Write(CMD,0x06);//进入点设定 AC+1
Delay(40);
}
int main()
{
RCC_Configuration();
SysTick_Config(72000); //配置SYSTICK时钟节拍为1ms一次
LCD_IOinit_OUT();
LCD_init();
while(1)
{
Display(Line1,\"你妹\");
Display(Line2,\"你妹\");
Display(Line3,\"你妹妹\");
Display(Line4,\"完事了,哈哈哈哈哈\");
}
}
void RCC_Configuration(void)
{
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE , ENABLE);
}
void Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
/*
temp|=((uint32_t)(ddata&(uint8_t)0xf0)<<16)+((uint32_t)(ddata&(uint8_t)0x0f)<<12);
重点解释一下这里,从串行时序图中可以看出,发送一个指令需要三个字节,第一个是0xf8或者0xfa这个根据你要发送的是命令还是数据而定,然后发送下一个数据的高四位和第四位,但是数据都是在高四位上面,用51的话我们要分三次发送,但是32的话一个字节可以是32位的/所以我们一次就能完成,这也是为什么下面的i<24的原因因为最后的8位没有用,
例如:我们发送指令0x35,则应该是这样0xf8然后0x30然后0x50,这个应该很好理解
所以看一下上面的语句首先我们cmd的值应该为0xf8000000,这个宏定义有的,这是发送命令然后我们让cmd=temp;在把temp和后面的计算结果做按位或运算.首先看这个(uint32_t)(ddata&(uint8_t)0xf0)<<16)我们的ddtate是0x35他和0xf0按位与之后/变为0x30然后左移16位变成0x30 0000;再强制转换为32位,就把高位补零变为0x00 30 0000再看这句话(uint32_t)(ddata&(uint8_t)0x0f)<<12)我们的ddtate是0x35
他和0x0f按位与/之后变为0x05,左移12位 0x05 000 强制转换为32位 高位补零 0x000 05 000 /在和前面的相加就是 0x00 30 0000+0x000 05 000=0x0030 5000然后在和前面的0xf8000000按位或变为0xf830 5000 液晶读这个数据的时候是 八位八位的读取 所以在液晶看来 是分四次的0xf8 0x30 0x50 0x00显然后八位没用 所以我们只取前面的24位
//应该能看懂了把言
*/
结合时序图还有延时一定要精确大家有看不懂的可以给我留
因篇幅问题不能全部显示,请点此查看更多更全内容